Commit 4c31791c authored by Russell King's avatar Russell King Committed by Russell King

Merge branch 'for-rmk' of...

Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6 into devel
parents 98797a24 7517b3fb
......@@ -680,6 +680,13 @@ M: sakoman@gmail.com
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
ARM/H4700 (HP IPAQ HX4700) MACHINE SUPPORT
P: Philipp Zabel
M: philipp.zabel@gmail.com
S: Maintained
F: arch/arm/mach-pxa/hx4700.c
F: arch/arm/mach-pxa/include/mach/hx4700.h
ARM/HP JORNADA 7XX MACHINE SUPPORT
P: Kristoffer Ericson
M: kristoffer.ericson@gmail.com
......@@ -4627,7 +4634,7 @@ F: drivers/media/video/pvrusb2/
PXA2xx/PXA3xx SUPPORT
P: Eric Miao
M: eric.miao@marvell.com
M: eric.y.miao@gmail.com
P: Russell King
M: linux@arm.linux.org.uk
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
......@@ -4641,19 +4648,19 @@ F: sound/soc/pxa/pxa2xx*
PXA168 SUPPORT
P: Eric Miao
M: eric.miao@marvell.com
M: eric.y.miao@gmail.com
P: Jason Chagas
M: jason.chagas@marvell.com
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
S: Supported
S: Maintained
PXA910 SUPPORT
P: Eric Miao
M: eric.miao@marvell.com
M: eric.y.miao@gmail.com
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
S: Supported
S: Maintained
PXA MMCI DRIVER
S: Orphan
......
......@@ -35,10 +35,6 @@ config SHARP_LOCOMO
config SHARP_PARAM
bool
config SHARPSL_PM
bool
select APM_EMULATION
config SHARP_SCOOP
bool
......
......@@ -12,7 +12,6 @@ obj-$(CONFIG_DMABOUNCE) += dmabounce.o
obj-$(CONFIG_TIMER_ACORN) += time-acorn.o
obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o
obj-$(CONFIG_ARCH_IXP2000) += uengine.o
obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
......
/*
* Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00
* series of PDAs
*
* Copyright (c) 2004-2005 Richard Purdie
*
* Based on code written by Sharp for 2.4 kernels
*
* 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.
*
*/
#undef DEBUG
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/apm_bios.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/apm-emulation.h>
#include <linux/suspend.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <mach/pm.h>
#include <mach/pxa2xx-regs.h>
#include <mach/regs-rtc.h>
#include <mach/sharpsl.h>
#include <asm/hardware/sharpsl_pm.h>
/*
* Constants
*/
#define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */
#define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */
#define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */
#define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */
#define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */
#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */
#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */
#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */
#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10 /* 10 msec */
#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */
#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */
#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */
/*
* Prototypes
*/
#ifdef CONFIG_PM
static int sharpsl_off_charge_battery(void);
static int sharpsl_check_battery_voltage(void);
static int sharpsl_fatal_check(void);
#endif
static int sharpsl_check_battery_temp(void);
static int sharpsl_ac_check(void);
static int sharpsl_average_value(int ad);
static void sharpsl_average_clear(void);
static void sharpsl_charge_toggle(struct work_struct *private_);
static void sharpsl_battery_thread(struct work_struct *private_);
/*
* Variables
*/
struct sharpsl_pm_status sharpsl_pm;
DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle);
DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread);
DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger);
static int get_percentage(int voltage)
{
int i = sharpsl_pm.machinfo->bat_levels - 1;
int bl_status = sharpsl_pm.machinfo->backlight_get_status ? sharpsl_pm.machinfo->backlight_get_status() : 0;
struct battery_thresh *thresh;
if (sharpsl_pm.charge_mode == CHRG_ON)
thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_acin_bl : sharpsl_pm.machinfo->bat_levels_acin;
else
thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_noac_bl : sharpsl_pm.machinfo->bat_levels_noac;
while (i > 0 && (voltage > thresh[i].voltage))
i--;
return thresh[i].percentage;
}
static int get_apm_status(int voltage)
{
int low_thresh, high_thresh;
if (sharpsl_pm.charge_mode == CHRG_ON) {
high_thresh = sharpsl_pm.machinfo->status_high_acin;
low_thresh = sharpsl_pm.machinfo->status_low_acin;
} else {
high_thresh = sharpsl_pm.machinfo->status_high_noac;
low_thresh = sharpsl_pm.machinfo->status_low_noac;
}
if (voltage >= high_thresh)
return APM_BATTERY_STATUS_HIGH;
if (voltage >= low_thresh)
return APM_BATTERY_STATUS_LOW;
return APM_BATTERY_STATUS_CRITICAL;
}
void sharpsl_battery_kick(void)
{
schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
}
EXPORT_SYMBOL(sharpsl_battery_kick);
static void sharpsl_battery_thread(struct work_struct *private_)
{
int voltage, percent, apm_status, i = 0;
if (!sharpsl_pm.machinfo)
return;
sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE);
/* Corgi cannot confirm when battery fully charged so periodically kick! */
if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON)
&& time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL))
schedule_delayed_work(&toggle_charger, 0);
while(1) {
voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
if (voltage > 0) break;
if (i++ > 5) {
voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
break;
}
}
voltage = sharpsl_average_value(voltage);
apm_status = get_apm_status(voltage);
percent = get_percentage(voltage);
/* At low battery voltages, the voltage has a tendency to start
creeping back up so we try to avoid this here */
if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) {
sharpsl_pm.battstat.mainbat_voltage = voltage;
sharpsl_pm.battstat.mainbat_status = apm_status;
sharpsl_pm.battstat.mainbat_percent = percent;
}
dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage,
sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
#ifdef CONFIG_BACKLIGHT_CORGI
/* If battery is low. limit backlight intensity to save power. */
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
(sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
sharpsl_pm.machinfo->backlight_limit(1);
sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
}
} else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
sharpsl_pm.machinfo->backlight_limit(0);
sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
}
#endif
/* Suspend if critical battery level */
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
&& (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
&& !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
dev_err(sharpsl_pm.dev, "Fatal Off\n");
apm_queue_event(APM_CRITICAL_SUSPEND);
}
schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
}
void sharpsl_pm_led(int val)
{
if (val == SHARPSL_LED_ERROR) {
dev_err(sharpsl_pm.dev, "Charging Error!\n");
} else if (val == SHARPSL_LED_ON) {
dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
led_trigger_event(sharpsl_charge_led_trigger, LED_FULL);
} else {
dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
led_trigger_event(sharpsl_charge_led_trigger, LED_OFF);
}
}
static void sharpsl_charge_on(void)
{
dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
sharpsl_pm.full_count = 0;
sharpsl_pm.charge_mode = CHRG_ON;
schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250));
schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500));
}
static void sharpsl_charge_off(void)
{
dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
sharpsl_pm.machinfo->charge(0);
sharpsl_pm_led(SHARPSL_LED_OFF);
sharpsl_pm.charge_mode = CHRG_OFF;
schedule_delayed_work(&sharpsl_bat, 0);
}
static void sharpsl_charge_error(void)
{
sharpsl_pm_led(SHARPSL_LED_ERROR);
sharpsl_pm.machinfo->charge(0);
sharpsl_pm.charge_mode = CHRG_ERROR;
}
static void sharpsl_charge_toggle(struct work_struct *private_)
{
dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
sharpsl_charge_off();
return;
} else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
sharpsl_charge_error();
return;
}
sharpsl_pm_led(SHARPSL_LED_ON);
sharpsl_pm.machinfo->charge(0);
mdelay(SHARPSL_CHARGE_WAIT_TIME);
sharpsl_pm.machinfo->charge(1);
sharpsl_pm.charge_start_time = jiffies;
}
static void sharpsl_ac_timer(unsigned long data)
{
int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
sharpsl_average_clear();
if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
sharpsl_charge_on();
else if (sharpsl_pm.charge_mode == CHRG_ON)
sharpsl_charge_off();
schedule_delayed_work(&sharpsl_bat, 0);
}
irqreturn_t sharpsl_ac_isr(int irq, void *dev_id)
{
/* Delay the event slightly to debounce */
/* Must be a smaller delay than the chrg_full_isr below */
mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
return IRQ_HANDLED;
}
static void sharpsl_chrg_full_timer(unsigned long data)
{
dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies);
sharpsl_pm.full_count++;
if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
if (sharpsl_pm.charge_mode == CHRG_ON)
sharpsl_charge_off();
} else if (sharpsl_pm.full_count < 2) {
dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
schedule_delayed_work(&toggle_charger, 0);
} else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
schedule_delayed_work(&toggle_charger, 0);
} else {
sharpsl_charge_off();
sharpsl_pm.charge_mode = CHRG_DONE;
dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n");
}
}
/* Charging Finished Interrupt (Not present on Corgi) */
/* Can trigger at the same time as an AC status change so
delay until after that has been processed */
irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id)
{
if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
return IRQ_HANDLED;
/* delay until after any ac interrupt */
mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500));
return IRQ_HANDLED;
}
irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id)
{
int is_fatal = 0;
if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) {
dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
is_fatal = 1;
}
if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL)) {
dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
is_fatal = 1;
}
if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) {
sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
apm_queue_event(APM_CRITICAL_SUSPEND);
}
return IRQ_HANDLED;
}
/*
* Maintain an average of the last 10 readings
*/
#define SHARPSL_CNV_VALUE_NUM 10
static int sharpsl_ad_index;
static void sharpsl_average_clear(void)
{
sharpsl_ad_index = 0;
}
static int sharpsl_average_value(int ad)
{
int i, ad_val = 0;
static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) {
sharpsl_ad_index = 0;
return ad;
}
sharpsl_ad[sharpsl_ad_index] = ad;
sharpsl_ad_index++;
if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
sharpsl_ad[i] = sharpsl_ad[i+1];
sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
}
for (i=0; i < sharpsl_ad_index; i++)
ad_val += sharpsl_ad[i];
return (ad_val / sharpsl_ad_index);
}
/*
* Take an array of 5 integers, remove the maximum and minimum values
* and return the average.
*/
static int get_select_val(int *val)
{
int i, j, k, temp, sum = 0;
/* Find MAX val */
temp = val[0];
j=0;
for (i=1; i<5; i++) {
if (temp < val[i]) {
temp = val[i];
j = i;
}
}
/* Find MIN val */
temp = val[4];
k=4;
for (i=3; i>=0; i--) {
if (temp > val[i]) {
temp = val[i];
k = i;
}
}
for (i=0; i<5; i++)
if (i != j && i != k )
sum += val[i];
dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
return (sum/3);
}
static int sharpsl_check_battery_temp(void)
{
int val, i, buff[5];
/* Check battery temperature */
for (i=0; i<5; i++) {
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
sharpsl_pm.machinfo->measure_temp(1);
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_TEMP);
sharpsl_pm.machinfo->measure_temp(0);
}
val = get_select_val(buff);
dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
if (val > sharpsl_pm.machinfo->charge_on_temp) {
printk(KERN_WARNING "Not charging: temperature out of limits.\n");
return -1;
}
return 0;
}
#ifdef CONFIG_PM
static int sharpsl_check_battery_voltage(void)
{
int val, i, buff[5];
/* disable charge, enable discharge */
sharpsl_pm.machinfo->charge(0);
sharpsl_pm.machinfo->discharge(1);
mdelay(SHARPSL_WAIT_DISCHARGE_ON);
if (sharpsl_pm.machinfo->discharge1)
sharpsl_pm.machinfo->discharge1(1);
/* Check battery voltage */
for (i=0; i<5; i++) {
buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
}
if (sharpsl_pm.machinfo->discharge1)
sharpsl_pm.machinfo->discharge1(0);
sharpsl_pm.machinfo->discharge(0);
val = get_select_val(buff);
dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
if (val < sharpsl_pm.machinfo->charge_on_volt)
return -1;
return 0;
}
#endif
static int sharpsl_ac_check(void)
{
int temp, i, buff[5];
for (i=0; i<5; i++) {
buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT);
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
}
temp = get_select_val(buff);
dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
if ((temp > sharpsl_pm.machinfo->charge_acin_high) || (temp < sharpsl_pm.machinfo->charge_acin_low)) {
dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
return -1;
}
return 0;
}
#ifdef CONFIG_PM
static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
{
sharpsl_pm.flags |= SHARPSL_SUSPENDED;
flush_scheduled_work();
if (sharpsl_pm.charge_mode == CHRG_ON)
sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
else
sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
return 0;
}
static int sharpsl_pm_resume(struct platform_device *pdev)
{
/* Clear the reset source indicators as they break the bootloader upon reboot */
RCSR = 0x0f;
sharpsl_average_clear();
sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;
sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;
return 0;
}
static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
{
dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
/* not charging and AC-IN! */
if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) {
dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
sharpsl_pm.charge_mode = CHRG_OFF;
sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
sharpsl_off_charge_battery();
}
sharpsl_pm.machinfo->presuspend();
PEDR = 0xffffffff; /* clear it */
sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;
if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
RTSR &= RTSR_ALE;
RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
} else if (alarm_enable) {
RTSR &= RTSR_ALE;
RTAR = alarm_time;
dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
} else {
dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
}
pxa_pm_enter(state);
sharpsl_pm.machinfo->postsuspend();
dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
}
static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
{
if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
{
if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
corgi_goto_sleep(alarm_time, alarm_enable, state);
return 1;
}
if(sharpsl_off_charge_battery()) {
dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
corgi_goto_sleep(alarm_time, alarm_enable, state);
return 1;
}
dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
}
if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || (sharpsl_fatal_check() < 0) )
{
dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
corgi_goto_sleep(alarm_time, alarm_enable, state);
return 1;
}
return 0;
}
static int corgi_pxa_pm_enter(suspend_state_t state)
{
unsigned long alarm_time = RTAR;
unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);
dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");
corgi_goto_sleep(alarm_time, alarm_status, state);
while (corgi_enter_suspend(alarm_time,alarm_status,state))
{}
if (sharpsl_pm.machinfo->earlyresume)
sharpsl_pm.machinfo->earlyresume();
dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
return 0;
}
/*
* Check for fatal battery errors
* Fatal returns -1
*/
static int sharpsl_fatal_check(void)
{
int buff[5], temp, i, acin;
dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
/* Check AC-Adapter */
acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
sharpsl_pm.machinfo->charge(0);
udelay(100);
sharpsl_pm.machinfo->discharge(1); /* enable discharge */
mdelay(SHARPSL_WAIT_DISCHARGE_ON);
}
if (sharpsl_pm.machinfo->discharge1)
sharpsl_pm.machinfo->discharge1(1);
/* Check battery : check inserting battery ? */
for (i=0; i<5; i++) {
buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
}
if (sharpsl_pm.machinfo->discharge1)
sharpsl_pm.machinfo->discharge1(0);
if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
udelay(100);
sharpsl_pm.machinfo->charge(1);
sharpsl_pm.machinfo->discharge(0);
}
temp = get_select_val(buff);
dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %ld\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT));
if ((acin && (temp < sharpsl_pm.machinfo->fatal_acin_volt)) ||
(!acin && (temp < sharpsl_pm.machinfo->fatal_noacin_volt)))
return -1;
return 0;
}
static int sharpsl_off_charge_error(void)
{
dev_err(sharpsl_pm.dev, "Offline Charger: Error occurred.\n");
sharpsl_pm.machinfo->charge(0);
sharpsl_pm_led(SHARPSL_LED_ERROR);
sharpsl_pm.charge_mode = CHRG_ERROR;
return 1;
}
/*
* Charging Control while suspended
* Return 1 - go straight to sleep
* Return 0 - sleep or wakeup depending on other factors
*/
static int sharpsl_off_charge_battery(void)
{
int time;
dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);
if (sharpsl_pm.charge_mode == CHRG_OFF) {
dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
/* AC Check */
if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
return sharpsl_off_charge_error();
/* Start Charging */
sharpsl_pm_led(SHARPSL_LED_ON);
sharpsl_pm.machinfo->charge(0);
mdelay(SHARPSL_CHARGE_WAIT_TIME);
sharpsl_pm.machinfo->charge(1);
sharpsl_pm.charge_mode = CHRG_ON;
sharpsl_pm.full_count = 0;
return 1;
} else if (sharpsl_pm.charge_mode != CHRG_ON) {
return 1;
}
if (sharpsl_pm.full_count == 0) {
int time;
dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
return sharpsl_off_charge_error();
sharpsl_pm.machinfo->charge(0);
mdelay(SHARPSL_CHARGE_WAIT_TIME);
sharpsl_pm.machinfo->charge(1);
sharpsl_pm.charge_mode = CHRG_ON;
mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
time = RCNR;
while(1) {
/* Check if any wakeup event had occurred */
if (sharpsl_pm.machinfo->charger_wakeup() != 0)
return 0;
/* Check for timeout */
if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
return 1;
if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occurred. Retrying to check\n");
sharpsl_pm.full_count++;
sharpsl_pm.machinfo->charge(0);
mdelay(SHARPSL_CHARGE_WAIT_TIME);
sharpsl_pm.machinfo->charge(1);
return 1;
}
}
}
dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");
mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
time = RCNR;
while(1) {
/* Check if any wakeup event had occurred */
if (sharpsl_pm.machinfo->charger_wakeup() != 0)
return 0;
/* Check for timeout */
if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {
dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");
sharpsl_pm.full_count = 0;
}
sharpsl_pm.full_count++;
return 1;
}
if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
sharpsl_pm_led(SHARPSL_LED_OFF);
sharpsl_pm.machinfo->charge(0);
sharpsl_pm.charge_mode = CHRG_DONE;
return 1;
}
}
}
#else
#define sharpsl_pm_suspend NULL
#define sharpsl_pm_resume NULL
#endif
static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
}
static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
}
static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
extern void (*apm_get_power_status)(struct apm_power_info *);
static void sharpsl_apm_get_power_status(struct apm_power_info *info)
{
info->ac_line_status = sharpsl_pm.battstat.ac_status;
if (sharpsl_pm.charge_mode == CHRG_ON)
info->battery_status = APM_BATTERY_STATUS_CHARGING;
else
info->battery_status = sharpsl_pm.battstat.mainbat_status;
info->battery_flag = (1 << info->battery_status);
info->battery_life = sharpsl_pm.battstat.mainbat_percent;
}
#ifdef CONFIG_PM
static struct platform_suspend_ops sharpsl_pm_ops = {
.enter = corgi_pxa_pm_enter,
.valid = suspend_valid_only_mem,
};
#endif
static int __init sharpsl_pm_probe(struct platform_device *pdev)
{
int ret;
if (!pdev->dev.platform_data)
return -EINVAL;
sharpsl_pm.dev = &pdev->dev;
sharpsl_pm.machinfo = pdev->dev.platform_data;
sharpsl_pm.charge_mode = CHRG_OFF;
sharpsl_pm.flags = 0;
init_timer(&sharpsl_pm.ac_timer);
sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
init_timer(&sharpsl_pm.chrg_full_timer);
sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger);
sharpsl_pm.machinfo->init();
ret = device_create_file(&pdev->dev, &dev_attr_battery_percentage);
ret |= device_create_file(&pdev->dev, &dev_attr_battery_voltage);
if (ret != 0)
dev_warn(&pdev->dev, "Failed to register attributes (%d)\n", ret);
apm_get_power_status = sharpsl_apm_get_power_status;
#ifdef CONFIG_PM
suspend_set_ops(&sharpsl_pm_ops);
#endif
mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
return 0;
}
static int sharpsl_pm_remove(struct platform_device *pdev)
{
suspend_set_ops(NULL);
device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
led_trigger_unregister_simple(sharpsl_charge_led_trigger);
sharpsl_pm.machinfo->exit();
del_timer_sync(&sharpsl_pm.chrg_full_timer);
del_timer_sync(&sharpsl_pm.ac_timer);
return 0;
}
static struct platform_driver sharpsl_pm_driver = {
.probe = sharpsl_pm_probe,
.remove = sharpsl_pm_remove,
.suspend = sharpsl_pm_suspend,
.resume = sharpsl_pm_resume,
.driver = {
.name = "sharpsl-pm",
},
};
static int __devinit sharpsl_pm_init(void)
{
return platform_driver_register(&sharpsl_pm_driver);
}
static void sharpsl_pm_exit(void)
{
platform_driver_unregister(&sharpsl_pm_driver);
}
late_initcall(sharpsl_pm_init);
module_exit(sharpsl_pm_exit);
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.27-rc3
# Tue Aug 19 11:26:54 2008
# Linux kernel version: 2.6.30-rc8
# Thu Jun 4 09:53:21 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
......@@ -22,8 +22,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_ZONE_DMA=y
CONFIG_ARCH_MTD_XIP=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
......@@ -44,15 +42,24 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
#
# RCU Subsystem
#
CONFIG_CLASSIC_RCU=y
# CONFIG_TREE_RCU is not set
# CONFIG_PREEMPT_RCU is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=18
# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
......@@ -61,31 +68,37 @@ CONFIG_NAMESPACES=y
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
# CONFIG_NET_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
......@@ -93,19 +106,13 @@ CONFIG_SLUB=y
# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
# CONFIG_HAVE_IOREMAP_PROT is not set
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
# CONFIG_HAVE_ARCH_TRACEHOOK is not set
# CONFIG_HAVE_DMA_ATTRS is not set
# CONFIG_USE_GENERIC_SMP_HELPERS is not set
CONFIG_HAVE_CLK=y
CONFIG_PROC_PAGE_MONITOR=y
# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
......@@ -113,11 +120,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
......@@ -133,7 +137,7 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_CLASSIC_RCU=y
CONFIG_FREEZER=y
#
# System Type
......@@ -143,10 +147,10 @@ CONFIG_CLASSIC_RCU=y
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
......@@ -167,14 +171,17 @@ CONFIG_CLASSIC_RCU=y
# CONFIG_ARCH_ORION5X is not set
# CONFIG_ARCH_PNX4008 is not set
CONFIG_ARCH_PXA=y
# CONFIG_ARCH_MMP is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_MSM7X00A is not set
# CONFIG_ARCH_MSM is not set
# CONFIG_ARCH_W90X900 is not set
#
# Intel PXA2xx/PXA3xx Implementations
......@@ -187,16 +194,24 @@ CONFIG_CPU_PXA300=y
# CONFIG_CPU_PXA310 is not set
# CONFIG_CPU_PXA320 is not set
# CONFIG_CPU_PXA930 is not set
# CONFIG_CPU_PXA935 is not set
# CONFIG_ARCH_GUMSTIX is not set
# CONFIG_MACH_INTELMOTE2 is not set
# CONFIG_ARCH_LUBBOCK is not set
# CONFIG_MACH_LOGICPD_PXA270 is not set
# CONFIG_MACH_MAINSTONE is not set
# CONFIG_MACH_MP900C is not set
# CONFIG_ARCH_PXA_IDP is not set
# CONFIG_PXA_SHARPSL is not set
# CONFIG_ARCH_VIPER is not set
# CONFIG_ARCH_PXA_ESERIES is not set
# CONFIG_MACH_TRIZEPS4 is not set
# CONFIG_TRIZEPS_PXA is not set
# CONFIG_MACH_H5000 is not set
# CONFIG_MACH_EM_X270 is not set
# CONFIG_MACH_EXEDA is not set
# CONFIG_MACH_COLIBRI is not set
# CONFIG_MACH_COLIBRI300 is not set
# CONFIG_MACH_COLIBRI320 is not set
# CONFIG_MACH_ZYLONITE is not set
# CONFIG_MACH_LITTLETON is not set
# CONFIG_MACH_TAVOREVB is not set
......@@ -204,19 +219,15 @@ CONFIG_CPU_PXA300=y
# CONFIG_MACH_ARMCORE is not set
CONFIG_MACH_CM_X300=y
# CONFIG_MACH_MAGICIAN is not set
# CONFIG_MACH_HIMALAYA is not set
# CONFIG_MACH_MIOA701 is not set
# CONFIG_MACH_PCM027 is not set
# CONFIG_ARCH_PXA_PALM is not set
# CONFIG_MACH_CSB726 is not set
# CONFIG_PXA_EZX is not set
CONFIG_PXA3xx=y
# CONFIG_PXA_PWM is not set
#
# Boot options
#
#
# Power management
#
CONFIG_PLAT_PXA=y
#
# Processor Type
......@@ -241,6 +252,7 @@ CONFIG_IO_36=y
CONFIG_OUTER_CACHE=y
CONFIG_CACHE_XSC3L2=y
CONFIG_IWMMXT=y
CONFIG_COMMON_CLKDEV=y
#
# Bus support
......@@ -256,25 +268,33 @@ CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
# CONFIG_PREEMPT is not set
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
CONFIG_HIGHMEM=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_RESOURCES_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
CONFIG_ALIGNMENT_TRAP=y
#
......@@ -287,7 +307,7 @@ CONFIG_CMDLINE="root=/dev/mtdblock5 rootfstype=jffs2 console=ttyS2,38400"
# CONFIG_KEXEC is not set
#
# CPU Frequency scaling
# CPU Power Management
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
......@@ -304,6 +324,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
# CONFIG_CPU_IDLE is not set
#
# Floating point emulation
......@@ -320,6 +341,8 @@ CONFIG_FPE_NWFPE=y
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set
......@@ -376,6 +399,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
......@@ -385,7 +409,9 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
#
# Network testing
......@@ -407,8 +433,7 @@ CONFIG_BT_HIDP=m
#
# Bluetooth device drivers
#
CONFIG_BT_HCIUSB=m
CONFIG_BT_HCIUSB_SCO=y
# CONFIG_BT_HCIBTUSB is not set
# CONFIG_BT_HCIBTSDIO is not set
# CONFIG_BT_HCIUART is not set
# CONFIG_BT_HCIBCM203X is not set
......@@ -416,19 +441,15 @@ CONFIG_BT_HCIUSB_SCO=y
# CONFIG_BT_HCIBFUSB is not set
# CONFIG_BT_HCIVHCI is not set
# CONFIG_AF_RXRPC is not set
#
# Wireless
#
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
CONFIG_LIB80211=m
# CONFIG_LIB80211_DEBUG is not set
# CONFIG_MAC80211 is not set
CONFIG_IEEE80211=m
# CONFIG_IEEE80211_DEBUG is not set
CONFIG_IEEE80211_CRYPT_WEP=m
CONFIG_IEEE80211_CRYPT_CCMP=m
CONFIG_IEEE80211_CRYPT_TKIP=m
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
......@@ -453,6 +474,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AFS_PARTS is not set
......@@ -494,7 +516,6 @@ CONFIG_MTD_CFI_I2=y
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_SHARP_SL is not set
# CONFIG_MTD_PLATRAM is not set
#
......@@ -516,15 +537,22 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_ECC_SMC is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
# CONFIG_MTD_NAND_H1900 is not set
# CONFIG_MTD_NAND_GPIO is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_SHARPSL is not set
CONFIG_MTD_NAND_PXA3xx=y
# CONFIG_MTD_NAND_PXA3xx_BUILTIN is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set
# CONFIG_MTD_ONENAND is not set
#
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
#
# UBI - Unsorted block images
#
......@@ -585,11 +613,15 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_LIBFC is not set
# CONFIG_LIBFCOE is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
......@@ -604,11 +636,17 @@ CONFIG_MII=y
CONFIG_DM9000=y
CONFIG_DM9000_DEBUGLEVEL=0
CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
......@@ -624,9 +662,12 @@ CONFIG_LIBERTAS_SDIO=m
# CONFIG_LIBERTAS_DEBUG is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_USB_NET_RNDIS_WLAN is not set
# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_HOSTAP is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#
#
# USB Network Adapters
#
......@@ -677,18 +718,21 @@ CONFIG_KEYBOARD_PXA27x=m
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
# CONFIG_TOUCHSCREEN_AD7879 is not set
# CONFIG_TOUCHSCREEN_FUJITSU is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_INEXIO is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
# CONFIG_TOUCHSCREEN_PENMOUNT is not set
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_TOUCHSCREEN_UCB1400 is not set
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
# CONFIG_TOUCHSCREEN_TSC2007 is not set
# CONFIG_INPUT_MISC is not set
#
......@@ -721,10 +765,10 @@ CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_NVRAM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
......@@ -763,12 +807,8 @@ CONFIG_I2C_PXA=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_TPS65010 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
......@@ -781,6 +821,10 @@ CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
# CONFIG_GPIO_SYSFS is not set
#
# Memory mapped GPIO expanders:
#
#
# I2C GPIO expanders:
#
......@@ -798,12 +842,14 @@ CONFIG_GPIO_PCA953X=y
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
......@@ -811,12 +857,19 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_ASIC3 is not set
# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_TPS65010 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_T7L66XB is not set
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
#
# Multimedia devices
......@@ -842,6 +895,7 @@ CONFIG_SSB_POSSIBLE=y
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
# CONFIG_FB_BOOT_VESA_SUPPORT is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
......@@ -862,12 +916,15 @@ CONFIG_FB_CFB_IMAGEBLIT=y
#
# CONFIG_FB_S1D13XXX is not set
CONFIG_FB_PXA=y
# CONFIG_FB_PXA_OVERLAY is not set
# CONFIG_FB_PXA_SMARTPANEL is not set
# CONFIG_FB_PXA_PARAMETERS is not set
# CONFIG_FB_MBX is not set
# CONFIG_FB_W100 is not set
# CONFIG_FB_AM200EPD is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
......@@ -899,9 +956,11 @@ CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
CONFIG_SOUND=m
# CONFIG_SOUND_OSS_CORE is not set
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
CONFIG_SND_JACK=y
# CONFIG_SND_SEQUENCER is not set
# CONFIG_SND_MIXER_OSS is not set
# CONFIG_SND_PCM_OSS is not set
......@@ -916,12 +975,15 @@ CONFIG_SND_DRIVERS=y
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
CONFIG_SND_ARM=y
CONFIG_SND_PXA2XX_LIB=m
# CONFIG_SND_PXA2XX_AC97 is not set
CONFIG_SND_USB=y
# CONFIG_SND_USB_AUDIO is not set
# CONFIG_SND_USB_CAIAQ is not set
CONFIG_SND_SOC=m
CONFIG_SND_PXA2XX_SOC=m
CONFIG_SND_SOC_I2C_AND_SPI=m
# CONFIG_SND_SOC_ALL_CODECS is not set
# CONFIG_SOUND_PRIME is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
......@@ -932,9 +994,39 @@ CONFIG_HID_DEBUG=y
# USB Input Devices
#
CONFIG_USB_HID=y
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set
#
# Special HID drivers
#
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
CONFIG_HID_KYE=y
CONFIG_HID_GYRATION=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
CONFIG_HID_NTRIG=y
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
CONFIG_HID_SUNPLUS=y
# CONFIG_GREENASIA_FF is not set
CONFIG_HID_TOPSEED=y
# CONFIG_THRUSTMASTER_FF is not set
# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
......@@ -952,11 +1044,14 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
CONFIG_USB_MON=y
# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set
#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
......@@ -965,6 +1060,7 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_HWA_HCD is not set
# CONFIG_USB_MUSB_HDRC is not set
#
......@@ -973,20 +1069,20 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_WDM is not set
# CONFIG_USB_TMC is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
# may also be needed; see USB_STORAGE Help for more information
# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
......@@ -994,7 +1090,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_SIERRA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_LIBUSUAL is not set
......@@ -1015,6 +1110,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
......@@ -1022,7 +1118,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
......@@ -1031,13 +1126,20 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
#
# OTG and related infrastructure
#
# CONFIG_USB_GPIO_VBUS is not set
# CONFIG_NOP_USB_XCEIV is not set
CONFIG_MMC=m
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
#
# MMC/SD Card Drivers
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=m
CONFIG_MMC_BLOCK_BOUNCE=y
......@@ -1045,10 +1147,12 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_MMC_TEST is not set
#
# MMC/SD Host Controller Drivers
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_PXA=m
# CONFIG_MMC_SDHCI is not set
# CONFIG_MEMSTICK is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
......@@ -1057,7 +1161,10 @@ CONFIG_LEDS_CLASS=y
#
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_GPIO_PLATFORM=y
# CONFIG_LEDS_LP5521 is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_BD2802 is not set
#
# LED Triggers
......@@ -1065,7 +1172,13 @@ CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
# CONFIG_LEDS_TRIGGER_TIMER is not set
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_GPIO is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
#
# iptables trigger is under Netfilter config (LED target)
#
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
......@@ -1096,6 +1209,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
......@@ -1105,28 +1219,27 @@ CONFIG_RTC_INTF_DEV=y
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_V3020 is not set
# CONFIG_RTC_DRV_BQ4802 is not set
CONFIG_RTC_DRV_V3020=y
#
# on-CPU RTC drivers
#
CONFIG_RTC_DRV_SA1100=y
# CONFIG_RTC_DRV_PXA is not set
# CONFIG_DMADEVICES is not set
#
# Voltage and Current regulators
#
# CONFIG_AUXDISPLAY is not set
# CONFIG_REGULATOR is not set
# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
# CONFIG_REGULATOR_BQ24022 is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
#
# File systems
......@@ -1135,15 +1248,18 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set
# CONFIG_EXT4DEV_FS is not set
# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
......@@ -1152,6 +1268,11 @@ CONFIG_INOTIFY_USER=y
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
# Caches
#
# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
#
......@@ -1173,15 +1294,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
#
CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
......@@ -1201,6 +1320,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
......@@ -1209,6 +1329,7 @@ CONFIG_JFFS2_RTIME=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
......@@ -1313,6 +1434,7 @@ CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
# CONFIG_DETECT_HUNG_TASK is not set
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
......@@ -1329,6 +1451,7 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
......@@ -1336,22 +1459,38 @@ CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
CONFIG_FRAME_POINTER=y
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
# CONFIG_FTRACE is not set
# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_TRACING_SUPPORT=y
#
# Tracers
#
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
CONFIG_ARM_UNWIND=y
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_ERRORS is not set
# CONFIG_DEBUG_STACK_USAGE is not set
......@@ -1363,17 +1502,28 @@ CONFIG_DEBUG_LL=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
......@@ -1442,15 +1592,21 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
# CONFIG_BINARY_PRINTF is not set
#
# Library routines
#
CONFIG_BITREVERSE=y
# CONFIG_GENERIC_FIND_FIRST_BIT is not set
# CONFIG_GENERIC_FIND_NEXT_BIT is not set
CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC_T10DIF=y
......@@ -1460,7 +1616,10 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_NLATTR=y
......@@ -190,6 +190,7 @@ CONFIG_ARCH_PXA=y
# CONFIG_MACH_SAAR is not set
# CONFIG_MACH_ARMCORE is not set
# CONFIG_MACH_CM_X300 is not set
CONFIG_MACH_H4700=y
CONFIG_MACH_MAGICIAN=y
# CONFIG_MACH_MIOA701 is not set
# CONFIG_MACH_PCM027 is not set
......@@ -828,7 +829,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_ASIC3 is not set
CONFIG_MFD_ASIC3=y
CONFIG_HTC_EGPIO=y
CONFIG_HTC_PASIC3=y
# CONFIG_TPS65010 is not set
......@@ -891,7 +892,7 @@ CONFIG_FB_PXA_OVERLAY=y
# CONFIG_FB_PXA_SMARTPANEL is not set
# CONFIG_FB_PXA_PARAMETERS is not set
# CONFIG_FB_MBX is not set
# CONFIG_FB_W100 is not set
CONFIG_FB_W100=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
......
......@@ -52,6 +52,7 @@
/*
* Interrupt numbers for PXA910
*/
#define IRQ_PXA910_NONE (-1)
#define IRQ_PXA910_AIRQ 0
#define IRQ_PXA910_SSP3 1
#define IRQ_PXA910_SSP2 2
......
......@@ -253,6 +253,10 @@
#define GPIO58_LCD_PCLK_WR MFP_CFG(GPIO58, AF1)
#define GPIO85_LCD_VSYNC MFP_CFG(GPIO85, AF1)
/* I2C */
#define GPIO105_CI2C_SDA MFP_CFG(GPIO105, AF1)
#define GPIO106_CI2C_SCL MFP_CFG(GPIO106, AF1)
/* I2S */
#define GPIO113_I2S_MCLK MFP_CFG(GPIO113,AF6)
#define GPIO114_I2S_FRM MFP_CFG(GPIO114,AF1)
......@@ -260,4 +264,27 @@
#define GPIO116_I2S_RXD MFP_CFG(GPIO116,AF2)
#define GPIO117_I2S_TXD MFP_CFG(GPIO117,AF2)
/* PWM */
#define GPIO96_PWM3_OUT MFP_CFG(GPIO96, AF1)
#define GPIO97_PWM2_OUT MFP_CFG(GPIO97, AF1)
#define GPIO98_PWM1_OUT MFP_CFG(GPIO98, AF1)
#define GPIO104_PWM4_OUT MFP_CFG(GPIO104, AF1)
#define GPIO106_PWM2_OUT MFP_CFG(GPIO106, AF2)
#define GPIO74_PWM4_OUT MFP_CFG(GPIO74, AF2)
#define GPIO75_PWM3_OUT MFP_CFG(GPIO75, AF2)
#define GPIO76_PWM2_OUT MFP_CFG(GPIO76, AF2)
#define GPIO77_PWM1_OUT MFP_CFG(GPIO77, AF2)
#define GPIO82_PWM4_OUT MFP_CFG(GPIO82, AF2)
#define GPIO83_PWM3_OUT MFP_CFG(GPIO83, AF2)
#define GPIO84_PWM2_OUT MFP_CFG(GPIO84, AF2)
#define GPIO85_PWM1_OUT MFP_CFG(GPIO85, AF2)
#define GPIO84_PWM1_OUT MFP_CFG(GPIO84, AF4)
#define GPIO122_PWM3_OUT MFP_CFG(GPIO122, AF3)
#define GPIO123_PWM1_OUT MFP_CFG(GPIO123, AF1)
#define GPIO124_PWM2_OUT MFP_CFG(GPIO124, AF1)
#define GPIO125_PWM3_OUT MFP_CFG(GPIO125, AF1)
#define GPIO126_PWM4_OUT MFP_CFG(GPIO126, AF1)
#define GPIO86_PWM1_OUT MFP_CFG(GPIO86, AF2)
#define GPIO86_PWM2_OUT MFP_CFG(GPIO86, AF3)
#endif /* __ASM_MACH_MFP_PXA168_H */
......@@ -159,4 +159,12 @@
#define MMC1_CD_MMC1_CD MFP_CFG_DRV(MMC1_CD, AF0, MEDIUM)
#define MMC1_WP_MMC1_WP MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM)
/* PWM */
#define GPIO27 PWM3 AF2 MFP_CFG(GPIO27, AF2)
#define GPIO51_PWM2_OUT MFP_CFG(GPIO51, AF2)
#define GPIO117_PWM1_OUT MFP_CFG(GPIO117, AF2)
#define GPIO118_PWM2_OUT MFP_CFG(GPIO118, AF2)
#define GPIO119_PWM3_OUT MFP_CFG(GPIO119, AF2)
#define GPIO120_PWM4_OUT MFP_CFG(GPIO120, AF2)
#endif /* __ASM_MACH MFP_PXA910_H */
#ifndef __ASM_MACH_PXA168_H
#define __ASM_MACH_PXA168_H
#include <linux/i2c.h>
#include <mach/devices.h>
#include <plat/i2c.h>
extern struct pxa_device_desc pxa168_device_uart1;
extern struct pxa_device_desc pxa168_device_uart2;
extern struct pxa_device_desc pxa168_device_twsi0;
extern struct pxa_device_desc pxa168_device_twsi1;
extern struct pxa_device_desc pxa168_device_pwm1;
extern struct pxa_device_desc pxa168_device_pwm2;
extern struct pxa_device_desc pxa168_device_pwm3;
extern struct pxa_device_desc pxa168_device_pwm4;
static inline int pxa168_add_uart(int id)
{
......@@ -20,4 +28,40 @@ static inline int pxa168_add_uart(int id)
return pxa_register_device(d, NULL, 0);
}
static inline int pxa168_add_twsi(int id, struct i2c_pxa_platform_data *data,
struct i2c_board_info *info, unsigned size)
{
struct pxa_device_desc *d = NULL;
int ret;
switch (id) {
case 0: d = &pxa168_device_twsi0; break;
case 1: d = &pxa168_device_twsi1; break;
default:
return -EINVAL;
}
ret = i2c_register_board_info(id, info, size);
if (ret)
return ret;
return pxa_register_device(d, data, sizeof(*data));
}
static inline int pxa168_add_pwm(int id)
{
struct pxa_device_desc *d = NULL;
switch (id) {
case 1: d = &pxa168_device_pwm1; break;
case 2: d = &pxa168_device_pwm2; break;
case 3: d = &pxa168_device_pwm3; break;
case 4: d = &pxa168_device_pwm4; break;
default:
return -EINVAL;
}
return pxa_register_device(d, NULL, 0);
}
#endif /* __ASM_MACH_PXA168_H */
#ifndef __ASM_MACH_PXA910_H
#define __ASM_MACH_PXA910_H
#include <linux/i2c.h>
#include <mach/devices.h>
#include <plat/i2c.h>
extern struct pxa_device_desc pxa910_device_uart1;
extern struct pxa_device_desc pxa910_device_uart2;
extern struct pxa_device_desc pxa910_device_twsi0;
extern struct pxa_device_desc pxa910_device_twsi1;
extern struct pxa_device_desc pxa910_device_pwm1;
extern struct pxa_device_desc pxa910_device_pwm2;
extern struct pxa_device_desc pxa910_device_pwm3;
extern struct pxa_device_desc pxa910_device_pwm4;
static inline int pxa910_add_uart(int id)
{
......@@ -20,4 +28,40 @@ static inline int pxa910_add_uart(int id)
return pxa_register_device(d, NULL, 0);
}
static inline int pxa910_add_twsi(int id, struct i2c_pxa_platform_data *data,
struct i2c_board_info *info, unsigned size)
{
struct pxa_device_desc *d = NULL;
int ret;
switch (id) {
case 0: d = &pxa910_device_twsi0; break;
case 1: d = &pxa910_device_twsi1; break;
default:
return -EINVAL;
}
ret = i2c_register_board_info(id, info, size);
if (ret)
return ret;
return pxa_register_device(d, data, sizeof(*data));
}
static inline int pxa910_add_pwm(int id)
{
struct pxa_device_desc *d = NULL;
switch (id) {
case 1: d = &pxa910_device_pwm1; break;
case 2: d = &pxa910_device_pwm2; break;
case 3: d = &pxa910_device_pwm3; break;
case 4: d = &pxa910_device_pwm4; break;
default:
return -EINVAL;
}
return pxa_register_device(d, NULL, 0);
}
#endif /* __ASM_MACH_PXA910_H */
......@@ -22,8 +22,10 @@
#define APBC_PXA168_UART1 APBC_REG(0x000)
#define APBC_PXA168_UART2 APBC_REG(0x004)
#define APBC_PXA168_GPIO APBC_REG(0x008)
#define APBC_PXA168_PWM0 APBC_REG(0x00c)
#define APBC_PXA168_PWM1 APBC_REG(0x010)
#define APBC_PXA168_PWM1 APBC_REG(0x00c)
#define APBC_PXA168_PWM2 APBC_REG(0x010)
#define APBC_PXA168_PWM3 APBC_REG(0x014)
#define APBC_PXA168_PWM4 APBC_REG(0x018)
#define APBC_PXA168_SSP1 APBC_REG(0x01c)
#define APBC_PXA168_SSP2 APBC_REG(0x020)
#define APBC_PXA168_RTC APBC_REG(0x028)
......@@ -48,10 +50,10 @@
#define APBC_PXA910_UART0 APBC_REG(0x000)
#define APBC_PXA910_UART1 APBC_REG(0x004)
#define APBC_PXA910_GPIO APBC_REG(0x008)
#define APBC_PXA910_PWM0 APBC_REG(0x00c)
#define APBC_PXA910_PWM1 APBC_REG(0x010)
#define APBC_PXA910_PWM2 APBC_REG(0x014)
#define APBC_PXA910_PWM3 APBC_REG(0x018)
#define APBC_PXA910_PWM1 APBC_REG(0x00c)
#define APBC_PXA910_PWM2 APBC_REG(0x010)
#define APBC_PXA910_PWM3 APBC_REG(0x014)
#define APBC_PXA910_PWM4 APBC_REG(0x018)
#define APBC_PXA910_SSP1 APBC_REG(0x01c)
#define APBC_PXA910_SSP2 APBC_REG(0x020)
#define APBC_PXA910_IPC APBC_REG(0x024)
......
......@@ -65,11 +65,23 @@ void __init pxa168_init_irq(void)
/* APB peripheral clocks */
static APBC_CLK(uart1, PXA168_UART1, 1, 14745600);
static APBC_CLK(uart2, PXA168_UART2, 1, 14745600);
static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000);
static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000);
static APBC_CLK(pwm1, PXA168_PWM1, 1, 13000000);
static APBC_CLK(pwm2, PXA168_PWM2, 1, 13000000);
static APBC_CLK(pwm3, PXA168_PWM3, 1, 13000000);
static APBC_CLK(pwm4, PXA168_PWM4, 1, 13000000);
/* device and clock bindings */
static struct clk_lookup pxa168_clkregs[] = {
INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
INIT_CLKREG(&clk_pwm1, "pxa168-pwm.0", NULL),
INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL),
INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL),
INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL),
};
static int __init pxa168_init(void)
......@@ -109,3 +121,9 @@ struct sys_timer pxa168_timer = {
/* on-chip devices */
PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22);
PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24);
PXA168_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28);
PXA168_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28);
PXA168_DEVICE(pwm1, "pxa168-pwm", 0, NONE, 0xd401a000, 0x10);
PXA168_DEVICE(pwm2, "pxa168-pwm", 1, NONE, 0xd401a400, 0x10);
PXA168_DEVICE(pwm3, "pxa168-pwm", 2, NONE, 0xd401a800, 0x10);
PXA168_DEVICE(pwm4, "pxa168-pwm", 3, NONE, 0xd401ac00, 0x10);
......@@ -103,11 +103,23 @@ void __init pxa910_init_irq(void)
/* APB peripheral clocks */
static APBC_CLK(uart1, PXA910_UART0, 1, 14745600);
static APBC_CLK(uart2, PXA910_UART1, 1, 14745600);
static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000);
static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000);
static APBC_CLK(pwm1, PXA910_PWM1, 1, 13000000);
static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000);
static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
/* device and clock bindings */
static struct clk_lookup pxa910_clkregs[] = {
INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
INIT_CLKREG(&clk_pwm1, "pxa910-pwm.0", NULL),
INIT_CLKREG(&clk_pwm2, "pxa910-pwm.1", NULL),
INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL),
INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
};
static int __init pxa910_init(void)
......@@ -156,3 +168,9 @@ struct sys_timer pxa910_timer = {
*/
PXA910_DEVICE(uart1, "pxa2xx-uart", 0, UART2, 0xd4017000, 0x30, 21, 22);
PXA910_DEVICE(uart2, "pxa2xx-uart", 1, UART3, 0xd4018000, 0x30, 23, 24);
PXA910_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28);
PXA910_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28);
PXA910_DEVICE(pwm1, "pxa910-pwm", 0, NONE, 0xd401a000, 0x10);
PXA910_DEVICE(pwm2, "pxa910-pwm", 1, NONE, 0xd401a400, 0x10);
PXA910_DEVICE(pwm3, "pxa910-pwm", 2, NONE, 0xd401a800, 0x10);
PXA910_DEVICE(pwm4, "pxa910-pwm", 3, NONE, 0xd401ac00, 0x10);
......@@ -51,6 +51,12 @@ config MACH_INTELMOTE2
select IWMMXT
select PXA_HAVE_BOARD_IRQS
config MACH_STARGATE2
bool "Intel Stargate 2 Platform"
select PXA27x
select IWMMXT
select PXA_HAVE_BOARD_IRQS
config ARCH_LUBBOCK
bool "Intel DBPXA250 Development Platform"
select PXA25x
......@@ -88,6 +94,10 @@ config PXA_SHARPSL
SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
handheld computer.
config SHARPSL_PM
bool
select APM_EMULATION
config CORGI_SSP_DEPRECATED
bool
select PXA_SSP
......@@ -280,6 +290,7 @@ config MACH_ZYLONITE
select PXA3xx
select PXA_SSP
select HAVE_PWM
select PXA_HAVE_BOARD_IRQS
config MACH_LITTLETON
bool "PXA3xx Form Factor Platform (aka Littleton)"
......@@ -308,6 +319,14 @@ config MACH_CM_X300
select PXA3xx
select CPU_PXA300
config MACH_H4700
bool "HP iPAQ hx4700"
select PXA27x
select IWMMXT
select PXA_SSP
select HAVE_PWM
select PXA_HAVE_BOARD_IRQS
config MACH_MAGICIAN
bool "Enable HTC Magician Support"
select PXA27x
......@@ -505,12 +524,6 @@ config PXA_SSP
help
Enable support for PXA2xx SSP ports
config PXA_PWM
tristate
default BACKLIGHT_PWM
help
Enable support for PXA2xx/PXA3xx PWM controllers
config TOSA_BT
tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
depends on MACH_TOSA
......
......@@ -15,7 +15,6 @@ endif
# Generic drivers that other drivers may depend upon
obj-$(CONFIG_PXA_SSP) += ssp.o
obj-$(CONFIG_PXA_PWM) += pwm.o
# SoC-specific code
obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o
......@@ -47,6 +46,7 @@ obj-$(CONFIG_MACH_PCM027) += pcm027.o
obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o
obj-$(CONFIG_MACH_TOSA) += tosa.o
obj-$(CONFIG_MACH_EM_X270) += em-x270.o
obj-$(CONFIG_MACH_H4700) += hx4700.o
obj-$(CONFIG_MACH_MAGICIAN) += magician.o
obj-$(CONFIG_MACH_HIMALAYA) += himalaya.o
obj-$(CONFIG_MACH_MIOA701) += mioa701.o mioa701_bootresume.o
......@@ -78,6 +78,7 @@ obj-$(CONFIG_MACH_CM_X300) += cm-x300.o
obj-$(CONFIG_PXA_EZX) += ezx.o
obj-$(CONFIG_MACH_INTELMOTE2) += imote2.o
obj-$(CONFIG_MACH_STARGATE2) += stargate2.o
obj-$(CONFIG_MACH_CSB726) += csb726.o
obj-$(CONFIG_CSB726_CSB701) += csb701.o
......
......@@ -335,6 +335,10 @@ void __init cmx270_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config));
#ifdef CONFIG_PM
pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP);
#endif
cmx270_init_rtc();
cmx270_init_mmc();
cmx270_init_ohci();
......
......@@ -21,18 +21,20 @@
#include <linux/gpio.h>
#include <linux/dm9000.h>
#include <linux/leds.h>
#include <linux/rtc-v3020.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/setup.h>
#include <mach/pxa300.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/pxa3xx_nand.h>
#include <asm/mach/map.h>
......@@ -46,6 +48,11 @@
#define CM_X300_MMC2_IRQ IRQ_GPIO(GPIO82_MMC2_IRQ)
#define GPIO95_RTC_CS (95)
#define GPIO96_RTC_WR (96)
#define GPIO97_RTC_RD (97)
#define GPIO98_RTC_IO (98)
static mfp_cfg_t cm_x300_mfp_cfg[] __initdata = {
/* LCD */
GPIO54_LCD_LDD_0,
......@@ -135,6 +142,12 @@ static mfp_cfg_t cm_x300_mfp_cfg[] __initdata = {
GPIO85_GPIO, /* MMC WP */
GPIO99_GPIO, /* Ethernet IRQ */
/* RTC GPIOs */
GPIO95_GPIO, /* RTC CS */
GPIO96_GPIO, /* RTC WR */
GPIO97_GPIO, /* RTC RD */
GPIO98_GPIO, /* RTC IO */
/* Standard I2C */
GPIO21_I2C_SCL,
GPIO22_I2C_SDA,
......@@ -265,6 +278,7 @@ static struct mtd_partition cm_x300_nand_partitions[] = {
static struct pxa3xx_nand_platform_data cm_x300_nand_info = {
.enable_arbiter = 1,
.keep_config = 1,
.parts = cm_x300_nand_partitions,
.nr_parts = ARRAY_SIZE(cm_x300_nand_partitions),
};
......@@ -441,6 +455,31 @@ static void __init cm_x300_init_i2c(void)
static inline void cm_x300_init_i2c(void) {}
#endif
#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
struct v3020_platform_data cm_x300_v3020_pdata = {
.use_gpio = 1,
.gpio_cs = GPIO95_RTC_CS,
.gpio_wr = GPIO96_RTC_WR,
.gpio_rd = GPIO97_RTC_RD,
.gpio_io = GPIO98_RTC_IO,
};
static struct platform_device cm_x300_rtc_device = {
.name = "v3020",
.id = -1,
.dev = {
.platform_data = &cm_x300_v3020_pdata,
}
};
static void __init cm_x300_init_rtc(void)
{
platform_device_register(&cm_x300_rtc_device);
}
#else
static inline void cm_x300_init_rtc(void) {}
#endif
static void __init cm_x300_init(void)
{
/* board-processor specific GPIO initialization */
......@@ -453,6 +492,19 @@ static void __init cm_x300_init(void)
cm_x300_init_nand();
cm_x300_init_leds();
cm_x300_init_i2c();
cm_x300_init_rtc();
}
static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
mi->nr_banks = 2;
mi->bank[0].start = 0xa0000000;
mi->bank[0].node = 0;
mi->bank[0].size = (64*1024*1024);
mi->bank[1].start = 0xc0000000;
mi->bank[1].node = 0;
mi->bank[1].size = (64*1024*1024);
}
MACHINE_START(CM_X300, "CM-X300 module")
......@@ -463,4 +515,5 @@ MACHINE_START(CM_X300, "CM-X300 module")
.init_irq = pxa3xx_init_irq,
.timer = &pxa_timer,
.init_machine = cm_x300_init,
.fixup = cm_x300_fixup,
MACHINE_END
......@@ -42,7 +42,7 @@
#include <asm/mach/irq.h>
#include <mach/pxa25x.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/irda.h>
#include <mach/mmc.h>
#include <mach/udc.h>
......@@ -445,13 +445,8 @@ static struct ads7846_platform_data corgi_ads7846_info = {
.wait_for_sync = corgi_wait_for_hsync,
};
static void corgi_ads7846_cs(u32 command)
{
gpio_set_value(CORGI_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT));
}
static struct pxa2xx_spi_chip corgi_ads7846_chip = {
.cs_control = corgi_ads7846_cs,
.gpio_cs = CORGI_GPIO_ADS7846_CS,
};
static void corgi_bl_kick_battery(void)
......@@ -475,22 +470,12 @@ static struct corgi_lcd_platform_data corgi_lcdcon_info = {
.kick_battery = corgi_bl_kick_battery,
};
static void corgi_lcdcon_cs(u32 command)
{
gpio_set_value(CORGI_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT));
}
static struct pxa2xx_spi_chip corgi_lcdcon_chip = {
.cs_control = corgi_lcdcon_cs,
.gpio_cs = CORGI_GPIO_LCDCON_CS,
};
static void corgi_max1111_cs(u32 command)
{
gpio_set_value(CORGI_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT));
}
static struct pxa2xx_spi_chip corgi_max1111_chip = {
.cs_control = corgi_max1111_cs,
.gpio_cs = CORGI_GPIO_MAX1111_CS,
};
static struct spi_board_info corgi_spi_devices[] = {
......@@ -520,32 +505,8 @@ static struct spi_board_info corgi_spi_devices[] = {
static void __init corgi_init_spi(void)
{
int err;
err = gpio_request(CORGI_GPIO_ADS7846_CS, "ADS7846_CS");
if (err)
return;
err = gpio_request(CORGI_GPIO_LCDCON_CS, "LCDCON_CS");
if (err)
goto err_free_1;
err = gpio_request(CORGI_GPIO_MAX1111_CS, "MAX1111_CS");
if (err)
goto err_free_2;
gpio_direction_output(CORGI_GPIO_ADS7846_CS, 1);
gpio_direction_output(CORGI_GPIO_LCDCON_CS, 1);
gpio_direction_output(CORGI_GPIO_MAX1111_CS, 1);
pxa2xx_set_spi_info(1, &corgi_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices));
return;
err_free_2:
gpio_free(CORGI_GPIO_LCDCON_CS);
err_free_1:
gpio_free(CORGI_GPIO_ADS7846_CS);
}
#else
static inline void corgi_init_spi(void) {}
......
......@@ -41,7 +41,6 @@ static void corgi_charger_init(void)
pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT);
pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT);
pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN);
sharpsl_pm_pxa_init();
}
static void corgi_measure_temp(int on)
......@@ -191,7 +190,7 @@ unsigned long corgipm_read_devdata(int type)
static struct sharpsl_charger_machinfo corgi_pm_machinfo = {
.init = corgi_charger_init,
.exit = sharpsl_pm_pxa_remove,
.exit = NULL,
.gpio_batlock = CORGI_GPIO_BAT_COVER,
.gpio_acin = CORGI_GPIO_AC_IN,
.gpio_batfull = CORGI_GPIO_CHRG_FULL,
......
......@@ -36,6 +36,8 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/regulator/consumer.h>
#include <mach/pxa2xx-regs.h>
......@@ -47,6 +49,8 @@ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
#define freq_debug 0
#endif
static struct regulator *vcc_core;
static unsigned int pxa27x_maxfreq;
module_param(pxa27x_maxfreq, uint, 0);
MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz"
......@@ -58,6 +62,8 @@ typedef struct {
unsigned int cccr;
unsigned int div2;
unsigned int cclkcfg;
int vmin;
int vmax;
} pxa_freqs_t;
/* Define the refresh period in mSec for the SDRAM and the number of rows */
......@@ -83,23 +89,23 @@ static unsigned int sdram_rows;
static pxa_freqs_t pxa255_run_freqs[] =
{
/* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */
{ 99500, 99500, 0x121, 1, CCLKCFG}, /* 99, 99, 50, 50 */
{132700, 132700, 0x123, 1, CCLKCFG}, /* 133, 133, 66, 66 */
{199100, 99500, 0x141, 0, CCLKCFG}, /* 199, 199, 99, 99 */
{265400, 132700, 0x143, 1, CCLKCFG}, /* 265, 265, 133, 66 */
{331800, 165900, 0x145, 1, CCLKCFG}, /* 331, 331, 166, 83 */
{398100, 99500, 0x161, 0, CCLKCFG}, /* 398, 398, 196, 99 */
{ 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */
{132700, 132700, 0x123, 1, CCLKCFG, -1, -1}, /* 133, 133, 66, 66 */
{199100, 99500, 0x141, 0, CCLKCFG, -1, -1}, /* 199, 199, 99, 99 */
{265400, 132700, 0x143, 1, CCLKCFG, -1, -1}, /* 265, 265, 133, 66 */
{331800, 165900, 0x145, 1, CCLKCFG, -1, -1}, /* 331, 331, 166, 83 */
{398100, 99500, 0x161, 0, CCLKCFG, -1, -1}, /* 398, 398, 196, 99 */
};
/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
static pxa_freqs_t pxa255_turbo_freqs[] =
{
/* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */
{ 99500, 99500, 0x121, 1, CCLKCFG}, /* 99, 99, 50, 50 */
{199100, 99500, 0x221, 0, CCLKCFG}, /* 99, 199, 50, 99 */
{298500, 99500, 0x321, 0, CCLKCFG}, /* 99, 287, 50, 99 */
{298600, 99500, 0x1c1, 0, CCLKCFG}, /* 199, 287, 99, 99 */
{398100, 99500, 0x241, 0, CCLKCFG}, /* 199, 398, 99, 99 */
{ 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */
{199100, 99500, 0x221, 0, CCLKCFG, -1, -1}, /* 99, 199, 50, 99 */
{298500, 99500, 0x321, 0, CCLKCFG, -1, -1}, /* 99, 287, 50, 99 */
{298600, 99500, 0x1c1, 0, CCLKCFG, -1, -1}, /* 199, 287, 99, 99 */
{398100, 99500, 0x241, 0, CCLKCFG, -1, -1}, /* 199, 398, 99, 99 */
};
#define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
......@@ -148,13 +154,13 @@ MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table
((T) ? CCLKCFG_TURBO : 0))
static pxa_freqs_t pxa27x_freqs[] = {
{104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1)},
{156000, 104000, PXA27x_CCCR(1, 8, 6), 0, CCLKCFG2(1, 1, 1)},
{208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1)},
{312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1)},
{416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1)},
{520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1)},
{624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1)}
{104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 },
{156000, 104000, PXA27x_CCCR(1, 8, 6), 0, CCLKCFG2(1, 1, 1), 1000000, 1705000 },
{208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 },
{312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 },
{416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 },
{520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1), 1450000, 1705000 },
{624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1), 1550000, 1705000 }
};
#define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs)
......@@ -163,6 +169,47 @@ static struct cpufreq_frequency_table
extern unsigned get_clk_frequency_khz(int info);
#ifdef CONFIG_REGULATOR
static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq)
{
int ret = 0;
int vmin, vmax;
if (!cpu_is_pxa27x())
return 0;
vmin = pxa_freq->vmin;
vmax = pxa_freq->vmax;
if ((vmin == -1) || (vmax == -1))
return 0;
ret = regulator_set_voltage(vcc_core, vmin, vmax);
if (ret)
pr_err("cpufreq: Failed to set vcc_core in [%dmV..%dmV]\n",
vmin, vmax);
return ret;
}
static __init void pxa_cpufreq_init_voltages(void)
{
vcc_core = regulator_get(NULL, "vcc_core");
if (IS_ERR(vcc_core)) {
pr_info("cpufreq: Didn't find vcc_core regulator\n");
vcc_core = NULL;
} else {
pr_info("cpufreq: Found vcc_core regulator\n");
}
}
#else
static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq)
{
return 0;
}
static __init void pxa_cpufreq_init_voltages(void) { }
#endif
static void find_freq_tables(struct cpufreq_frequency_table **freq_table,
pxa_freqs_t **pxa_freqs)
{
......@@ -251,6 +298,7 @@ static int pxa_set_target(struct cpufreq_policy *policy,
unsigned long flags;
unsigned int new_freq_cpu, new_freq_mem;
unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg;
int ret = 0;
/* Get the current policy */
find_freq_tables(&pxa_freqs_table, &pxa_freq_settings);
......@@ -273,6 +321,10 @@ static int pxa_set_target(struct cpufreq_policy *policy,
freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
(new_freq_mem / 2000) : (new_freq_mem / 1000));
if (vcc_core && freqs.new > freqs.old)
ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]);
if (ret)
return ret;
/*
* Tell everyone what we're about to do...
* you should add a notify client with any platform specific
......@@ -335,6 +387,18 @@ static int pxa_set_target(struct cpufreq_policy *policy,
*/
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
/*
* Even if voltage setting fails, we don't report it, as the frequency
* change succeeded. The voltage reduction is not a critical failure,
* only power savings will suffer from this.
*
* Note: if the voltage change fails, and a return value is returned, a
* bug is triggered (seems a deadlock). Should anybody find out where,
* the "return 0" should become a "return ret".
*/
if (vcc_core && freqs.new < freqs.old)
ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]);
return 0;
}
......@@ -349,6 +413,8 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
if (cpu_is_pxa27x())
pxa27x_guess_max_freq();
pxa_cpufreq_init_voltages();
init_sdram_rows();
/* set default policy and cpuinfo */
......
......@@ -16,15 +16,17 @@
#include <linux/mtd/physmap.h>
#include <linux/mtd/partitions.h>
#include <linux/sm501.h>
#include <linux/smsc911x.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/csb726.h>
#include <mach/mfp-pxa27x.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
#include <mach/pxa2xx-regs.h>
#include <mach/audio.h>
#include "generic.h"
#include "devices.h"
......@@ -275,15 +277,26 @@ static struct resource csb726_lan_resources[] = {
{
.start = CSB726_IRQ_LAN,
.end = CSB726_IRQ_LAN,
.flags = IORESOURCE_IRQ,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
},
};
struct smsc911x_platform_config csb726_lan_config = {
.irq_type = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
.irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
.flags = SMSC911X_USE_32BIT,
.phy_interface = PHY_INTERFACE_MODE_MII,
};
static struct platform_device csb726_lan = {
.name = "smc911x",
.name = "smsc911x",
.id = -1,
.num_resources = ARRAY_SIZE(csb726_lan_resources),
.resource = csb726_lan_resources,
.dev = {
.platform_data = &csb726_lan_config,
},
};
static struct platform_device *devices[] __initdata = {
......@@ -303,6 +316,7 @@ static void __init csb726_init(void)
pxa27x_set_i2c_power_info(NULL);
pxa_set_mci_info(&csb726_mci);
pxa_set_ohci_info(&csb726_ohci_platform_data);
pxa_set_ac97_info(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
......
......@@ -8,7 +8,7 @@
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/ohci.h>
#include <mach/pxa27x_keypad.h>
#include <mach/pxa2xx_spi.h>
......@@ -287,7 +287,7 @@ static struct resource pxa3xx_resources_i2c_power[] = {
};
struct platform_device pxa3xx_device_i2c_power = {
.name = "pxa2xx-i2c",
.name = "pxa3xx-pwri2c",
.id = 1,
.resource = pxa3xx_resources_i2c_power,
.num_resources = ARRAY_SIZE(pxa3xx_resources_i2c_power),
......
......@@ -28,6 +28,8 @@
#include <linux/spi/libertas_spi.h>
#include <linux/power_supply.h>
#include <linux/apm-emulation.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
#include <media/soc_camera.h>
......@@ -41,7 +43,7 @@
#include <mach/ohci.h>
#include <mach/mmc.h>
#include <mach/pxa27x_keypad.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/camera.h>
#include <mach/pxa2xx_spi.h>
......@@ -52,23 +54,31 @@
#define GPIO13_MMC_CD (13)
#define GPIO95_MMC_WP (95)
#define GPIO56_NAND_RB (56)
#define GPIO93_CAM_RESET (93)
#define GPIO16_USB_HUB_RESET (16)
/* eXeda specific GPIOs */
#define GPIO114_MMC_CD (114)
#define GPIO20_NAND_RB (20)
#define GPIO38_SD_PWEN (38)
#define GPIO37_WLAN_RST (37)
#define GPIO95_TOUCHPAD_INT (95)
#define GPIO130_CAM_RESET (130)
#define GPIO10_USB_HUB_RESET (10)
/* common GPIOs */
#define GPIO11_NAND_CS (11)
#define GPIO93_CAM_RESET (93)
#define GPIO41_ETHIRQ (41)
#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ)
#define GPIO115_WLAN_PWEN (115)
#define GPIO19_WLAN_STRAP (19)
#define GPIO9_USB_VBUS_EN (9)
static int mmc_cd;
static int nand_rb;
static int dm9000_flags;
static int cam_reset;
static int usb_hub_reset;
static unsigned long common_pin_config[] = {
/* AC'97 */
......@@ -180,7 +190,6 @@ static unsigned long common_pin_config[] = {
/* power controls */
GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */
GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */
GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */
/* NAND controls */
......@@ -192,13 +201,17 @@ static unsigned long common_pin_config[] = {
static unsigned long em_x270_pin_config[] = {
GPIO13_GPIO, /* MMC card detect */
GPIO16_GPIO, /* USB hub reset */
GPIO56_GPIO, /* NAND Ready/Busy */
GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */
GPIO95_GPIO, /* MMC Write protect */
};
static unsigned long exeda_pin_config[] = {
GPIO10_GPIO, /* USB hub reset */
GPIO20_GPIO, /* NAND Ready/Busy */
GPIO38_GPIO | MFP_LPM_DRIVE_LOW, /* SD slot power */
GPIO95_GPIO, /* touchpad IRQ */
GPIO114_GPIO, /* MMC card detect */
};
......@@ -464,18 +477,79 @@ static inline void em_x270_init_nor(void) {}
/* PXA27x OHCI controller setup */
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static struct regulator *em_x270_usb_ldo;
static int em_x270_usb_hub_init(void)
{
int err;
em_x270_usb_ldo = regulator_get(NULL, "vcc usb");
if (IS_ERR(em_x270_usb_ldo))
return PTR_ERR(em_x270_usb_ldo);
err = gpio_request(GPIO9_USB_VBUS_EN, "vbus en");
if (err)
goto err_free_usb_ldo;
err = gpio_request(usb_hub_reset, "hub rst");
if (err)
goto err_free_vbus_gpio;
/* USB Hub power-on and reset */
gpio_direction_output(usb_hub_reset, 0);
regulator_enable(em_x270_usb_ldo);
gpio_set_value(usb_hub_reset, 1);
gpio_set_value(usb_hub_reset, 0);
regulator_disable(em_x270_usb_ldo);
regulator_enable(em_x270_usb_ldo);
gpio_set_value(usb_hub_reset, 1);
/* enable VBUS */
gpio_direction_output(GPIO9_USB_VBUS_EN, 1);
return 0;
err_free_vbus_gpio:
gpio_free(GPIO9_USB_VBUS_EN);
err_free_usb_ldo:
regulator_put(em_x270_usb_ldo);
return err;
}
static int em_x270_ohci_init(struct device *dev)
{
int err;
/* we don't want to entirely disable USB if the HUB init failed */
err = em_x270_usb_hub_init();
if (err)
pr_err("USB Hub initialization failed: %d\n", err);
/* enable port 2 transiever */
UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
return 0;
}
static void em_x270_ohci_exit(struct device *dev)
{
gpio_free(usb_hub_reset);
gpio_free(GPIO9_USB_VBUS_EN);
if (!IS_ERR(em_x270_usb_ldo)) {
if (regulator_is_enabled(em_x270_usb_ldo))
regulator_disable(em_x270_usb_ldo);
regulator_put(em_x270_usb_ldo);
}
}
static struct pxaohci_platform_data em_x270_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
.init = em_x270_ohci_init,
.exit = em_x270_ohci_exit,
};
static void __init em_x270_init_ohci(void)
......@@ -677,26 +751,52 @@ static int em_x270_libertas_setup(struct spi_device *spi)
if (err)
return err;
err = gpio_request(GPIO19_WLAN_STRAP, "WLAN STRAP");
if (err)
goto err_free_pwen;
if (machine_is_exeda()) {
err = gpio_request(GPIO37_WLAN_RST, "WLAN RST");
if (err)
goto err_free_strap;
gpio_direction_output(GPIO37_WLAN_RST, 1);
msleep(100);
}
gpio_direction_output(GPIO19_WLAN_STRAP, 1);
mdelay(100);
msleep(100);
pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_libertas_pin_config));
gpio_direction_output(GPIO115_WLAN_PWEN, 0);
mdelay(100);
msleep(100);
gpio_set_value(GPIO115_WLAN_PWEN, 1);
mdelay(100);
msleep(100);
spi->bits_per_word = 16;
spi_setup(spi);
return 0;
err_free_strap:
gpio_free(GPIO19_WLAN_STRAP);
err_free_pwen:
gpio_free(GPIO115_WLAN_PWEN);
return err;
}
static int em_x270_libertas_teardown(struct spi_device *spi)
{
gpio_set_value(GPIO115_WLAN_PWEN, 0);
gpio_free(GPIO115_WLAN_PWEN);
gpio_free(GPIO19_WLAN_STRAP);
if (machine_is_exeda()) {
gpio_set_value(GPIO37_WLAN_RST, 0);
gpio_free(GPIO37_WLAN_RST);
}
return 0;
}
......@@ -863,26 +963,26 @@ static int em_x270_sensor_init(struct device *dev)
{
int ret;
ret = gpio_request(GPIO93_CAM_RESET, "camera reset");
ret = gpio_request(cam_reset, "camera reset");
if (ret)
return ret;
gpio_direction_output(GPIO93_CAM_RESET, 0);
gpio_direction_output(cam_reset, 0);
em_x270_camera_ldo = regulator_get(NULL, "vcc cam");
if (em_x270_camera_ldo == NULL) {
gpio_free(GPIO93_CAM_RESET);
gpio_free(cam_reset);
return -ENODEV;
}
ret = regulator_enable(em_x270_camera_ldo);
if (ret) {
regulator_put(em_x270_camera_ldo);
gpio_free(GPIO93_CAM_RESET);
gpio_free(cam_reset);
return ret;
}
gpio_set_value(GPIO93_CAM_RESET, 1);
gpio_set_value(cam_reset, 1);
return 0;
}
......@@ -902,7 +1002,7 @@ static int em_x270_sensor_power(struct device *dev, int on)
if (on == is_on)
return 0;
gpio_set_value(GPIO93_CAM_RESET, !on);
gpio_set_value(cam_reset, !on);
if (on)
ret = regulator_enable(em_x270_camera_ldo);
......@@ -912,7 +1012,7 @@ static int em_x270_sensor_power(struct device *dev, int on)
if (ret)
return ret;
gpio_set_value(GPIO93_CAM_RESET, on);
gpio_set_value(cam_reset, on);
return 0;
}
......@@ -929,13 +1029,8 @@ static struct i2c_board_info em_x270_i2c_cam_info[] = {
},
};
static struct i2c_pxa_platform_data em_x270_i2c_info = {
.fast_mode = 1,
};
static void __init em_x270_init_camera(void)
{
pxa_set_i2c_info(&em_x270_i2c_info);
i2c_register_board_info(0, ARRAY_AND_SIZE(em_x270_i2c_cam_info));
pxa_set_camera_info(&em_x270_camera_platform_data);
}
......@@ -985,7 +1080,7 @@ struct led_info em_x270_led_info = {
};
struct power_supply_info em_x270_psy_info = {
.name = "LP555597P6H-FPS",
.name = "battery",
.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
.voltage_max_design = 4200000,
.voltage_min_design = 3000000,
......@@ -1069,6 +1164,29 @@ static void __init em_x270_init_da9030(void)
i2c_register_board_info(1, &em_x270_i2c_pmic_info, 1);
}
static struct pca953x_platform_data exeda_gpio_ext_pdata = {
.gpio_base = 128,
};
static struct i2c_board_info exeda_i2c_info[] = {
{
I2C_BOARD_INFO("pca9555", 0x21),
.platform_data = &exeda_gpio_ext_pdata,
},
};
static struct i2c_pxa_platform_data em_x270_i2c_info = {
.fast_mode = 1,
};
static void __init em_x270_init_i2c(void)
{
pxa_set_i2c_info(&em_x270_i2c_info);
if (machine_is_exeda())
i2c_register_board_info(0, ARRAY_AND_SIZE(exeda_i2c_info));
}
static void __init em_x270_module_init(void)
{
pr_info("%s\n", __func__);
......@@ -1077,6 +1195,8 @@ static void __init em_x270_module_init(void)
mmc_cd = GPIO13_MMC_CD;
nand_rb = GPIO56_NAND_RB;
dm9000_flags = DM9000_PLATF_32BITONLY;
cam_reset = GPIO93_CAM_RESET;
usb_hub_reset = GPIO16_USB_HUB_RESET;
}
static void __init em_x270_exeda_init(void)
......@@ -1087,12 +1207,18 @@ static void __init em_x270_exeda_init(void)
mmc_cd = GPIO114_MMC_CD;
nand_rb = GPIO20_NAND_RB;
dm9000_flags = DM9000_PLATF_16BITONLY;
cam_reset = GPIO130_CAM_RESET;
usb_hub_reset = GPIO10_USB_HUB_RESET;
}
static void __init em_x270_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(common_pin_config));
#ifdef CONFIG_PM
pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP);
#endif
if (machine_is_em_x270())
em_x270_module_init();
else if (machine_is_exeda())
......@@ -1111,8 +1237,9 @@ static void __init em_x270_init(void)
em_x270_init_keypad();
em_x270_init_gpio_keys();
em_x270_init_ac97();
em_x270_init_camera();
em_x270_init_spi();
em_x270_init_i2c();
em_x270_init_camera();
}
MACHINE_START(EM_X270, "Compulab EM-X270")
......
......@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/pwm_backlight.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
......@@ -25,13 +26,19 @@
#include <mach/pxa27x.h>
#include <mach/pxafb.h>
#include <mach/ohci.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/hardware.h>
#include <mach/pxa27x_keypad.h>
#include "devices.h"
#include "generic.h"
#define GPIO12_A780_FLIP_LID 12
#define GPIO15_A1200_FLIP_LID 15
#define GPIO15_A910_FLIP_LID 15
#define GPIO12_E680_LOCK_SWITCH 12
#define GPIO15_E6_LOCK_SWITCH 15
static struct platform_pwm_backlight_data ezx_backlight_data = {
.pwm_id = 0,
.max_brightness = 1023,
......@@ -88,7 +95,7 @@ static struct pxafb_mach_info ezx_fb_info_2 = {
.lcd_conn = LCD_COLOR_TFT_18BPP,
};
static struct platform_device *devices[] __initdata = {
static struct platform_device *ezx_devices[] __initdata = {
&ezx_backlight_device,
};
......@@ -651,6 +658,35 @@ static struct pxa27x_keypad_platform_data e2_keypad_platform_data = {
#endif /* CONFIG_MACH_EZX_E2 */
#ifdef CONFIG_MACH_EZX_A780
/* gpio_keys */
static struct gpio_keys_button a780_buttons[] = {
[0] = {
.code = SW_LID,
.gpio = GPIO12_A780_FLIP_LID,
.active_low = 0,
.desc = "A780 flip lid",
.type = EV_SW,
.wakeup = 1,
},
};
static struct gpio_keys_platform_data a780_gpio_keys_platform_data = {
.buttons = a780_buttons,
.nbuttons = ARRAY_SIZE(a780_buttons),
};
static struct platform_device a780_gpio_keys = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &a780_gpio_keys_platform_data,
},
};
static struct platform_device *a780_devices[] __initdata = {
&a780_gpio_keys,
};
static void __init a780_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
......@@ -663,7 +699,8 @@ static void __init a780_init(void)
pxa_set_keypad_info(&a780_keypad_platform_data);
platform_add_devices(devices, ARRAY_SIZE(devices));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(a780_devices));
}
MACHINE_START(EZX_A780, "Motorola EZX A780")
......@@ -678,10 +715,39 @@ MACHINE_END
#endif
#ifdef CONFIG_MACH_EZX_E680
/* gpio_keys */
static struct gpio_keys_button e680_buttons[] = {
[0] = {
.code = KEY_SCREENLOCK,
.gpio = GPIO12_E680_LOCK_SWITCH,
.active_low = 0,
.desc = "E680 lock switch",
.type = EV_KEY,
.wakeup = 1,
},
};
static struct gpio_keys_platform_data e680_gpio_keys_platform_data = {
.buttons = e680_buttons,
.nbuttons = ARRAY_SIZE(e680_buttons),
};
static struct platform_device e680_gpio_keys = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &e680_gpio_keys_platform_data,
},
};
static struct i2c_board_info __initdata e680_i2c_board_info[] = {
{ I2C_BOARD_INFO("tea5767", 0x81) },
};
static struct platform_device *e680_devices[] __initdata = {
&e680_gpio_keys,
};
static void __init e680_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
......@@ -695,7 +761,8 @@ static void __init e680_init(void)
pxa_set_keypad_info(&e680_keypad_platform_data);
platform_add_devices(devices, ARRAY_SIZE(devices));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(e680_devices));
}
MACHINE_START(EZX_E680, "Motorola EZX E680")
......@@ -710,10 +777,39 @@ MACHINE_END
#endif
#ifdef CONFIG_MACH_EZX_A1200
/* gpio_keys */
static struct gpio_keys_button a1200_buttons[] = {
[0] = {
.code = SW_LID,
.gpio = GPIO15_A1200_FLIP_LID,
.active_low = 0,
.desc = "A1200 flip lid",
.type = EV_SW,
.wakeup = 1,
},
};
static struct gpio_keys_platform_data a1200_gpio_keys_platform_data = {
.buttons = a1200_buttons,
.nbuttons = ARRAY_SIZE(a1200_buttons),
};
static struct platform_device a1200_gpio_keys = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &a1200_gpio_keys_platform_data,
},
};
static struct i2c_board_info __initdata a1200_i2c_board_info[] = {
{ I2C_BOARD_INFO("tea5767", 0x81) },
};
static struct platform_device *a1200_devices[] __initdata = {
&a1200_gpio_keys,
};
static void __init a1200_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
......@@ -727,7 +823,8 @@ static void __init a1200_init(void)
pxa_set_keypad_info(&a1200_keypad_platform_data);
platform_add_devices(devices, ARRAY_SIZE(devices));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(a1200_devices));
}
MACHINE_START(EZX_A1200, "Motorola EZX A1200")
......@@ -742,6 +839,35 @@ MACHINE_END
#endif
#ifdef CONFIG_MACH_EZX_A910
/* gpio_keys */
static struct gpio_keys_button a910_buttons[] = {
[0] = {
.code = SW_LID,
.gpio = GPIO15_A910_FLIP_LID,
.active_low = 0,
.desc = "A910 flip lid",
.type = EV_SW,
.wakeup = 1,
},
};
static struct gpio_keys_platform_data a910_gpio_keys_platform_data = {
.buttons = a910_buttons,
.nbuttons = ARRAY_SIZE(a910_buttons),
};
static struct platform_device a910_gpio_keys = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &a910_gpio_keys_platform_data,
},
};
static struct platform_device *a910_devices[] __initdata = {
&a910_gpio_keys,
};
static void __init a910_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
......@@ -754,7 +880,8 @@ static void __init a910_init(void)
pxa_set_keypad_info(&a910_keypad_platform_data);
platform_add_devices(devices, ARRAY_SIZE(devices));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(a910_devices));
}
MACHINE_START(EZX_A910, "Motorola EZX A910")
......@@ -769,10 +896,39 @@ MACHINE_END
#endif
#ifdef CONFIG_MACH_EZX_E6
/* gpio_keys */
static struct gpio_keys_button e6_buttons[] = {
[0] = {
.code = KEY_SCREENLOCK,
.gpio = GPIO15_E6_LOCK_SWITCH,
.active_low = 0,
.desc = "E6 lock switch",
.type = EV_KEY,
.wakeup = 1,
},
};
static struct gpio_keys_platform_data e6_gpio_keys_platform_data = {
.buttons = e6_buttons,
.nbuttons = ARRAY_SIZE(e6_buttons),
};
static struct platform_device e6_gpio_keys = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &e6_gpio_keys_platform_data,
},
};
static struct i2c_board_info __initdata e6_i2c_board_info[] = {
{ I2C_BOARD_INFO("tea5767", 0x81) },
};
static struct platform_device *e6_devices[] __initdata = {
&e6_gpio_keys,
};
static void __init e6_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
......@@ -786,7 +942,8 @@ static void __init e6_init(void)
pxa_set_keypad_info(&e6_keypad_platform_data);
platform_add_devices(devices, ARRAY_SIZE(devices));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(e6_devices));
}
MACHINE_START(EZX_E6, "Motorola EZX E6")
......@@ -805,6 +962,9 @@ static struct i2c_board_info __initdata e2_i2c_board_info[] = {
{ I2C_BOARD_INFO("tea5767", 0x81) },
};
static struct platform_device *e2_devices[] __initdata = {
};
static void __init e2_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
......@@ -818,7 +978,8 @@ static void __init e2_init(void)
pxa_set_keypad_info(&e2_keypad_platform_data);
platform_add_devices(devices, ARRAY_SIZE(devices));
platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
platform_add_devices(ARRAY_AND_SIZE(e2_devices));
}
MACHINE_START(EZX_E2, "Motorola EZX E2")
......
/*
* Support for HP iPAQ hx4700 PDAs.
*
* Copyright (c) 2008-2009 Philipp Zabel
*
* Based on code:
* Copyright (c) 2004 Hewlett-Packard Company.
* Copyright (c) 2005 SDG Systems, LLC
* Copyright (c) 2006 Anton Vorontsov <cbou@mail.ru>
*
* 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/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/lcd.h>
#include <linux/mfd/htc-egpio.h>
#include <linux/mfd/asic3.h>
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/regulator/bq24022.h>
#include <linux/regulator/machine.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/spi.h>
#include <linux/usb/gpio_vbus.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/pxa27x.h>
#include <mach/hx4700.h>
#include <plat/i2c.h>
#include <mach/irda.h>
#include <mach/pxa2xx_spi.h>
#include <video/w100fb.h>
#include "devices.h"
#include "generic.h"
/* Physical address space information */
#define ATI_W3220_PHYS PXA_CS2_PHYS /* ATI Imageon 3220 Graphics */
#define ASIC3_PHYS PXA_CS3_PHYS
#define ASIC3_SD_PHYS (PXA_CS3_PHYS + 0x02000000)
static unsigned long hx4700_pin_config[] __initdata = {
/* SDRAM and Static Memory I/O Signals */
GPIO20_nSDCS_2,
GPIO21_nSDCS_3,
GPIO15_nCS_1,
GPIO78_nCS_2, /* W3220 */
GPIO79_nCS_3, /* ASIC3 */
GPIO80_nCS_4,
GPIO33_nCS_5, /* EGPIO, WLAN */
/* PC CARD */
GPIO48_nPOE,
GPIO49_nPWE,
GPIO50_nPIOR,
GPIO51_nPIOW,
GPIO54_nPCE_2,
GPIO55_nPREG,
GPIO56_nPWAIT,
GPIO57_nIOIS16,
GPIO85_nPCE_1,
GPIO104_PSKTSEL,
/* I2C */
GPIO117_I2C_SCL,
GPIO118_I2C_SDA,
/* FFUART (RS-232) */
GPIO34_FFUART_RXD,
GPIO35_FFUART_CTS,
GPIO36_FFUART_DCD,
GPIO37_FFUART_DSR,
GPIO38_FFUART_RI,
GPIO39_FFUART_TXD,
GPIO40_FFUART_DTR,
GPIO41_FFUART_RTS,
/* BTUART */
GPIO42_BTUART_RXD,
GPIO43_BTUART_TXD,
GPIO44_BTUART_CTS,
GPIO45_BTUART_RTS,
/* PWM 1 (Backlight) */
GPIO17_PWM1_OUT,
/* I2S */
GPIO28_I2S_BITCLK_OUT,
GPIO29_I2S_SDATA_IN,
GPIO30_I2S_SDATA_OUT,
GPIO31_I2S_SYNC,
GPIO113_I2S_SYSCLK,
/* SSP 1 (NavPoint) */
GPIO23_SSP1_SCLK,
GPIO24_SSP1_SFRM,
GPIO25_SSP1_TXD,
GPIO26_SSP1_RXD,
/* SSP 2 (TSC2046) */
GPIO19_SSP2_SCLK,
GPIO86_SSP2_RXD,
GPIO87_SSP2_TXD,
GPIO88_GPIO,
/* HX4700 specific input GPIOs */
GPIO12_GPIO, /* ASIC3_IRQ */
GPIO13_GPIO, /* W3220_IRQ */
GPIO14_GPIO, /* nWLAN_IRQ */
GPIO10_GPIO, /* GSM_IRQ */
GPIO13_GPIO, /* CPLD_IRQ */
GPIO107_GPIO, /* DS1WM_IRQ */
GPIO108_GPIO, /* GSM_READY */
GPIO58_GPIO, /* TSC2046_nPENIRQ */
GPIO66_GPIO, /* nSDIO_IRQ */
};
#define HX4700_GPIO_IN(num, _desc) \
{ .gpio = (num), .dir = 0, .desc = (_desc) }
#define HX4700_GPIO_OUT(num, _init, _desc) \
{ .gpio = (num), .dir = 1, .init = (_init), .desc = (_desc) }
struct gpio_ress {
unsigned gpio : 8;
unsigned dir : 1;
unsigned init : 1;
char *desc;
};
static int hx4700_gpio_request(struct gpio_ress *gpios, int size)
{
int i, rc = 0;
int gpio;
int dir;
for (i = 0; (!rc) && (i < size); i++) {
gpio = gpios[i].gpio;
dir = gpios[i].dir;
rc = gpio_request(gpio, gpios[i].desc);
if (rc) {
pr_err("Error requesting GPIO %d(%s) : %d\n",
gpio, gpios[i].desc, rc);
continue;
}
if (dir)
gpio_direction_output(gpio, gpios[i].init);
else
gpio_direction_input(gpio);
}
while ((rc) && (--i >= 0))
gpio_free(gpios[i].gpio);
return rc;
}
/*
* IRDA
*/
static void irda_transceiver_mode(struct device *dev, int mode)
{
gpio_set_value(GPIO105_HX4700_nIR_ON, mode & IR_OFF);
}
static struct pxaficp_platform_data ficp_info = {
.transceiver_cap = IR_SIRMODE | IR_OFF,
.transceiver_mode = irda_transceiver_mode,
};
/*
* GPIO Keys
*/
#define INIT_KEY(_code, _gpio, _active_low, _desc) \
{ \
.code = KEY_##_code, \
.gpio = _gpio, \
.active_low = _active_low, \
.desc = _desc, \
.type = EV_KEY, \
.wakeup = 1, \
}
static struct gpio_keys_button gpio_keys_buttons[] = {
INIT_KEY(POWER, GPIO0_HX4700_nKEY_POWER, 1, "Power button"),
INIT_KEY(MAIL, GPIO94_HX4700_KEY_MAIL, 0, "Mail button"),
INIT_KEY(ADDRESSBOOK, GPIO99_HX4700_KEY_CONTACTS,0, "Contacts button"),
INIT_KEY(RECORD, GPIOD6_nKEY_RECORD, 1, "Record button"),
INIT_KEY(CALENDAR, GPIOD1_nKEY_CALENDAR, 1, "Calendar button"),
INIT_KEY(HOMEPAGE, GPIOD3_nKEY_HOME, 1, "Home button"),
};
static struct gpio_keys_platform_data gpio_keys_data = {
.buttons = gpio_keys_buttons,
.nbuttons = ARRAY_SIZE(gpio_keys_buttons),
};
static struct platform_device gpio_keys = {
.name = "gpio-keys",
.dev = {
.platform_data = &gpio_keys_data,
},
.id = -1,
};
/*
* ASIC3
*/
static u16 asic3_gpio_config[] = {
/* ASIC3 GPIO banks A and B along with some of C and D
implement the buffering for the CF slot. */
ASIC3_CONFIG_GPIO(0, 1, 1, 0),
ASIC3_CONFIG_GPIO(1, 1, 1, 0),
ASIC3_CONFIG_GPIO(2, 1, 1, 0),
ASIC3_CONFIG_GPIO(3, 1, 1, 0),
ASIC3_CONFIG_GPIO(4, 1, 1, 0),
ASIC3_CONFIG_GPIO(5, 1, 1, 0),
ASIC3_CONFIG_GPIO(6, 1, 1, 0),
ASIC3_CONFIG_GPIO(7, 1, 1, 0),
ASIC3_CONFIG_GPIO(8, 1, 1, 0),
ASIC3_CONFIG_GPIO(9, 1, 1, 0),
ASIC3_CONFIG_GPIO(10, 1, 1, 0),
ASIC3_CONFIG_GPIO(11, 1, 1, 0),
ASIC3_CONFIG_GPIO(12, 1, 1, 0),
ASIC3_CONFIG_GPIO(13, 1, 1, 0),
ASIC3_CONFIG_GPIO(14, 1, 1, 0),
ASIC3_CONFIG_GPIO(15, 1, 1, 0),
ASIC3_CONFIG_GPIO(16, 1, 1, 0),
ASIC3_CONFIG_GPIO(17, 1, 1, 0),
ASIC3_CONFIG_GPIO(18, 1, 1, 0),
ASIC3_CONFIG_GPIO(19, 1, 1, 0),
ASIC3_CONFIG_GPIO(20, 1, 1, 0),
ASIC3_CONFIG_GPIO(21, 1, 1, 0),
ASIC3_CONFIG_GPIO(22, 1, 1, 0),
ASIC3_CONFIG_GPIO(23, 1, 1, 0),
ASIC3_CONFIG_GPIO(24, 1, 1, 0),
ASIC3_CONFIG_GPIO(25, 1, 1, 0),
ASIC3_CONFIG_GPIO(26, 1, 1, 0),
ASIC3_CONFIG_GPIO(27, 1, 1, 0),
ASIC3_CONFIG_GPIO(28, 1, 1, 0),
ASIC3_CONFIG_GPIO(29, 1, 1, 0),
ASIC3_CONFIG_GPIO(30, 1, 1, 0),
ASIC3_CONFIG_GPIO(31, 1, 1, 0),
/* GPIOC - CF, LEDs, SD */
ASIC3_GPIOC0_LED0, /* red */
ASIC3_GPIOC1_LED1, /* green */
ASIC3_GPIOC2_LED2, /* blue */
ASIC3_GPIOC4_CF_nCD,
ASIC3_GPIOC5_nCIOW,
ASIC3_GPIOC6_nCIOR,
ASIC3_GPIOC7_nPCE_1,
ASIC3_GPIOC8_nPCE_2,
ASIC3_GPIOC9_nPOE,
ASIC3_GPIOC10_nPWE,
ASIC3_GPIOC11_PSKTSEL,
ASIC3_GPIOC12_nPREG,
ASIC3_GPIOC13_nPWAIT,
ASIC3_GPIOC14_nPIOIS16,
ASIC3_GPIOC15_nPIOR,
/* GPIOD: input GPIOs, CF */
ASIC3_GPIOD11_nCIOIS16,
ASIC3_GPIOD12_nCWAIT,
ASIC3_GPIOD15_nPIOW,
};
static struct resource asic3_resources[] = {
/* GPIO part */
[0] = {
.start = ASIC3_PHYS,
.end = ASIC3_PHYS + ASIC3_MAP_SIZE_16BIT - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gpio_to_irq(GPIO12_HX4700_ASIC3_IRQ),
.end = gpio_to_irq(GPIO12_HX4700_ASIC3_IRQ),
.flags = IORESOURCE_IRQ,
},
/* SD part */
[2] = {
.start = ASIC3_SD_PHYS,
.end = ASIC3_SD_PHYS + ASIC3_MAP_SIZE_16BIT - 1,
.flags = IORESOURCE_MEM,
},
[3] = {
.start = gpio_to_irq(GPIO66_HX4700_ASIC3_nSDIO_IRQ),
.end = gpio_to_irq(GPIO66_HX4700_ASIC3_nSDIO_IRQ),
.flags = IORESOURCE_IRQ,
},
};
static struct asic3_platform_data asic3_platform_data = {
.gpio_config = asic3_gpio_config,
.gpio_config_num = ARRAY_SIZE(asic3_gpio_config),
.irq_base = IRQ_BOARD_START,
.gpio_base = HX4700_ASIC3_GPIO_BASE,
};
static struct platform_device asic3 = {
.name = "asic3",
.id = -1,
.resource = asic3_resources,
.num_resources = ARRAY_SIZE(asic3_resources),
.dev = {
.platform_data = &asic3_platform_data,
},
};
/*
* EGPIO
*/
static struct resource egpio_resources[] = {
[0] = {
.start = PXA_CS5_PHYS,
.end = PXA_CS5_PHYS + 0x4 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct htc_egpio_chip egpio_chips[] = {
[0] = {
.reg_start = 0,
.gpio_base = HX4700_EGPIO_BASE,
.num_gpios = 8,
.direction = HTC_EGPIO_OUTPUT,
},
};
static struct htc_egpio_platform_data egpio_info = {
.reg_width = 16,
.bus_width = 16,
.chip = egpio_chips,
.num_chips = ARRAY_SIZE(egpio_chips),
};
static struct platform_device egpio = {
.name = "htc-egpio",
.id = -1,
.resource = egpio_resources,
.num_resources = ARRAY_SIZE(egpio_resources),
.dev = {
.platform_data = &egpio_info,
},
};
/*
* LCD - Sony display connected to ATI Imageon w3220
*/
static int lcd_power;
static void sony_lcd_init(void)
{
gpio_set_value(GPIO84_HX4700_LCD_SQN, 1);
gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 0);
gpio_set_value(GPIO111_HX4700_LCD_AVDD_3V3_ON, 0);
gpio_set_value(GPIO70_HX4700_LCD_SLIN1, 0);
gpio_set_value(GPIO62_HX4700_LCD_nRESET, 0);
mdelay(10);
gpio_set_value(GPIO59_HX4700_LCD_PC1, 0);
gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 0);
mdelay(20);
gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 1);
mdelay(5);
gpio_set_value(GPIO111_HX4700_LCD_AVDD_3V3_ON, 1);
/* FIXME: init w3220 registers here */
mdelay(5);
gpio_set_value(GPIO70_HX4700_LCD_SLIN1, 1);
mdelay(10);
gpio_set_value(GPIO62_HX4700_LCD_nRESET, 1);
mdelay(10);
gpio_set_value(GPIO59_HX4700_LCD_PC1, 1);
mdelay(10);
gpio_set_value(GPIO112_HX4700_LCD_N2V7_7V3_ON, 1);
}
static void sony_lcd_off(void)
{
gpio_set_value(GPIO59_HX4700_LCD_PC1, 0);
gpio_set_value(GPIO62_HX4700_LCD_nRESET, 0);
mdelay(10);
gpio_set_value(GPIO112_HX4700_LCD_N2V7_7V3_ON, 0);
mdelay(10);
gpio_set_value(GPIO111_HX4700_LCD_AVDD_3V3_ON, 0);
mdelay(10);
gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 0);
}
static int hx4700_lcd_set_power(struct lcd_device *ldev, int level)
{
switch (level) {
case FB_BLANK_UNBLANK:
sony_lcd_init();
break;
case FB_BLANK_NORMAL:
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_POWERDOWN:
sony_lcd_off();
break;
}
lcd_power = level;
return 0;
}
static int hx4700_lcd_get_power(struct lcd_device *lm)
{
return lcd_power;
}
static struct lcd_ops hx4700_lcd_ops = {
.get_power = hx4700_lcd_get_power,
.set_power = hx4700_lcd_set_power,
};
static struct lcd_device *hx4700_lcd_device;
#ifdef CONFIG_PM
static void w3220_lcd_suspend(struct w100fb_par *wfb)
{
sony_lcd_off();
}
static void w3220_lcd_resume(struct w100fb_par *wfb)
{
sony_lcd_init();
}
#else
#define w3220_lcd_resume NULL
#define w3220_lcd_suspend NULL
#endif
static struct w100_tg_info w3220_tg_info = {
.suspend = w3220_lcd_suspend,
.resume = w3220_lcd_resume,
};
/* W3220_VGA QVGA */
static struct w100_gen_regs w3220_regs = {
.lcd_format = 0x00000003,
.lcdd_cntl1 = 0x00000000,
.lcdd_cntl2 = 0x0003ffff,
.genlcd_cntl1 = 0x00abf003, /* 0x00fff003 */
.genlcd_cntl2 = 0x00000003,
.genlcd_cntl3 = 0x000102aa,
};
static struct w100_mode w3220_modes[] = {
{
.xres = 480,
.yres = 640,
.left_margin = 15,
.right_margin = 16,
.upper_margin = 8,
.lower_margin = 7,
.crtc_ss = 0x00000000,
.crtc_ls = 0xa1ff01f9, /* 0x21ff01f9 */
.crtc_gs = 0xc0000000, /* 0x40000000 */
.crtc_vpos_gs = 0x0000028f,
.crtc_ps1_active = 0x00000000, /* 0x41060010 */
.crtc_rev = 0,
.crtc_dclk = 0x80000000,
.crtc_gclk = 0x040a0104,
.crtc_goe = 0,
.pll_freq = 95,
.pixclk_divider = 4,
.pixclk_divider_rotated = 4,
.pixclk_src = CLK_SRC_PLL,
.sysclk_divider = 0,
.sysclk_src = CLK_SRC_PLL,
},
{
.xres = 240,
.yres = 320,
.left_margin = 9,
.right_margin = 8,
.upper_margin = 5,
.lower_margin = 4,
.crtc_ss = 0x80150014,
.crtc_ls = 0xa0fb00f7,
.crtc_gs = 0xc0080007,
.crtc_vpos_gs = 0x00080007,
.crtc_rev = 0x0000000a,
.crtc_dclk = 0x81700030,
.crtc_gclk = 0x8015010f,
.crtc_goe = 0x00000000,
.pll_freq = 95,
.pixclk_divider = 4,
.pixclk_divider_rotated = 4,
.pixclk_src = CLK_SRC_PLL,
.sysclk_divider = 0,
.sysclk_src = CLK_SRC_PLL,
},
};
struct w100_mem_info w3220_mem_info = {
.ext_cntl = 0x09640011,
.sdram_mode_reg = 0x00600021,
.ext_timing_cntl = 0x1a001545, /* 0x15001545 */
.io_cntl = 0x7ddd7333,
.size = 0x1fffff,
};
struct w100_bm_mem_info w3220_bm_mem_info = {
.ext_mem_bw = 0x50413e01,
.offset = 0,
.ext_timing_ctl = 0x00043f7f,
.ext_cntl = 0x00000010,
.mode_reg = 0x00250000,
.io_cntl = 0x0fff0000,
.config = 0x08301480,
};
static struct w100_gpio_regs w3220_gpio_info = {
.init_data1 = 0xdfe00100, /* GPIO_DATA */
.gpio_dir1 = 0xffff0000, /* GPIO_CNTL1 */
.gpio_oe1 = 0x00000000, /* GPIO_CNTL2 */
.init_data2 = 0x00000000, /* GPIO_DATA2 */
.gpio_dir2 = 0x00000000, /* GPIO_CNTL3 */
.gpio_oe2 = 0x00000000, /* GPIO_CNTL4 */
};
static struct w100fb_mach_info w3220_info = {
.tg = &w3220_tg_info,
.mem = &w3220_mem_info,
.bm_mem = &w3220_bm_mem_info,
.gpio = &w3220_gpio_info,
.regs = &w3220_regs,
.modelist = w3220_modes,
.num_modes = 2,
.xtal_freq = 16000000,
};
static struct resource w3220_resources[] = {
[0] = {
.start = ATI_W3220_PHYS,
.end = ATI_W3220_PHYS + 0x00ffffff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device w3220 = {
.name = "w100fb",
.id = -1,
.dev = {
.platform_data = &w3220_info,
},
.num_resources = ARRAY_SIZE(w3220_resources),
.resource = w3220_resources,
};
/*
* Backlight
*/
static struct platform_pwm_backlight_data backlight_data = {
.pwm_id = 1,
.max_brightness = 200,
.dft_brightness = 100,
.pwm_period_ns = 30923,
};
static struct platform_device backlight = {
.name = "pwm-backlight",
.id = -1,
.dev = {
.parent = &pxa27x_device_pwm1.dev,
.platform_data = &backlight_data,
},
};
/*
* USB "Transceiver"
*/
static struct gpio_vbus_mach_info gpio_vbus_info = {
.gpio_pullup = GPIO76_HX4700_USBC_PUEN,
.gpio_vbus = GPIOD14_nUSBC_DETECT,
.gpio_vbus_inverted = 1,
};
static struct platform_device gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &gpio_vbus_info,
},
};
/*
* Touchscreen - TSC2046 connected to SSP2
*/
static const struct ads7846_platform_data tsc2046_info = {
.model = 7846,
.vref_delay_usecs = 100,
.pressure_max = 512,
.debounce_max = 10,
.debounce_tol = 3,
.debounce_rep = 1,
.gpio_pendown = GPIO58_HX4700_TSC2046_nPENIRQ,
};
static struct pxa2xx_spi_chip tsc2046_chip = {
.tx_threshold = 1,
.rx_threshold = 2,
.timeout = 64,
.gpio_cs = GPIO88_HX4700_TSC2046_CS,
};
static struct spi_board_info tsc2046_board_info[] __initdata = {
{
.modalias = "ads7846",
.bus_num = 2,
.max_speed_hz = 2600000, /* 100 kHz sample rate */
.irq = gpio_to_irq(GPIO58_HX4700_TSC2046_nPENIRQ),
.platform_data = &tsc2046_info,
.controller_data = &tsc2046_chip,
},
};
static struct pxa2xx_spi_master pxa_ssp2_master_info = {
.num_chipselect = 1,
.clock_enable = CKEN_SSP2,
.enable_dma = 1,
};
/*
* External power
*/
static int power_supply_init(struct device *dev)
{
return gpio_request(GPIOD9_nAC_IN, "AC charger detect");
}
static int hx4700_is_ac_online(void)
{
return !gpio_get_value(GPIOD9_nAC_IN);
}
static void power_supply_exit(struct device *dev)
{
gpio_free(GPIOD9_nAC_IN);
}
static char *hx4700_supplicants[] = {
"ds2760-battery.0", "backup-battery"
};
static struct pda_power_pdata power_supply_info = {
.init = power_supply_init,
.is_ac_online = hx4700_is_ac_online,
.exit = power_supply_exit,
.supplied_to = hx4700_supplicants,
.num_supplicants = ARRAY_SIZE(hx4700_supplicants),
};
static struct resource power_supply_resources[] = {
[0] = {
.name = "ac",
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
IORESOURCE_IRQ_LOWEDGE,
.start = gpio_to_irq(GPIOD9_nAC_IN),
.end = gpio_to_irq(GPIOD9_nAC_IN),
},
[1] = {
.name = "usb",
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
IORESOURCE_IRQ_LOWEDGE,
.start = gpio_to_irq(GPIOD14_nUSBC_DETECT),
.end = gpio_to_irq(GPIOD14_nUSBC_DETECT),
},
};
static struct platform_device power_supply = {
.name = "pda-power",
.id = -1,
.dev = {
.platform_data = &power_supply_info,
},
.resource = power_supply_resources,
.num_resources = ARRAY_SIZE(power_supply_resources),
};
/*
* Battery charger
*/
static struct regulator_consumer_supply bq24022_consumers[] = {
{
.dev = &gpio_vbus.dev,
.supply = "vbus_draw",
},
{
.dev = &power_supply.dev,
.supply = "ac_draw",
},
};
static struct regulator_init_data bq24022_init_data = {
.constraints = {
.max_uA = 500000,
.valid_ops_mask = REGULATOR_CHANGE_CURRENT,
},
.num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
.consumer_supplies = bq24022_consumers,
};
static struct bq24022_mach_info bq24022_info = {
.gpio_nce = GPIO72_HX4700_BQ24022_nCHARGE_EN,
.gpio_iset2 = GPIO96_HX4700_BQ24022_ISET2,
.init_data = &bq24022_init_data,
};
static struct platform_device bq24022 = {
.name = "bq24022",
.id = -1,
.dev = {
.platform_data = &bq24022_info,
},
};
/*
* StrataFlash
*/
static void hx4700_set_vpp(struct map_info *map, int vpp)
{
gpio_set_value(GPIO91_HX4700_FLASH_VPEN, vpp);
}
static struct resource strataflash_resource = {
.start = PXA_CS0_PHYS,
.end = PXA_CS0_PHYS + SZ_128M - 1,
.flags = IORESOURCE_MEM,
};
static struct physmap_flash_data strataflash_data = {
.width = 4,
.set_vpp = hx4700_set_vpp,
};
static struct platform_device strataflash = {
.name = "physmap-flash",
.id = -1,
.resource = &strataflash_resource,
.num_resources = 1,
.dev = {
.platform_data = &strataflash_data,
},
};
/*
* PCMCIA
*/
static struct platform_device pcmcia = {
.name = "hx4700-pcmcia",
.dev = {
.parent = &asic3.dev,
},
};
/*
* Platform devices
*/
static struct platform_device *devices[] __initdata = {
&asic3,
&gpio_keys,
&backlight,
&w3220,
&egpio,
&bq24022,
&gpio_vbus,
&power_supply,
&strataflash,
&pcmcia,
};
static struct gpio_ress global_gpios[] = {
HX4700_GPIO_IN(GPIO12_HX4700_ASIC3_IRQ, "ASIC3_IRQ"),
HX4700_GPIO_IN(GPIO13_HX4700_W3220_IRQ, "W3220_IRQ"),
HX4700_GPIO_IN(GPIO14_HX4700_nWLAN_IRQ, "WLAN_IRQ"),
HX4700_GPIO_OUT(GPIO59_HX4700_LCD_PC1, 1, "LCD_PC1"),
HX4700_GPIO_OUT(GPIO62_HX4700_LCD_nRESET, 1, "LCD_RESET"),
HX4700_GPIO_OUT(GPIO70_HX4700_LCD_SLIN1, 1, "LCD_SLIN1"),
HX4700_GPIO_OUT(GPIO84_HX4700_LCD_SQN, 1, "LCD_SQN"),
HX4700_GPIO_OUT(GPIO110_HX4700_LCD_LVDD_3V3_ON, 1, "LCD_LVDD"),
HX4700_GPIO_OUT(GPIO111_HX4700_LCD_AVDD_3V3_ON, 1, "LCD_AVDD"),
HX4700_GPIO_OUT(GPIO32_HX4700_RS232_ON, 1, "RS232_ON"),
HX4700_GPIO_OUT(GPIO71_HX4700_ASIC3_nRESET, 1, "ASIC3_nRESET"),
HX4700_GPIO_OUT(GPIO82_HX4700_EUART_RESET, 1, "EUART_RESET"),
HX4700_GPIO_OUT(GPIO105_HX4700_nIR_ON, 1, "nIR_EN"),
};
static void __init hx4700_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(hx4700_pin_config));
hx4700_gpio_request(ARRAY_AND_SIZE(global_gpios));
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_ficp_info(&ficp_info);
pxa27x_set_i2c_power_info(NULL);
pxa_set_i2c_info(NULL);
pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info));
hx4700_lcd_device = lcd_device_register("w100fb", NULL,
(void *)&w3220_info, &hx4700_lcd_ops);
gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 0);
mdelay(10);
gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 1);
mdelay(10);
}
MACHINE_START(H4700, "HP iPAQ HX4700")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.init_machine = hx4700_init,
.timer = &pxa_timer,
MACHINE_END
......@@ -22,6 +22,7 @@
#include <linux/spi/spi.h>
#include <linux/i2c.h>
#include <linux/mfd/da903x.h>
#include <linux/sht15.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
......@@ -29,7 +30,7 @@
#include <asm/mach/flash.h>
#include <mach/pxa27x.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/udc.h>
#include <mach/mmc.h>
#include <mach/pxa2xx_spi.h>
......@@ -102,6 +103,10 @@ static unsigned long imote2_pin_config[] __initdata = {
GPIO96_GPIO, /* accelerometer interrupt */
GPIO99_GPIO, /* ADC interrupt */
/* SHT15 */
GPIO100_GPIO,
GPIO98_GPIO,
/* Connector pins specified as gpios */
GPIO94_GPIO, /* large basic connector pin 14 */
GPIO10_GPIO, /* large basic connector pin 23 */
......@@ -112,6 +117,26 @@ static unsigned long imote2_pin_config[] __initdata = {
GPIO105_GPIO, /* blue led */
};
static struct sht15_platform_data platform_data_sht15 = {
.gpio_data = 100,
.gpio_sck = 98,
};
static struct platform_device sht15 = {
.name = "sht15",
.id = -1,
.dev = {
.platform_data = &platform_data_sht15,
},
};
static struct regulator_consumer_supply imote2_sensor_3_con[] = {
{
.dev = &sht15.dev,
.supply = "vcc",
},
};
static struct gpio_led imote2_led_pins[] = {
{
.name = "imote2:red",
......@@ -257,6 +282,8 @@ static struct regulator_init_data imote2_ldo_init_data[] = {
.min_uV = 2800000,
.max_uV = 3000000,
},
.num_consumer_supplies = ARRAY_SIZE(imote2_sensor_3_con),
.consumer_supplies = imote2_sensor_3_con,
},
[vcc_pxa_pll] = { /* 1.17V - 1.43V, default 1.3V*/
.constraints = {
......@@ -432,6 +459,9 @@ static struct i2c_board_info __initdata imote2_i2c_board_info[] = {
.type = "tmp175",
.addr = 0x4A,
.irq = IRQ_GPIO(96),
}, { /* IMB400 Multimedia board */
.type = "wm8940",
.addr = 0x1A,
},
};
......@@ -456,25 +486,12 @@ static struct pxa2xx_spi_master pxa_ssp_master_2_info = {
.num_chipselect = 1,
};
/* Patch posted by Eric Miao <eric.miao@marvell.com> will remove
* the need for these functions.
*/
static void spi1control(u32 command)
{
gpio_set_value(24, command & PXA2XX_CS_ASSERT ? 0 : 1);
};
static void spi3control(u32 command)
{
gpio_set_value(39, command & PXA2XX_CS_ASSERT ? 0 : 1);
};
static struct pxa2xx_spi_chip staccel_chip_info = {
.tx_threshold = 8,
.rx_threshold = 8,
.dma_burst_size = 8,
.timeout = 235,
.cs_control = spi1control,
.gpio_cs = 24,
};
static struct pxa2xx_spi_chip cc2420_info = {
......@@ -482,7 +499,7 @@ static struct pxa2xx_spi_chip cc2420_info = {
.rx_threshold = 8,
.dma_burst_size = 8,
.timeout = 235,
.cs_control = spi3control,
.gpio_cs = 39,
};
static struct spi_board_info spi_board_info[] __initdata = {
......@@ -521,6 +538,7 @@ static struct pxa2xx_udc_mach_info imote2_udc_info __initdata = {
static struct platform_device *imote2_devices[] = {
&imote2_flash_device,
&imote2_leds,
&sht15,
};
static struct i2c_pxa_platform_data i2c_pwr_pdata = {
......@@ -538,8 +556,6 @@ static void __init imote2_init(void)
/* SPI chip select directions - all other directions should
* be handled by drivers.*/
gpio_direction_output(37, 0);
gpio_direction_output(24, 0);
gpio_direction_output(39, 0);
platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
......
/*
* GPIO and IRQ definitions for HP iPAQ hx4700
*
* Copyright (c) 2008 Philipp Zabel
*
* 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 _HX4700_H_
#define _HX4700_H_
#include <linux/gpio.h>
#include <linux/mfd/asic3.h>
#define HX4700_ASIC3_GPIO_BASE NR_BUILTIN_GPIO
#define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS)
/*
* PXA GPIOs
*/
#define GPIO0_HX4700_nKEY_POWER 0
#define GPIO12_HX4700_ASIC3_IRQ 12
#define GPIO13_HX4700_W3220_IRQ 13
#define GPIO14_HX4700_nWLAN_IRQ 14
#define GPIO18_HX4700_RDY 18
#define GPIO22_HX4700_LCD_RL 22
#define GPIO27_HX4700_CODEC_ON 27
#define GPIO32_HX4700_RS232_ON 32
#define GPIO52_HX4700_CPU_nBATT_FAULT 52
#define GPIO58_HX4700_TSC2046_nPENIRQ 58
#define GPIO59_HX4700_LCD_PC1 59
#define GPIO60_HX4700_CF_RNB 60
#define GPIO61_HX4700_W3220_nRESET 61
#define GPIO62_HX4700_LCD_nRESET 62
#define GPIO63_HX4700_CPU_SS_nRESET 63
#define GPIO65_HX4700_TSC2046_PEN_PU 65
#define GPIO66_HX4700_ASIC3_nSDIO_IRQ 66
#define GPIO67_HX4700_EUART_PS 67
#define GPIO70_HX4700_LCD_SLIN1 70
#define GPIO71_HX4700_ASIC3_nRESET 71
#define GPIO72_HX4700_BQ24022_nCHARGE_EN 72
#define GPIO73_HX4700_LCD_UD_1 73
#define GPIO75_HX4700_EARPHONE_nDET 75
#define GPIO76_HX4700_USBC_PUEN 76
#define GPIO81_HX4700_CPU_GP_nRESET 81
#define GPIO82_HX4700_EUART_RESET 82
#define GPIO83_HX4700_WLAN_nRESET 83
#define GPIO84_HX4700_LCD_SQN 84
#define GPIO85_HX4700_nPCE1 85
#define GPIO88_HX4700_TSC2046_CS 88
#define GPIO91_HX4700_FLASH_VPEN 91
#define GPIO92_HX4700_HP_DRIVER 92
#define GPIO93_HX4700_EUART_INT 93
#define GPIO94_HX4700_KEY_MAIL 94
#define GPIO95_HX4700_BATT_OFF 95
#define GPIO96_HX4700_BQ24022_ISET2 96
#define GPIO97_HX4700_nBL_DETECT 97
#define GPIO99_HX4700_KEY_CONTACTS 99
#define GPIO100_HX4700_AUTO_SENSE 100 /* BL auto brightness */
#define GPIO102_HX4700_SYNAPTICS_POWER_ON 102
#define GPIO103_HX4700_SYNAPTICS_INT 103
#define GPIO105_HX4700_nIR_ON 105
#define GPIO106_HX4700_CPU_BT_nRESET 106
#define GPIO107_HX4700_SPK_nSD 107
#define GPIO109_HX4700_CODEC_nPDN 109
#define GPIO110_HX4700_LCD_LVDD_3V3_ON 110
#define GPIO111_HX4700_LCD_AVDD_3V3_ON 111
#define GPIO112_HX4700_LCD_N2V7_7V3_ON 112
#define GPIO114_HX4700_CF_RESET 114
#define GPIO116_HX4700_CPU_HW_nRESET 116
/*
* ASIC3 GPIOs
*/
#define GPIOC_BASE (HX4700_ASIC3_GPIO_BASE + 32)
#define GPIOD_BASE (HX4700_ASIC3_GPIO_BASE + 48)
#define GPIOC0_LED_RED (GPIOC_BASE + 0)
#define GPIOC1_LED_GREEN (GPIOC_BASE + 1)
#define GPIOC2_LED_BLUE (GPIOC_BASE + 2)
#define GPIOC3_nSD_CS (GPIOC_BASE + 3)
#define GPIOC4_CF_nCD (GPIOC_BASE + 4) /* Input */
#define GPIOC5_nCIOW (GPIOC_BASE + 5) /* Output, to CF */
#define GPIOC6_nCIOR (GPIOC_BASE + 6) /* Output, to CF */
#define GPIOC7_nPCE1 (GPIOC_BASE + 7) /* Input, from CPU */
#define GPIOC8_nPCE2 (GPIOC_BASE + 8) /* Input, from CPU */
#define GPIOC9_nPOE (GPIOC_BASE + 9) /* Input, from CPU */
#define GPIOC10_CF_nPWE (GPIOC_BASE + 10) /* Input */
#define GPIOC11_PSKTSEL (GPIOC_BASE + 11) /* Input, from CPU */
#define GPIOC12_nPREG (GPIOC_BASE + 12) /* Input, from CPU */
#define GPIOC13_nPWAIT (GPIOC_BASE + 13) /* Output, to CPU */
#define GPIOC14_nPIOIS16 (GPIOC_BASE + 14) /* Output, to CPU */
#define GPIOC15_nPIOR (GPIOC_BASE + 15) /* Input, from CPU */
#define GPIOD0_CPU_SS_INT (GPIOD_BASE + 0) /* Input */
#define GPIOD1_nKEY_CALENDAR (GPIOD_BASE + 1)
#define GPIOD2_BLUETOOTH_WAKEUP (GPIOD_BASE + 2)
#define GPIOD3_nKEY_HOME (GPIOD_BASE + 3)
#define GPIOD4_CF_nCD (GPIOD_BASE + 4) /* Input, from CF */
#define GPIOD5_nPIO (GPIOD_BASE + 5) /* Input */
#define GPIOD6_nKEY_RECORD (GPIOD_BASE + 6)
#define GPIOD7_nSDIO_DETECT (GPIOD_BASE + 7)
#define GPIOD8_COM_DCD (GPIOD_BASE + 8) /* Input */
#define GPIOD9_nAC_IN (GPIOD_BASE + 9)
#define GPIOD10_nSDIO_IRQ (GPIOD_BASE + 10) /* Input */
#define GPIOD11_nCIOIS16 (GPIOD_BASE + 11) /* Input, from CF */
#define GPIOD12_nCWAIT (GPIOD_BASE + 12) /* Input, from CF */
#define GPIOD13_CF_RNB (GPIOD_BASE + 13) /* Input */
#define GPIOD14_nUSBC_DETECT (GPIOD_BASE + 14)
#define GPIOD15_nPIOW (GPIOD_BASE + 15) /* Input, from CPU */
/*
* EGPIOs
*/
#define EGPIO0_VCC_3V3_EN (HX4700_EGPIO_BASE + 0) /* WLAN support chip */
#define EGPIO1_WL_VREG_EN (HX4700_EGPIO_BASE + 1) /* WLAN power */
#define EGPIO2_VCC_2V1_WL_EN (HX4700_EGPIO_BASE + 2) /* unused */
#define EGPIO3_SS_PWR_ON (HX4700_EGPIO_BASE + 3) /* smart slot power */
#define EGPIO4_CF_3V3_ON (HX4700_EGPIO_BASE + 4) /* CF 3.3V enable */
#define EGPIO5_BT_3V3_ON (HX4700_EGPIO_BASE + 5) /* BT 3.3V enable */
#define EGPIO6_WL1V8_EN (HX4700_EGPIO_BASE + 6) /* WLAN 1.8V enable */
#define EGPIO7_VCC_3V3_WL_EN (HX4700_EGPIO_BASE + 7) /* WLAN 3.3V enable */
#define EGPIO8_USB_3V3_ON (HX4700_EGPIO_BASE + 8) /* unused */
#endif /* _HX4700_H_ */
......@@ -91,13 +91,23 @@
#define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i))
/*
* The next 16 interrupts are for board specific purposes. Since
* The following interrupts are for board specific purposes. Since
* the kernel can only run on one machine at a time, we can re-use
* these. If you need more, increase IRQ_BOARD_END, but keep it
* within sensible limits.
* these. There will be 16 IRQs by default. If it is not enough,
* IRQ_BOARD_END is allowed be customized for each board, but keep
* the numbers within sensible limits and in descending order, so
* when multiple config options are selected, the maximum will be
* used.
*/
#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM)
#if defined(CONFIG_MACH_H4700)
#define IRQ_BOARD_END (IRQ_BOARD_START + 70)
#elif defined(CONFIG_MACH_ZYLONITE)
#define IRQ_BOARD_END (IRQ_BOARD_START + 32)
#else
#define IRQ_BOARD_END (IRQ_BOARD_START + 16)
#endif
#define IRQ_SA1111_START (IRQ_BOARD_END)
#define IRQ_GPAIN0 (IRQ_BOARD_END + 0)
......@@ -188,8 +198,6 @@
#define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1)
#elif defined(CONFIG_PXA_HAVE_BOARD_IRQS)
#define NR_IRQS (IRQ_BOARD_END)
#elif defined(CONFIG_MACH_ZYLONITE)
#define NR_IRQS (IRQ_BOARD_START + 32)
#else
#define NR_IRQS (IRQ_BOARD_START)
#endif
......
......@@ -283,6 +283,9 @@
#define GPIO41_UART1_TXD MFP_CFG_LPM(GPIO41, AF4, FLOAT)
#define GPIO42_UART1_RXD MFP_CFG_LPM(GPIO42, AF4, FLOAT)
#define GPIO42_UART1_TXD MFP_CFG_LPM(GPIO42, AF2, FLOAT)
#define GPIO75_UART1_RXD MFP_CFG_LPM(GPIO75, AF1, FLOAT)
#define GPIO76_UART1_RXD MFP_CFG_LPM(GPIO76, AF3, FLOAT)
#define GPIO76_UART1_TXD MFP_CFG_LPM(GPIO76, AF1, FLOAT)
#define GPIO97_UART1_RXD MFP_CFG_LPM(GPIO97, AF1, FLOAT)
#define GPIO97_UART1_TXD MFP_CFG_LPM(GPIO97, AF6, FLOAT)
#define GPIO98_UART1_RXD MFP_CFG_LPM(GPIO98, AF6, FLOAT)
......@@ -291,6 +294,9 @@
#define GPIO43_UART1_RTS MFP_CFG_LPM(GPIO43, AF4, FLOAT)
#define GPIO48_UART1_CTS MFP_CFG_LPM(GPIO48, AF4, FLOAT)
#define GPIO48_UART1_RTS MFP_CFG_LPM(GPIO48, AF2, FLOAT)
#define GPIO77_UART1_CTS MFP_CFG_LPM(GPIO77, AF1, FLOAT)
#define GPIO82_UART1_RTS MFP_CFG_LPM(GPIO82, AF1, FLOAT)
#define GPIO82_UART1_CTS MFP_CFG_LPM(GPIO82, AF3, FLOAT)
#define GPIO99_UART1_CTS MFP_CFG_LPM(GPIO99, AF1, FLOAT)
#define GPIO99_UART1_RTS MFP_CFG_LPM(GPIO99, AF6, FLOAT)
#define GPIO104_UART1_CTS MFP_CFG_LPM(GPIO104, AF6, FLOAT)
......@@ -299,13 +305,18 @@
#define GPIO45_UART1_DSR MFP_CFG_LPM(GPIO45, AF2, FLOAT)
#define GPIO47_UART1_DTR MFP_CFG_LPM(GPIO47, AF2, FLOAT)
#define GPIO47_UART1_DSR MFP_CFG_LPM(GPIO47, AF4, FLOAT)
#define GPIO79_UART1_DSR MFP_CFG_LPM(GPIO79, AF1, FLOAT)
#define GPIO81_UART1_DTR MFP_CFG_LPM(GPIO81, AF1, FLOAT)
#define GPIO81_UART1_DSR MFP_CFG_LPM(GPIO81, AF3, FLOAT)
#define GPIO101_UART1_DTR MFP_CFG_LPM(GPIO101, AF6, FLOAT)
#define GPIO101_UART1_DSR MFP_CFG_LPM(GPIO101, AF1, FLOAT)
#define GPIO103_UART1_DTR MFP_CFG_LPM(GPIO103, AF1, FLOAT)
#define GPIO103_UART1_DSR MFP_CFG_LPM(GPIO103, AF6, FLOAT)
#define GPIO44_UART1_DCD MFP_CFG_LPM(GPIO44, AF2, FLOAT)
#define GPIO78_UART1_DCD MFP_CFG_LPM(GPIO78, AF1, FLOAT)
#define GPIO100_UART1_DCD MFP_CFG_LPM(GPIO100, AF1, FLOAT)
#define GPIO46_UART1_RI MFP_CFG_LPM(GPIO46, AF2, FLOAT)
#define GPIO80_UART1_RI MFP_CFG_LPM(GPIO80, AF1, FLOAT)
#define GPIO102_UART1_RI MFP_CFG_LPM(GPIO102, AF1, FLOAT)
/* UART2 */
......@@ -438,6 +449,9 @@
#define GPIO2_RDY MFP_CFG(GPIO2, AF1)
#define GPIO5_NPIOR MFP_CFG(GPIO5, AF3)
#define GPIO6_NPIOW MFP_CFG(GPIO6, AF3)
#define GPIO7_NPIOS16 MFP_CFG(GPIO7, AF3)
#define GPIO8_NPWAIT MFP_CFG(GPIO8, AF3)
#define GPIO11_PWM0_OUT MFP_CFG(GPIO11, AF1)
#define GPIO12_PWM1_OUT MFP_CFG(GPIO12, AF1)
......
......@@ -27,6 +27,8 @@ extern void pxa27x_cpu_suspend(unsigned int);
extern void pxa_cpu_resume(void);
extern int pxa_pm_enter(suspend_state_t state);
extern int pxa_pm_prepare(void);
extern void pxa_pm_finish(void);
/* NOTE: this is for PM debugging on Lubbock, it's really a big
* ugly, but let's keep the crap minimum here, instead of direct
......
......@@ -16,4 +16,7 @@
#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */
#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */
#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */
extern int __init pxa27x_set_pwrmode(unsigned int mode);
#endif /* __MACH_PXA27x_H */
......@@ -8,8 +8,8 @@
* published by the Free Software Foundation.
*
*/
#include <linux/interrupt.h>
#ifndef _MACH_SHARPSL_PM
#define _MACH_SHARPSL_PM
struct sharpsl_charger_machinfo {
void (*init)(void);
......@@ -100,7 +100,5 @@ extern struct sharpsl_pm_status sharpsl_pm;
void sharpsl_battery_kick(void);
void sharpsl_pm_led(int val);
irqreturn_t sharpsl_ac_isr(int irq, void *dev_id);
irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id);
irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id);
#endif
......@@ -36,7 +36,8 @@ static inline void flush(void)
static inline void arch_decomp_setup(void)
{
if (machine_is_littleton() || machine_is_intelmote2()
|| machine_is_csb726())
|| machine_is_csb726() || machine_is_stargate2()
|| machine_is_cm_x300())
UART = STUART;
}
......
......@@ -42,14 +42,17 @@
#include <mach/pxa300.h>
#include <mach/pxafb.h>
#include <mach/ssp.h>
#include <mach/mmc.h>
#include <mach/pxa2xx_spi.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/pxa27x_keypad.h>
#include <mach/pxa3xx_nand.h>
#include <mach/littleton.h>
#include "generic.h"
#define GPIO_MMC1_CARD_DETECT mfp_to_gpio(MFP_PIN_GPIO15)
/* Littleton MFP configurations */
static mfp_cfg_t littleton_mfp_cfg[] __initdata = {
/* LCD */
......@@ -98,6 +101,15 @@ static mfp_cfg_t littleton_mfp_cfg[] __initdata = {
GPIO123_KP_MKOUT_2,
GPIO124_KP_MKOUT_3,
GPIO125_KP_MKOUT_4,
/* MMC1 */
GPIO3_MMC1_DAT0,
GPIO4_MMC1_DAT1,
GPIO5_MMC1_DAT2,
GPIO6_MMC1_DAT3,
GPIO7_MMC1_CLK,
GPIO8_MMC1_CMD,
GPIO15_GPIO, /* card detect */
};
static struct resource smc91x_resources[] = {
......@@ -179,15 +191,10 @@ static struct pxa2xx_spi_master littleton_spi_info = {
.num_chipselect = 1,
};
static void littleton_tdo24m_cs(u32 cmd)
{
gpio_set_value(LITTLETON_GPIO_LCD_CS, !(cmd == PXA2XX_CS_ASSERT));
}
static struct pxa2xx_spi_chip littleton_tdo24m_chip = {
.rx_threshold = 1,
.tx_threshold = 1,
.cs_control = littleton_tdo24m_cs,
.gpio_cs = LITTLETON_GPIO_LCD_CS,
};
static struct spi_board_info littleton_spi_devices[] __initdata = {
......@@ -202,16 +209,6 @@ static struct spi_board_info littleton_spi_devices[] __initdata = {
static void __init littleton_init_spi(void)
{
int err;
err = gpio_request(LITTLETON_GPIO_LCD_CS, "LCD_CS");
if (err) {
pr_warning("failed to request GPIO for LCS CS\n");
return;
}
gpio_direction_output(LITTLETON_GPIO_LCD_CS, 1);
pxa2xx_set_spi_info(2, &littleton_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices));
}
......@@ -267,6 +264,56 @@ static void __init littleton_init_keypad(void)
static inline void littleton_init_keypad(void) {}
#endif
#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
static int littleton_mci_init(struct device *dev,
irq_handler_t littleton_detect_int, void *data)
{
int err, gpio_cd = GPIO_MMC1_CARD_DETECT;
err = gpio_request(gpio_cd, "mmc card detect");
if (err)
goto err_request_cd;
gpio_direction_input(gpio_cd);
err = request_irq(gpio_to_irq(gpio_cd), littleton_detect_int,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"mmc card detect", data);
if (err) {
dev_err(dev, "failed to request card detect IRQ\n");
goto err_request_irq;
}
return 0;
err_request_irq:
gpio_free(gpio_cd);
err_request_cd:
return err;
}
static void littleton_mci_exit(struct device *dev, void *data)
{
int gpio_cd = GPIO_MMC1_CARD_DETECT;
free_irq(gpio_to_irq(gpio_cd), data);
gpio_free(gpio_cd);
}
static struct pxamci_platform_data littleton_mci_platform_data = {
.detect_delay = 20,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.init = littleton_mci_init,
.exit = littleton_mci_exit,
};
static void __init littleton_init_mmc(void)
{
pxa_set_mci_info(&littleton_mci_platform_data);
}
#else
static inline void littleton_init_mmc(void) {}
#endif
#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
static struct mtd_partition littleton_nand_partitions[] = {
[0] = {
......@@ -407,6 +454,7 @@ static void __init littleton_init(void)
littleton_init_spi();
littleton_init_i2c();
littleton_init_mmc();
littleton_init_lcd();
littleton_init_keypad();
littleton_init_nand();
......
......@@ -36,7 +36,7 @@
#include <mach/pxa27x.h>
#include <mach/magician.h>
#include <mach/pxafb.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
......@@ -744,6 +744,14 @@ static struct platform_device strataflash = {
},
};
/*
* I2C
*/
static struct i2c_pxa_platform_data i2c_info = {
.fast_mode = 1,
};
/*
* Platform devices
*/
......@@ -771,7 +779,7 @@ static void __init magician_init(void)
pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
platform_add_devices(devices, ARRAY_SIZE(devices));
platform_add_devices(ARRAY_AND_SIZE(devices));
err = gpio_request(GPIO83_MAGICIAN_nIR_EN, "nIR_EN");
if (!err) {
......@@ -779,7 +787,7 @@ static void __init magician_init(void)
pxa_set_ficp_info(&magician_ficp_info);
}
pxa27x_set_i2c_power_info(NULL);
pxa_set_i2c_info(NULL);
pxa_set_i2c_info(&i2c_info);
pxa_set_mci_info(&magician_mci_info);
pxa_set_ohci_info(&magician_ohci_info);
......
......@@ -46,7 +46,7 @@
#include <mach/mainstone.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
......
......@@ -48,7 +48,7 @@
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/pxa27x-udc.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/camera.h>
#include <mach/audio.h>
#include <media/soc_camera.h>
......@@ -798,7 +798,7 @@ static void mioa701_restart(char c, const char *cmd)
arm_machine_restart('s', cmd);
}
struct gpio_ress global_gpios[] = {
static struct gpio_ress global_gpios[] = {
MIO_GPIO_OUT(GPIO9_CHARGE_EN, 1, "Charger enable"),
MIO_GPIO_OUT(GPIO18_POWEROFF, 0, "Power Off"),
MIO_GPIO_OUT(GPIO87_LCD_POWER, 0, "LCD Power")
......
......@@ -532,30 +532,18 @@ static struct pxafb_mach_info palmld_lcd_screen = {
/******************************************************************************
* Power management - standby
******************************************************************************/
#ifdef CONFIG_PM
static u32 *addr __initdata;
static u32 resume[3] __initdata = {
static void __init palmld_pm_init(void)
{
static u32 resume[] = {
0xe3a00101, /* mov r0, #0x40000000 */
0xe380060f, /* orr r0, r0, #0x00f00000 */
0xe590f008, /* ldr pc, [r0, #0x08] */
};
static int __init palmld_pm_init(void)
{
int i;
/* this is where the bootloader jumps */
addr = phys_to_virt(PALMLD_STR_BASE);
};
for (i = 0; i < 3; i++)
addr[i] = resume[i];
return 0;
/* copy the bootloader */
memcpy(phys_to_virt(PALMLD_STR_BASE), resume, sizeof(resume));
}
device_initcall(palmld_pm_init);
#endif
/******************************************************************************
* Machine init
******************************************************************************/
......@@ -595,6 +583,7 @@ static void __init palmld_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config));
palmld_pm_init();
set_pxa_fb_info(&palmld_lcd_screen);
pxa_set_mci_info(&palmld_mci_platform_data);
pxa_set_ac97_info(&palmld_ac97_pdata);
......
......@@ -26,6 +26,7 @@
#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>
......@@ -343,11 +344,18 @@ static struct pxaficp_platform_data palmt5_ficp_platform_data = {
/******************************************************************************
* UDC
******************************************************************************/
static struct pxa2xx_udc_mach_info palmt5_udc_info __initdata = {
static struct gpio_vbus_mach_info palmt5_udc_info = {
.gpio_vbus = GPIO_NR_PALMT5_USB_DETECT_N,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_PALMT5_USB_PULLUP,
.gpio_pullup_inverted = 0,
};
static struct platform_device palmt5_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &palmt5_udc_info,
},
};
/******************************************************************************
......@@ -466,30 +474,18 @@ static struct pxafb_mach_info palmt5_lcd_screen = {
/******************************************************************************
* Power management - standby
******************************************************************************/
#ifdef CONFIG_PM
static u32 *addr __initdata;
static u32 resume[3] __initdata = {
static void __init palmt5_pm_init(void)
{
static u32 resume[] = {
0xe3a00101, /* mov r0, #0x40000000 */
0xe380060f, /* orr r0, r0, #0x00f00000 */
0xe590f008, /* ldr pc, [r0, #0x08] */
};
};
static int __init palmt5_pm_init(void)
{
int i;
/* this is where the bootloader jumps */
addr = phys_to_virt(PALMT5_STR_BASE);
for (i = 0; i < 3; i++)
addr[i] = resume[i];
return 0;
/* copy the bootloader */
memcpy(phys_to_virt(PALMT5_STR_BASE), resume, sizeof(resume));
}
device_initcall(palmt5_pm_init);
#endif
/******************************************************************************
* Machine init
******************************************************************************/
......@@ -500,6 +496,7 @@ static struct platform_device *devices[] __initdata = {
&palmt5_backlight,
&power_supply,
&palmt5_asoc,
&palmt5_gpio_vbus,
};
/* setup udc GPIOs initial state */
......@@ -515,14 +512,15 @@ static void __init palmt5_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
palmt5_pm_init();
set_pxa_fb_info(&palmt5_lcd_screen);
pxa_set_mci_info(&palmt5_mci_platform_data);
palmt5_udc_init();
pxa_set_ac97_info(&palmt5_ac97_pdata);
pxa_set_udc_info(&palmt5_udc_info);
pxa_set_ficp_info(&palmt5_ficp_platform_data);
pxa_set_keypad_info(&palmt5_keypad_platform_data);
wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
......
......@@ -25,6 +25,7 @@
#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>
......@@ -37,6 +38,7 @@
#include <mach/mfp-pxa25x.h>
#include <mach/irda.h>
#include <mach/udc.h>
#include <mach/palmasoc.h>
#include "generic.h"
#include "devices.h"
......@@ -107,6 +109,7 @@ static unsigned long palmte2_pin_config[] __initdata = {
GPIO1_RST, /* reset */
GPIO4_GPIO, /* Hotsync button */
GPIO9_GPIO, /* power detect */
GPIO15_GPIO, /* earphone detect */
GPIO37_GPIO, /* LCD power */
GPIO56_GPIO, /* Backlight power */
};
......@@ -318,11 +321,18 @@ static struct pxaficp_platform_data palmte2_ficp_platform_data = {
/******************************************************************************
* UDC
******************************************************************************/
static struct pxa2xx_udc_mach_info palmte2_udc_info __initdata = {
static struct gpio_vbus_mach_info palmte2_udc_info = {
.gpio_vbus = GPIO_NR_PALMTE2_USB_DETECT_N,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_PALMTE2_USB_PULLUP,
.gpio_pullup_inverted = 0,
};
static struct platform_device palmte2_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &palmte2_udc_info,
},
};
/******************************************************************************
......@@ -394,6 +404,21 @@ static struct wm97xx_batt_info wm97xx_batt_pdata = {
.batt_name = "main-batt",
};
/******************************************************************************
* aSoC audio
******************************************************************************/
static struct palm27x_asoc_info palmte2_asoc_pdata = {
.jack_gpio = GPIO_NR_PALMTE2_EARPHONE_DETECT,
};
static struct platform_device palmte2_asoc = {
.name = "palm27x-asoc",
.id = -1,
.dev = {
.platform_data = &palmte2_asoc_pdata,
},
};
/******************************************************************************
* Framebuffer
******************************************************************************/
......@@ -429,6 +454,8 @@ static struct platform_device *devices[] __initdata = {
#endif
&palmte2_backlight,
&power_supply,
&palmte2_asoc,
&palmte2_gpio_vbus,
};
/* setup udc GPIOs initial state */
......@@ -447,7 +474,6 @@ static void __init palmte2_init(void)
set_pxa_fb_info(&palmte2_lcd_screen);
pxa_set_mci_info(&palmte2_mci_platform_data);
palmte2_udc_init();
pxa_set_udc_info(&palmte2_udc_info);
pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&palmte2_ficp_platform_data);
wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
......
......@@ -27,6 +27,7 @@
#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>
......@@ -359,11 +360,18 @@ static struct pxaficp_platform_data palmtx_ficp_platform_data = {
/******************************************************************************
* UDC
******************************************************************************/
static struct pxa2xx_udc_mach_info palmtx_udc_info __initdata = {
static struct gpio_vbus_mach_info palmtx_udc_info = {
.gpio_vbus = GPIO_NR_PALMTX_USB_DETECT_N,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_PALMTX_USB_PULLUP,
.gpio_pullup_inverted = 0,
};
static struct platform_device palmtx_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &palmtx_udc_info,
},
};
/******************************************************************************
......@@ -483,30 +491,18 @@ static struct pxafb_mach_info palmtx_lcd_screen = {
/******************************************************************************
* Power management - standby
******************************************************************************/
#ifdef CONFIG_PM
static u32 *addr __initdata;
static u32 resume[3] __initdata = {
static void __init palmtx_pm_init(void)
{
static u32 resume[] = {
0xe3a00101, /* mov r0, #0x40000000 */
0xe380060f, /* orr r0, r0, #0x00f00000 */
0xe590f008, /* ldr pc, [r0, #0x08] */
};
};
static int __init palmtx_pm_init(void)
{
int i;
/* this is where the bootloader jumps */
addr = phys_to_virt(PALMTX_STR_BASE);
for (i = 0; i < 3; i++)
addr[i] = resume[i];
return 0;
/* copy the bootloader */
memcpy(phys_to_virt(PALMTX_STR_BASE), resume, sizeof(resume));
}
device_initcall(palmtx_pm_init);
#endif
/******************************************************************************
* Machine init
******************************************************************************/
......@@ -517,6 +513,7 @@ static struct platform_device *devices[] __initdata = {
&palmtx_backlight,
&power_supply,
&palmtx_asoc,
&palmtx_gpio_vbus,
};
static struct map_desc palmtx_io_desc[] __initdata = {
......@@ -548,11 +545,11 @@ static void __init palmtx_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config));
palmtx_pm_init();
set_pxa_fb_info(&palmtx_lcd_screen);
pxa_set_mci_info(&palmtx_mci_platform_data);
palmtx_udc_init();
pxa_set_ac97_info(&palmtx_ac97_pdata);
pxa_set_udc_info(&palmtx_udc_info);
pxa_set_ficp_info(&palmtx_ficp_platform_data);
pxa_set_keypad_info(&palmtx_keypad_platform_data);
wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
......
......@@ -28,7 +28,7 @@
#include <media/soc_camera.h>
#include <asm/gpio.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/camera.h>
#include <asm/mach/map.h>
#include <mach/pxa27x.h>
......
......@@ -79,7 +79,7 @@ static int pxa_pm_valid(suspend_state_t state)
return -EINVAL;
}
static int pxa_pm_prepare(void)
int pxa_pm_prepare(void)
{
int ret = 0;
......@@ -89,7 +89,7 @@ static int pxa_pm_prepare(void)
return ret;
}
static void pxa_pm_finish(void)
void pxa_pm_finish(void)
{
if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->finish)
pxa_cpu_pm_fns->finish();
......
......@@ -39,7 +39,7 @@
#include <mach/pxa25x.h>
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/irda.h>
#include <mach/poodle.h>
#include <mach/pxafb.h>
......@@ -214,13 +214,8 @@ static struct ads7846_platform_data poodle_ads7846_info = {
.gpio_pendown = POODLE_GPIO_TP_INT,
};
static void ads7846_cs(u32 command)
{
gpio_set_value(POODLE_GPIO_TP_CS, !(command == PXA2XX_CS_ASSERT));
}
static struct pxa2xx_spi_chip poodle_ads7846_chip = {
.cs_control = ads7846_cs,
.gpio_cs = POODLE_GPIO_TP_CS,
};
static struct spi_board_info poodle_spi_devices[] = {
......@@ -236,14 +231,6 @@ static struct spi_board_info poodle_spi_devices[] = {
static void __init poodle_init_spi(void)
{
int err;
err = gpio_request(POODLE_GPIO_TP_CS, "ADS7846_CS");
if (err)
return;
gpio_direction_output(POODLE_GPIO_TP_CS, 1);
pxa2xx_set_spi_info(1, &poodle_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
}
......
......@@ -27,7 +27,7 @@
#include <mach/ohci.h>
#include <mach/pm.h>
#include <mach/dma.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include "generic.h"
#include "devices.h"
......@@ -203,6 +203,23 @@ static struct clk_lookup pxa27x_clkregs[] = {
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
/*
* allow platforms to override default PWRMODE setting used for PM_SUSPEND_MEM
*/
static unsigned int pwrmode = PWRMODE_SLEEP;
int __init pxa27x_set_pwrmode(unsigned int mode)
{
switch (mode) {
case PWRMODE_SLEEP:
case PWRMODE_DEEPSLEEP:
pwrmode = mode;
return 0;
}
return -EINVAL;
}
/*
* List of global PXA peripheral registers to preserve.
* More ones like CP and general purpose register values are preserved
......@@ -254,7 +271,7 @@ void pxa27x_cpu_pm_enter(suspend_state_t state)
pxa_cpu_standby();
break;
case PM_SUSPEND_MEM:
pxa27x_cpu_suspend(PWRMODE_SLEEP);
pxa27x_cpu_suspend(pwrmode);
break;
}
}
......
......@@ -30,7 +30,7 @@
#include <mach/pm.h>
#include <mach/dma.h>
#include <mach/ssp.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include "generic.h"
#include "devices.h"
......@@ -552,7 +552,7 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
}
static struct platform_device *devices[] __initdata = {
/* &pxa_device_udc, The UDC driver is PXA25x only */
&pxa27x_device_udc,
&pxa_device_ffuart,
&pxa_device_btuart,
&pxa_device_stuart,
......
......@@ -27,7 +27,7 @@
#include <asm/mach/arch.h>
#include <mach/pxa930.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/pxafb.h>
#include "devices.h"
......
......@@ -7,7 +7,7 @@
*
*/
#include <asm/hardware/sharpsl_pm.h>
#include <mach/sharpsl_pm.h>
/*
* SharpSL SSP Driver
......@@ -44,8 +44,6 @@ void corgi_lcdtg_hw_init(int mode);
extern struct battery_thresh spitz_battery_levels_acin[];
extern struct battery_thresh spitz_battery_levels_noac[];
void sharpsl_pm_pxa_init(void);
void sharpsl_pm_pxa_remove(void);
int sharpsl_pm_pxa_read_max1111(int channel);
......@@ -15,20 +15,69 @@
#undef DEBUG
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/apm-emulation.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/leds.h>
#include <linux/suspend.h>
#include <linux/gpio.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <mach/pm.h>
#include <mach/pxa2xx-regs.h>
#include <mach/pxa2xx-gpio.h>
#include <mach/regs-rtc.h>
#include <mach/sharpsl.h>
#include <mach/sharpsl_pm.h>
#include "sharpsl.h"
/*
* Constants
*/
#define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */
#define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */
#define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */
#define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */
#define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */
#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */
#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */
#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */
#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10 /* 10 msec */
#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */
#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */
#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */
/*
* Prototypes
*/
#ifdef CONFIG_PM
static int sharpsl_off_charge_battery(void);
static int sharpsl_check_battery_voltage(void);
static int sharpsl_fatal_check(void);
#endif
static int sharpsl_check_battery_temp(void);
static int sharpsl_ac_check(void);
static int sharpsl_average_value(int ad);
static void sharpsl_average_clear(void);
static void sharpsl_charge_toggle(struct work_struct *private_);
static void sharpsl_battery_thread(struct work_struct *private_);
/*
* Variables
*/
struct sharpsl_pm_status sharpsl_pm;
static DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle);
static DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread);
DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger);
struct battery_thresh spitz_battery_levels_acin[] = {
{ 213, 100},
{ 212, 98},
......@@ -144,42 +193,789 @@ int sharpsl_pm_pxa_read_max1111(int channel)
#endif
}
void sharpsl_pm_pxa_init(void)
static int get_percentage(int voltage)
{
int i = sharpsl_pm.machinfo->bat_levels - 1;
int bl_status = sharpsl_pm.machinfo->backlight_get_status ? sharpsl_pm.machinfo->backlight_get_status() : 0;
struct battery_thresh *thresh;
if (sharpsl_pm.charge_mode == CHRG_ON)
thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_acin_bl : sharpsl_pm.machinfo->bat_levels_acin;
else
thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_noac_bl : sharpsl_pm.machinfo->bat_levels_noac;
while (i > 0 && (voltage > thresh[i].voltage))
i--;
return thresh[i].percentage;
}
static int get_apm_status(int voltage)
{
int low_thresh, high_thresh;
if (sharpsl_pm.charge_mode == CHRG_ON) {
high_thresh = sharpsl_pm.machinfo->status_high_acin;
low_thresh = sharpsl_pm.machinfo->status_low_acin;
} else {
high_thresh = sharpsl_pm.machinfo->status_high_noac;
low_thresh = sharpsl_pm.machinfo->status_low_noac;
}
if (voltage >= high_thresh)
return APM_BATTERY_STATUS_HIGH;
if (voltage >= low_thresh)
return APM_BATTERY_STATUS_LOW;
return APM_BATTERY_STATUS_CRITICAL;
}
void sharpsl_battery_kick(void)
{
schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
}
EXPORT_SYMBOL(sharpsl_battery_kick);
static void sharpsl_battery_thread(struct work_struct *private_)
{
int voltage, percent, apm_status, i = 0;
if (!sharpsl_pm.machinfo)
return;
sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE);
/* Corgi cannot confirm when battery fully charged so periodically kick! */
if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON)
&& time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL))
schedule_delayed_work(&toggle_charger, 0);
while(1) {
voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
if (voltage > 0) break;
if (i++ > 5) {
voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
break;
}
}
voltage = sharpsl_average_value(voltage);
apm_status = get_apm_status(voltage);
percent = get_percentage(voltage);
/* At low battery voltages, the voltage has a tendency to start
creeping back up so we try to avoid this here */
if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) {
sharpsl_pm.battstat.mainbat_voltage = voltage;
sharpsl_pm.battstat.mainbat_status = apm_status;
sharpsl_pm.battstat.mainbat_percent = percent;
}
dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage,
sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
#ifdef CONFIG_BACKLIGHT_CORGI
/* If battery is low. limit backlight intensity to save power. */
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
(sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
sharpsl_pm.machinfo->backlight_limit(1);
sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
}
} else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
sharpsl_pm.machinfo->backlight_limit(0);
sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
}
#endif
/* Suspend if critical battery level */
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
&& (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
&& !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
dev_err(sharpsl_pm.dev, "Fatal Off\n");
apm_queue_event(APM_CRITICAL_SUSPEND);
}
schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
}
void sharpsl_pm_led(int val)
{
if (val == SHARPSL_LED_ERROR) {
dev_err(sharpsl_pm.dev, "Charging Error!\n");
} else if (val == SHARPSL_LED_ON) {
dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
led_trigger_event(sharpsl_charge_led_trigger, LED_FULL);
} else {
dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
led_trigger_event(sharpsl_charge_led_trigger, LED_OFF);
}
}
static void sharpsl_charge_on(void)
{
dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
sharpsl_pm.full_count = 0;
sharpsl_pm.charge_mode = CHRG_ON;
schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250));
schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500));
}
static void sharpsl_charge_off(void)
{
dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
sharpsl_pm.machinfo->charge(0);
sharpsl_pm_led(SHARPSL_LED_OFF);
sharpsl_pm.charge_mode = CHRG_OFF;
schedule_delayed_work(&sharpsl_bat, 0);
}
static void sharpsl_charge_error(void)
{
sharpsl_pm_led(SHARPSL_LED_ERROR);
sharpsl_pm.machinfo->charge(0);
sharpsl_pm.charge_mode = CHRG_ERROR;
}
static void sharpsl_charge_toggle(struct work_struct *private_)
{
dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
sharpsl_charge_off();
return;
} else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
sharpsl_charge_error();
return;
}
sharpsl_pm_led(SHARPSL_LED_ON);
sharpsl_pm.machinfo->charge(0);
mdelay(SHARPSL_CHARGE_WAIT_TIME);
sharpsl_pm.machinfo->charge(1);
sharpsl_pm.charge_start_time = jiffies;
}
static void sharpsl_ac_timer(unsigned long data)
{
int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
sharpsl_average_clear();
if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
sharpsl_charge_on();
else if (sharpsl_pm.charge_mode == CHRG_ON)
sharpsl_charge_off();
schedule_delayed_work(&sharpsl_bat, 0);
}
static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id)
{
/* Delay the event slightly to debounce */
/* Must be a smaller delay than the chrg_full_isr below */
mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
return IRQ_HANDLED;
}
static void sharpsl_chrg_full_timer(unsigned long data)
{
dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies);
sharpsl_pm.full_count++;
if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
if (sharpsl_pm.charge_mode == CHRG_ON)
sharpsl_charge_off();
} else if (sharpsl_pm.full_count < 2) {
dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
schedule_delayed_work(&toggle_charger, 0);
} else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
schedule_delayed_work(&toggle_charger, 0);
} else {
sharpsl_charge_off();
sharpsl_pm.charge_mode = CHRG_DONE;
dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n");
}
}
/* Charging Finished Interrupt (Not present on Corgi) */
/* Can trigger at the same time as an AC status change so
delay until after that has been processed */
static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id)
{
if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
return IRQ_HANDLED;
/* delay until after any ac interrupt */
mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500));
return IRQ_HANDLED;
}
static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id)
{
int is_fatal = 0;
if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) {
dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
is_fatal = 1;
}
if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL)) {
dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
is_fatal = 1;
}
if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) {
sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
apm_queue_event(APM_CRITICAL_SUSPEND);
}
return IRQ_HANDLED;
}
/*
* Maintain an average of the last 10 readings
*/
#define SHARPSL_CNV_VALUE_NUM 10
static int sharpsl_ad_index;
static void sharpsl_average_clear(void)
{
sharpsl_ad_index = 0;
}
static int sharpsl_average_value(int ad)
{
pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
int i, ad_val = 0;
static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) {
sharpsl_ad_index = 0;
return ad;
}
sharpsl_ad[sharpsl_ad_index] = ad;
sharpsl_ad_index++;
if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
sharpsl_ad[i] = sharpsl_ad[i+1];
sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
}
for (i=0; i < sharpsl_ad_index; i++)
ad_val += sharpsl_ad[i];
return (ad_val / sharpsl_ad_index);
}
/*
* Take an array of 5 integers, remove the maximum and minimum values
* and return the average.
*/
static int get_select_val(int *val)
{
int i, j, k, temp, sum = 0;
/* Find MAX val */
temp = val[0];
j=0;
for (i=1; i<5; i++) {
if (temp < val[i]) {
temp = val[i];
j = i;
}
}
/* Find MIN val */
temp = val[4];
k=4;
for (i=3; i>=0; i--) {
if (temp > val[i]) {
temp = val[i];
k = i;
}
}
for (i=0; i<5; i++)
if (i != j && i != k )
sum += val[i];
dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
return (sum/3);
}
static int sharpsl_check_battery_temp(void)
{
int val, i, buff[5];
/* Check battery temperature */
for (i=0; i<5; i++) {
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
sharpsl_pm.machinfo->measure_temp(1);
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_TEMP);
sharpsl_pm.machinfo->measure_temp(0);
}
val = get_select_val(buff);
dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
if (val > sharpsl_pm.machinfo->charge_on_temp) {
printk(KERN_WARNING "Not charging: temperature out of limits.\n");
return -1;
}
return 0;
}
#ifdef CONFIG_PM
static int sharpsl_check_battery_voltage(void)
{
int val, i, buff[5];
/* disable charge, enable discharge */
sharpsl_pm.machinfo->charge(0);
sharpsl_pm.machinfo->discharge(1);
mdelay(SHARPSL_WAIT_DISCHARGE_ON);
if (sharpsl_pm.machinfo->discharge1)
sharpsl_pm.machinfo->discharge1(1);
/* Check battery voltage */
for (i=0; i<5; i++) {
buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
}
if (sharpsl_pm.machinfo->discharge1)
sharpsl_pm.machinfo->discharge1(0);
sharpsl_pm.machinfo->discharge(0);
val = get_select_val(buff);
dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
if (val < sharpsl_pm.machinfo->charge_on_volt)
return -1;
return 0;
}
#endif
static int sharpsl_ac_check(void)
{
int temp, i, buff[5];
for (i=0; i<5; i++) {
buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT);
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
}
temp = get_select_val(buff);
dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
if ((temp > sharpsl_pm.machinfo->charge_acin_high) || (temp < sharpsl_pm.machinfo->charge_acin_low)) {
dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
return -1;
}
return 0;
}
#ifdef CONFIG_PM
static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
{
sharpsl_pm.flags |= SHARPSL_SUSPENDED;
flush_scheduled_work();
if (sharpsl_pm.charge_mode == CHRG_ON)
sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
else
sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
return 0;
}
static int sharpsl_pm_resume(struct platform_device *pdev)
{
/* Clear the reset source indicators as they break the bootloader upon reboot */
RCSR = 0x0f;
sharpsl_average_clear();
sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;
sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;
return 0;
}
static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
{
dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
/* not charging and AC-IN! */
if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) {
dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
sharpsl_pm.charge_mode = CHRG_OFF;
sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
sharpsl_off_charge_battery();
}
sharpsl_pm.machinfo->presuspend();
PEDR = 0xffffffff; /* clear it */
sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;
if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
RTSR &= RTSR_ALE;
RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
} else if (alarm_enable) {
RTSR &= RTSR_ALE;
RTAR = alarm_time;
dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
} else {
dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
}
pxa_pm_enter(state);
sharpsl_pm.machinfo->postsuspend();
dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
}
static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
{
if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
{
if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
corgi_goto_sleep(alarm_time, alarm_enable, state);
return 1;
}
if(sharpsl_off_charge_battery()) {
dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
corgi_goto_sleep(alarm_time, alarm_enable, state);
return 1;
}
dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
}
if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || (sharpsl_fatal_check() < 0) )
{
dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
corgi_goto_sleep(alarm_time, alarm_enable, state);
return 1;
}
return 0;
}
static int corgi_pxa_pm_enter(suspend_state_t state)
{
unsigned long alarm_time = RTAR;
unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);
dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");
corgi_goto_sleep(alarm_time, alarm_status, state);
while (corgi_enter_suspend(alarm_time,alarm_status,state))
{}
if (sharpsl_pm.machinfo->earlyresume)
sharpsl_pm.machinfo->earlyresume();
dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
return 0;
}
/*
* Check for fatal battery errors
* Fatal returns -1
*/
static int sharpsl_fatal_check(void)
{
int buff[5], temp, i, acin;
dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
/* Check AC-Adapter */
acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
sharpsl_pm.machinfo->charge(0);
udelay(100);
sharpsl_pm.machinfo->discharge(1); /* enable discharge */
mdelay(SHARPSL_WAIT_DISCHARGE_ON);
}
if (sharpsl_pm.machinfo->discharge1)
sharpsl_pm.machinfo->discharge1(1);
/* Check battery : check inserting battery ? */
for (i=0; i<5; i++) {
buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
}
if (sharpsl_pm.machinfo->discharge1)
sharpsl_pm.machinfo->discharge1(0);
if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
udelay(100);
sharpsl_pm.machinfo->charge(1);
sharpsl_pm.machinfo->discharge(0);
}
temp = get_select_val(buff);
dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %ld\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT));
if ((acin && (temp < sharpsl_pm.machinfo->fatal_acin_volt)) ||
(!acin && (temp < sharpsl_pm.machinfo->fatal_noacin_volt)))
return -1;
return 0;
}
static int sharpsl_off_charge_error(void)
{
dev_err(sharpsl_pm.dev, "Offline Charger: Error occurred.\n");
sharpsl_pm.machinfo->charge(0);
sharpsl_pm_led(SHARPSL_LED_ERROR);
sharpsl_pm.charge_mode = CHRG_ERROR;
return 1;
}
/*
* Charging Control while suspended
* Return 1 - go straight to sleep
* Return 0 - sleep or wakeup depending on other factors
*/
static int sharpsl_off_charge_battery(void)
{
int time;
dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);
if (sharpsl_pm.charge_mode == CHRG_OFF) {
dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
/* AC Check */
if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
return sharpsl_off_charge_error();
/* Start Charging */
sharpsl_pm_led(SHARPSL_LED_ON);
sharpsl_pm.machinfo->charge(0);
mdelay(SHARPSL_CHARGE_WAIT_TIME);
sharpsl_pm.machinfo->charge(1);
sharpsl_pm.charge_mode = CHRG_ON;
sharpsl_pm.full_count = 0;
return 1;
} else if (sharpsl_pm.charge_mode != CHRG_ON) {
return 1;
}
if (sharpsl_pm.full_count == 0) {
int time;
dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
return sharpsl_off_charge_error();
sharpsl_pm.machinfo->charge(0);
mdelay(SHARPSL_CHARGE_WAIT_TIME);
sharpsl_pm.machinfo->charge(1);
sharpsl_pm.charge_mode = CHRG_ON;
mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
time = RCNR;
while(1) {
/* Check if any wakeup event had occurred */
if (sharpsl_pm.machinfo->charger_wakeup() != 0)
return 0;
/* Check for timeout */
if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
return 1;
if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occurred. Retrying to check\n");
sharpsl_pm.full_count++;
sharpsl_pm.machinfo->charge(0);
mdelay(SHARPSL_CHARGE_WAIT_TIME);
sharpsl_pm.machinfo->charge(1);
return 1;
}
}
}
dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");
mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
time = RCNR;
while(1) {
/* Check if any wakeup event had occurred */
if (sharpsl_pm.machinfo->charger_wakeup() != 0)
return 0;
/* Check for timeout */
if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {
dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");
sharpsl_pm.full_count = 0;
}
sharpsl_pm.full_count++;
return 1;
}
if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
sharpsl_pm_led(SHARPSL_LED_OFF);
sharpsl_pm.machinfo->charge(0);
sharpsl_pm.charge_mode = CHRG_DONE;
return 1;
}
}
}
#else
#define sharpsl_pm_suspend NULL
#define sharpsl_pm_resume NULL
#endif
static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
}
static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
}
static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
extern void (*apm_get_power_status)(struct apm_power_info *);
static void sharpsl_apm_get_power_status(struct apm_power_info *info)
{
info->ac_line_status = sharpsl_pm.battstat.ac_status;
if (sharpsl_pm.charge_mode == CHRG_ON)
info->battery_status = APM_BATTERY_STATUS_CHARGING;
else
info->battery_status = sharpsl_pm.battstat.mainbat_status;
info->battery_flag = (1 << info->battery_status);
info->battery_life = sharpsl_pm.battstat.mainbat_percent;
}
#ifdef CONFIG_PM
static struct platform_suspend_ops sharpsl_pm_ops = {
.prepare = pxa_pm_prepare,
.finish = pxa_pm_finish,
.enter = corgi_pxa_pm_enter,
.valid = suspend_valid_only_mem,
};
#endif
static int __init sharpsl_pm_probe(struct platform_device *pdev)
{
int ret;
if (!pdev->dev.platform_data)
return -EINVAL;
sharpsl_pm.dev = &pdev->dev;
sharpsl_pm.machinfo = pdev->dev.platform_data;
sharpsl_pm.charge_mode = CHRG_OFF;
sharpsl_pm.flags = 0;
init_timer(&sharpsl_pm.ac_timer);
sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
init_timer(&sharpsl_pm.chrg_full_timer);
sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger);
sharpsl_pm.machinfo->init();
gpio_request(sharpsl_pm.machinfo->gpio_acin, "AC IN");
gpio_direction_input(sharpsl_pm.machinfo->gpio_acin);
gpio_request(sharpsl_pm.machinfo->gpio_batfull, "Battery Full");
gpio_direction_input(sharpsl_pm.machinfo->gpio_batfull);
gpio_request(sharpsl_pm.machinfo->gpio_batlock, "Battery Lock");
gpio_direction_input(sharpsl_pm.machinfo->gpio_batlock);
/* Register interrupt handlers */
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED, "AC Input Detect", sharpsl_ac_isr)) {
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) {
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
}
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQ_TYPE_EDGE_BOTH);
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED, "Battery Cover", sharpsl_fatal_isr)) {
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) {
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
}
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQ_TYPE_EDGE_FALLING);
if (sharpsl_pm.machinfo->gpio_fatal) {
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED, "Fatal Battery", sharpsl_fatal_isr)) {
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) {
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
}
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQ_TYPE_EDGE_FALLING);
}
if (sharpsl_pm.machinfo->batfull_irq)
{
/* Register interrupt handler. */
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED, "CO", sharpsl_chrg_full_isr)) {
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) {
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
}
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQ_TYPE_EDGE_RISING);
}
ret = device_create_file(&pdev->dev, &dev_attr_battery_percentage);
ret |= device_create_file(&pdev->dev, &dev_attr_battery_voltage);
if (ret != 0)
dev_warn(&pdev->dev, "Failed to register attributes (%d)\n", ret);
apm_get_power_status = sharpsl_apm_get_power_status;
#ifdef CONFIG_PM
suspend_set_ops(&sharpsl_pm_ops);
#endif
mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
return 0;
}
void sharpsl_pm_pxa_remove(void)
static int sharpsl_pm_remove(struct platform_device *pdev)
{
suspend_set_ops(NULL);
device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
led_trigger_unregister_simple(sharpsl_charge_led_trigger);
free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
......@@ -188,4 +984,39 @@ void sharpsl_pm_pxa_remove(void)
if (sharpsl_pm.machinfo->batfull_irq)
free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
gpio_free(sharpsl_pm.machinfo->gpio_batlock);
gpio_free(sharpsl_pm.machinfo->gpio_batfull);
gpio_free(sharpsl_pm.machinfo->gpio_acin);
if (sharpsl_pm.machinfo->exit)
sharpsl_pm.machinfo->exit();
del_timer_sync(&sharpsl_pm.chrg_full_timer);
del_timer_sync(&sharpsl_pm.ac_timer);
return 0;
}
static struct platform_driver sharpsl_pm_driver = {
.probe = sharpsl_pm_probe,
.remove = sharpsl_pm_remove,
.suspend = sharpsl_pm_suspend,
.resume = sharpsl_pm_resume,
.driver = {
.name = "sharpsl-pm",
},
};
static int __devinit sharpsl_pm_init(void)
{
return platform_driver_register(&sharpsl_pm_driver);
}
static void sharpsl_pm_exit(void)
{
platform_driver_unregister(&sharpsl_pm_driver);
}
late_initcall(sharpsl_pm_init);
module_exit(sharpsl_pm_exit);
......@@ -13,19 +13,11 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/mmc/host.h>
#include <linux/mtd/physmap.h>
#include <linux/pm.h>
#include <linux/backlight.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
#include <linux/spi/spi.h>
......@@ -34,31 +26,22 @@
#include <linux/mtd/sharpsl.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/sharpsl_param.h>
#include <asm/hardware/scoop.h>
#include <mach/pxa27x.h>
#include <mach/pxa27x-udc.h>
#include <mach/reset.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/irda.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
#include <mach/udc.h>
#include <mach/pxafb.h>
#include <mach/pxa2xx_spi.h>
#include <mach/spitz.h>
#include <mach/sharpsl.h>
#include <asm/mach/sharpsl_param.h>
#include <asm/hardware/scoop.h>
#include "generic.h"
#include "devices.h"
......@@ -317,13 +300,8 @@ static struct ads7846_platform_data spitz_ads7846_info = {
.wait_for_sync = spitz_wait_for_hsync,
};
static void spitz_ads7846_cs(u32 command)
{
gpio_set_value(SPITZ_GPIO_ADS7846_CS, !(command == PXA2XX_CS_ASSERT));
}
static struct pxa2xx_spi_chip spitz_ads7846_chip = {
.cs_control = spitz_ads7846_cs,
.gpio_cs = SPITZ_GPIO_ADS7846_CS,
};
static void spitz_bl_kick_battery(void)
......@@ -347,22 +325,12 @@ static struct corgi_lcd_platform_data spitz_lcdcon_info = {
.kick_battery = spitz_bl_kick_battery,
};
static void spitz_lcdcon_cs(u32 command)
{
gpio_set_value(SPITZ_GPIO_LCDCON_CS, !(command == PXA2XX_CS_ASSERT));
}
static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
.cs_control = spitz_lcdcon_cs,
.gpio_cs = SPITZ_GPIO_LCDCON_CS,
};
static void spitz_max1111_cs(u32 command)
{
gpio_set_value(SPITZ_GPIO_MAX1111_CS, !(command == PXA2XX_CS_ASSERT));
}
static struct pxa2xx_spi_chip spitz_max1111_chip = {
.cs_control = spitz_max1111_cs,
.gpio_cs = SPITZ_GPIO_MAX1111_CS,
};
static struct spi_board_info spitz_spi_devices[] = {
......@@ -392,30 +360,6 @@ static struct spi_board_info spitz_spi_devices[] = {
static void __init spitz_init_spi(void)
{
int err;
err = gpio_request(SPITZ_GPIO_ADS7846_CS, "ADS7846_CS");
if (err)
return;
err = gpio_request(SPITZ_GPIO_LCDCON_CS, "LCDCON_CS");
if (err)
goto err_free_1;
err = gpio_request(SPITZ_GPIO_MAX1111_CS, "MAX1111_CS");
if (err)
goto err_free_2;
err = gpio_direction_output(SPITZ_GPIO_ADS7846_CS, 1);
if (err)
goto err_free_3;
err = gpio_direction_output(SPITZ_GPIO_LCDCON_CS, 1);
if (err)
goto err_free_3;
err = gpio_direction_output(SPITZ_GPIO_MAX1111_CS, 1);
if (err)
goto err_free_3;
if (machine_is_akita()) {
spitz_lcdcon_info.gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT;
spitz_lcdcon_info.gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON;
......@@ -423,14 +367,6 @@ static void __init spitz_init_spi(void)
pxa2xx_set_spi_info(2, &spitz_spi_info);
spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
return;
err_free_3:
gpio_free(SPITZ_GPIO_MAX1111_CS);
err_free_2:
gpio_free(SPITZ_GPIO_LCDCON_CS);
err_free_1:
gpio_free(SPITZ_GPIO_ADS7846_CS);
}
#else
static inline void spitz_init_spi(void) {}
......
......@@ -41,7 +41,6 @@ static void spitz_charger_init(void)
{
pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN);
pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
sharpsl_pm_pxa_init();
}
static void spitz_measure_temp(int on)
......@@ -182,7 +181,7 @@ unsigned long spitzpm_read_devdata(int type)
struct sharpsl_charger_machinfo spitz_pm_machinfo = {
.init = spitz_charger_init,
.exit = sharpsl_pm_pxa_remove,
.exit = NULL,
.gpio_batlock = SPITZ_GPIO_BAT_COVER,
.gpio_acin = SPITZ_GPIO_AC_IN,
.gpio_batfull = SPITZ_GPIO_CHRG_FULL,
......
/*
* linux/arch/arm/mach-pxa/stargate2.c
*
* Author: Ed C. Epp
* Created: Nov 05, 2002
* Copyright: Intel Corp.
*
* Modified 2009: Jonathan Cameron <jic23@cam.ac.uk>
*
* 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/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/regulator/machine.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/plat-ram.h>
#include <linux/mtd/partitions.h>
#include <linux/i2c/pcf857x.h>
#include <linux/i2c/at24.h>
#include <linux/smc91x.h>
#include <linux/gpio.h>
#include <asm/types.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
#include <mach/pxa27x.h>
#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/pxa2xx_spi.h>
#include <mach/pxa27x-udc.h>
#include <linux/spi/spi.h>
#include <linux/mfd/da903x.h>
#include <linux/sht15.h>
#include "devices.h"
#include "generic.h"
/* Bluetooth */
#define SG2_BT_RESET 81
/* SD */
#define SG2_GPIO_nSD_DETECT 90
#define SG2_SD_POWER_ENABLE 89
static unsigned long stargate2_pin_config[] __initdata = {
GPIO15_nCS_1, /* SRAM */
/* SMC91x */
GPIO80_nCS_4,
GPIO40_GPIO, /*cable detect?*/
/* Device Identification for wakeup*/
GPIO102_GPIO,
/* Button */
GPIO91_GPIO | WAKEUP_ON_LEVEL_HIGH,
/* DA9030 */
GPIO1_GPIO,
/* Compact Flash */
GPIO79_PSKTSEL,
GPIO48_nPOE,
GPIO49_nPWE,
GPIO50_nPIOR,
GPIO51_nPIOW,
GPIO85_nPCE_1,
GPIO54_nPCE_2,
GPIO55_nPREG,
GPIO56_nPWAIT,
GPIO57_nIOIS16,
GPIO120_GPIO, /* Buff ctrl */
GPIO108_GPIO, /* Power ctrl */
GPIO82_GPIO, /* Reset */
GPIO53_GPIO, /* SG2_S0_GPIO_DETECT */
/* MMC */
GPIO32_MMC_CLK,
GPIO112_MMC_CMD,
GPIO92_MMC_DAT_0,
GPIO109_MMC_DAT_1,
GPIO110_MMC_DAT_2,
GPIO111_MMC_DAT_3,
GPIO90_GPIO, /* nSD detect */
GPIO89_GPIO, /* SD_POWER_ENABLE */
/* Bluetooth */
GPIO81_GPIO, /* reset */
/* cc2420 802.15.4 radio */
GPIO22_GPIO, /* CC_RSTN (out)*/
GPIO114_GPIO, /* CC_FIFO (in) */
GPIO116_GPIO, /* CC_CCA (in) */
GPIO0_GPIO, /* CC_FIFOP (in) */
GPIO16_GPIO, /* CCSFD (in) */
GPIO39_GPIO, /* CSn (out) */
/* I2C */
GPIO117_I2C_SCL,
GPIO118_I2C_SDA,
/* SSP 3 - 802.15.4 radio */
GPIO39_GPIO, /* chip select */
GPIO34_SSP3_SCLK,
GPIO35_SSP3_TXD,
GPIO41_SSP3_RXD,
/* SSP 2 */
GPIO11_SSP2_RXD,
GPIO38_SSP2_TXD,
GPIO36_SSP2_SCLK,
GPIO37_GPIO, /* chip select */
/* SSP 1 */
GPIO26_SSP1_RXD,
GPIO25_SSP1_TXD,
GPIO23_SSP1_SCLK,
GPIO24_GPIO, /* chip select */
/* BTUART */
GPIO42_BTUART_RXD,
GPIO43_BTUART_TXD,
GPIO44_BTUART_CTS,
GPIO45_BTUART_RTS,
/* STUART */
GPIO46_STUART_RXD,
GPIO47_STUART_TXD,
/* Basic sensor board */
GPIO96_GPIO, /* accelerometer interrupt */
GPIO99_GPIO, /* ADC interrupt */
/* Connector pins specified as gpios */
GPIO94_GPIO, /* large basic connector pin 14 */
GPIO10_GPIO, /* large basic connector pin 23 */
/* SHT15 */
GPIO100_GPIO,
GPIO98_GPIO,
};
/**
* stargate2_reset_bluetooth() reset the bluecore to ensure consistent state
**/
static int stargate2_reset_bluetooth(void)
{
int err;
err = gpio_request(SG2_BT_RESET, "SG2_BT_RESET");
if (err) {
printk(KERN_ERR "Could not get gpio for bluetooth reset \n");
return err;
}
gpio_direction_output(SG2_BT_RESET, 1);
mdelay(5);
/* now reset it - 5 msec minimum */
gpio_set_value(SG2_BT_RESET, 0);
mdelay(10);
gpio_set_value(SG2_BT_RESET, 1);
gpio_free(SG2_BT_RESET);
return 0;
}
static struct led_info stargate2_leds[] = {
{
.name = "sg2:red",
.flags = DA9030_LED_RATE_ON,
}, {
.name = "sg2:blue",
.flags = DA9030_LED_RATE_ON,
}, {
.name = "sg2:green",
.flags = DA9030_LED_RATE_ON,
},
};
static struct sht15_platform_data platform_data_sht15 = {
.gpio_data = 100,
.gpio_sck = 98,
};
static struct platform_device sht15 = {
.name = "sht15",
.id = -1,
.dev = {
.platform_data = &platform_data_sht15,
},
};
static struct regulator_consumer_supply stargate2_sensor_3_con[] = {
{
.dev = &sht15.dev,
.supply = "vcc",
},
};
enum stargate2_ldos{
vcc_vref,
vcc_cc2420,
/* a mote connector? */
vcc_mica,
/* the CSR bluecore chip */
vcc_bt,
/* The two voltages available to sensor boards */
vcc_sensor_1_8,
vcc_sensor_3,
/* directly connected to the pxa27x */
vcc_sram_ext,
vcc_pxa_pll,
vcc_pxa_usim, /* Reference voltage for certain gpios */
vcc_pxa_mem,
vcc_pxa_flash,
vcc_pxa_core, /*Dc-Dc buck not yet supported */
vcc_lcd,
vcc_bb,
vcc_bbio, /*not sure!*/
vcc_io, /* cc2420 802.15.4 radio and pxa vcc_io ?*/
};
/* The values of the various regulator constraints are obviously dependent
* on exactly what is wired to each ldo. Unfortunately this information is
* not generally available. More information has been requested from Xbow.
*/
static struct regulator_init_data stargate2_ldo_init_data[] = {
[vcc_bbio] = {
.constraints = { /* board default 1.8V */
.name = "vcc_bbio",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
[vcc_bb] = {
.constraints = { /* board default 2.8V */
.name = "vcc_bb",
.min_uV = 2700000,
.max_uV = 3000000,
},
},
[vcc_pxa_flash] = {
.constraints = {/* default is 1.8V */
.name = "vcc_pxa_flash",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
[vcc_cc2420] = { /* also vcc_io */
.constraints = {
/* board default is 2.8V */
.name = "vcc_cc2420",
.min_uV = 2700000,
.max_uV = 3300000,
},
},
[vcc_vref] = { /* Reference for what? */
.constraints = { /* default 1.8V */
.name = "vcc_vref",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
[vcc_sram_ext] = {
.constraints = { /* default 2.8V */
.name = "vcc_sram_ext",
.min_uV = 2800000,
.max_uV = 2800000,
},
},
[vcc_mica] = {
.constraints = { /* default 2.8V */
.name = "vcc_mica",
.min_uV = 2800000,
.max_uV = 2800000,
},
},
[vcc_bt] = {
.constraints = { /* default 2.8V */
.name = "vcc_bt",
.min_uV = 2800000,
.max_uV = 2800000,
},
},
[vcc_lcd] = {
.constraints = { /* default 2.8V */
.name = "vcc_lcd",
.min_uV = 2700000,
.max_uV = 3300000,
},
},
[vcc_io] = { /* Same or higher than everything
* bar vccbat and vccusb */
.constraints = { /* default 2.8V */
.name = "vcc_io",
.min_uV = 2692000,
.max_uV = 3300000,
},
},
[vcc_sensor_1_8] = {
.constraints = { /* default 1.8V */
.name = "vcc_sensor_1_8",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
[vcc_sensor_3] = { /* curiously default 2.8V */
.constraints = {
.name = "vcc_sensor_3",
.min_uV = 2800000,
.max_uV = 3000000,
},
.num_consumer_supplies = ARRAY_SIZE(stargate2_sensor_3_con),
.consumer_supplies = stargate2_sensor_3_con,
},
[vcc_pxa_pll] = { /* 1.17V - 1.43V, default 1.3V*/
.constraints = {
.name = "vcc_pxa_pll",
.min_uV = 1170000,
.max_uV = 1430000,
},
},
[vcc_pxa_usim] = {
.constraints = { /* default 1.8V */
.name = "vcc_pxa_usim",
.min_uV = 1710000,
.max_uV = 2160000,
},
},
[vcc_pxa_mem] = {
.constraints = { /* default 1.8V */
.name = "vcc_pxa_mem",
.min_uV = 1800000,
.max_uV = 1800000,
},
},
};
static struct da903x_subdev_info stargate2_da9030_subdevs[] = {
{
.name = "da903x-led",
.id = DA9030_ID_LED_2,
.platform_data = &stargate2_leds[0],
}, {
.name = "da903x-led",
.id = DA9030_ID_LED_3,
.platform_data = &stargate2_leds[2],
}, {
.name = "da903x-led",
.id = DA9030_ID_LED_4,
.platform_data = &stargate2_leds[1],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO2,
.platform_data = &stargate2_ldo_init_data[vcc_bbio],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO3,
.platform_data = &stargate2_ldo_init_data[vcc_bb],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO4,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_flash],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO5,
.platform_data = &stargate2_ldo_init_data[vcc_cc2420],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO6,
.platform_data = &stargate2_ldo_init_data[vcc_vref],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO7,
.platform_data = &stargate2_ldo_init_data[vcc_sram_ext],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO8,
.platform_data = &stargate2_ldo_init_data[vcc_mica],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO9,
.platform_data = &stargate2_ldo_init_data[vcc_bt],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO10,
.platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO11,
.platform_data = &stargate2_ldo_init_data[vcc_sensor_3],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO12,
.platform_data = &stargate2_ldo_init_data[vcc_lcd],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO15,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_pll],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO17,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_usim],
}, {
.name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */
.id = DA9030_ID_LDO18,
.platform_data = &stargate2_ldo_init_data[vcc_io],
}, {
.name = "da903x-regulator",
.id = DA9030_ID_LDO19,
.platform_data = &stargate2_ldo_init_data[vcc_pxa_mem],
},
};
static struct da903x_platform_data stargate2_da9030_pdata = {
.num_subdevs = ARRAY_SIZE(stargate2_da9030_subdevs),
.subdevs = stargate2_da9030_subdevs,
};
static struct resource smc91x_resources[] = {
[0] = {
.name = "smc91x-regs",
.start = (PXA_CS4_PHYS + 0x300),
.end = (PXA_CS4_PHYS + 0xfffff),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_GPIO(40),
.end = IRQ_GPIO(40),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
}
};
static struct smc91x_platdata stargate2_smc91x_info = {
.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT
| SMC91X_NOWAIT | SMC91X_USE_DMA,
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
.dev = {
.platform_data = &stargate2_smc91x_info,
},
};
static struct pxamci_platform_data stargate2_mci_platform_data;
/*
* The card detect interrupt isn't debounced so we delay it by 250ms
* to give the card a chance to fully insert / eject.
*/
static int stargate2_mci_init(struct device *dev,
irq_handler_t stargate2_detect_int,
void *data)
{
int err;
err = gpio_request(SG2_SD_POWER_ENABLE, "SG2_sd_power_enable");
if (err) {
printk(KERN_ERR "Can't get the gpio for SD power control");
goto return_err;
}
gpio_direction_output(SG2_SD_POWER_ENABLE, 0);
err = gpio_request(SG2_GPIO_nSD_DETECT, "SG2_sd_detect");
if (err) {
printk(KERN_ERR "Can't get the sd detect gpio");
goto free_power_en;
}
gpio_direction_input(SG2_GPIO_nSD_DETECT);
/* Delay to allow for full insertion */
stargate2_mci_platform_data.detect_delay = msecs_to_jiffies(250);
err = request_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT),
stargate2_detect_int,
IRQ_TYPE_EDGE_BOTH,
"MMC card detect",
data);
if (err) {
printk(KERN_ERR "can't request MMC card detect IRQ\n");
goto free_nsd_detect;
}
return 0;
free_nsd_detect:
gpio_free(SG2_GPIO_nSD_DETECT);
free_power_en:
gpio_free(SG2_SD_POWER_ENABLE);
return_err:
return err;
}
/**
* stargate2_mci_setpower() - set state of mmc power supply
*
* Very simple control. Either it is on or off and is controlled by
* a gpio pin */
static void stargate2_mci_setpower(struct device *dev, unsigned int vdd)
{
gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd);
}
static void stargate2_mci_exit(struct device *dev, void *data)
{
free_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT), data);
gpio_free(SG2_SD_POWER_ENABLE);
gpio_free(SG2_GPIO_nSD_DETECT);
}
static struct pxamci_platform_data stargate2_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.init = stargate2_mci_init,
.setpower = stargate2_mci_setpower,
.exit = stargate2_mci_exit,
};
static struct mtd_partition stargate2flash_partitions[] = {
{
.name = "Bootloader",
.size = 0x00040000,
.offset = 0,
.mask_flags = 0,
}, {
.name = "Kernel",
.size = 0x00200000,
.offset = 0x00040000,
.mask_flags = 0
}, {
.name = "Filesystem",
.size = 0x01DC0000,
.offset = 0x00240000,
.mask_flags = 0
},
};
static struct resource flash_resources = {
.start = PXA_CS0_PHYS,
.end = PXA_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
};
static struct flash_platform_data stargate2_flash_data = {
.map_name = "cfi_probe",
.parts = stargate2flash_partitions,
.nr_parts = ARRAY_SIZE(stargate2flash_partitions),
.name = "PXA27xOnChipROM",
.width = 2,
};
static struct platform_device stargate2_flash_device = {
.name = "pxa2xx-flash",
.id = 0,
.dev = {
.platform_data = &stargate2_flash_data,
},
.resource = &flash_resources,
.num_resources = 1,
};
/*
* SRAM - The Stargate 2 has 32MB of SRAM.
*
* Here it is made available as an MTD. This will then
* typically have a cifs filesystem created on it to provide
* fast temporary storage.
*/
static struct resource sram_resources = {
.start = PXA_CS1_PHYS,
.end = PXA_CS1_PHYS + SZ_32M-1,
.flags = IORESOURCE_MEM,
};
static struct platdata_mtd_ram stargate2_sram_pdata = {
.mapname = "Stargate2 SRAM",
.bankwidth = 2,
};
static struct platform_device stargate2_sram = {
.name = "mtd-ram",
.id = 0,
.resource = &sram_resources,
.num_resources = 1,
.dev = {
.platform_data = &stargate2_sram_pdata,
},
};
static struct pcf857x_platform_data platform_data_pcf857x = {
.gpio_base = 128,
.n_latch = 0,
.setup = NULL,
.teardown = NULL,
.context = NULL,
};
static struct at24_platform_data pca9500_eeprom_pdata = {
.byte_len = 256,
.page_size = 4,
};
static struct i2c_board_info __initdata stargate2_i2c_board_info[] = {
/* Techically this a pca9500 - but it's compatible with the 8574
* for gpio expansion and the 24c02 for eeprom access.
*/
{
.type = "pcf8574",
.addr = 0x27,
.platform_data = &platform_data_pcf857x,
}, {
.type = "24c02",
.addr = 0x57,
.platform_data = &pca9500_eeprom_pdata,
}, {
.type = "max1238",
.addr = 0x35,
}, { /* ITS400 Sensor board only */
.type = "max1363",
.addr = 0x34,
/* Through a nand gate - Also beware, on V2 sensor board the
* pull up resistors are missing.
*/
.irq = IRQ_GPIO(99),
}, { /* ITS400 Sensor board only */
.type = "tsl2561",
.addr = 0x49,
/* Through a nand gate - Also beware, on V2 sensor board the
* pull up resistors are missing.
*/
.irq = IRQ_GPIO(99),
}, { /* ITS400 Sensor board only */
.type = "tmp175",
.addr = 0x4A,
.irq = IRQ_GPIO(96),
},
};
static struct i2c_board_info __initdata stargate2_pwr_i2c_board_info[] = {
{
.type = "da9030",
.addr = 0x49,
.platform_data = &stargate2_da9030_pdata,
.irq = gpio_to_irq(1),
},
};
static struct pxa2xx_spi_master pxa_ssp_master_0_info = {
.num_chipselect = 1,
};
static struct pxa2xx_spi_master pxa_ssp_master_1_info = {
.num_chipselect = 1,
};
static struct pxa2xx_spi_master pxa_ssp_master_2_info = {
.num_chipselect = 1,
};
/* An upcoming kernel change will scrap SFRM usage so these
* drivers have been moved to use gpio's via cs_control */
static struct pxa2xx_spi_chip staccel_chip_info = {
.tx_threshold = 8,
.rx_threshold = 8,
.dma_burst_size = 8,
.timeout = 235,
.gpio_cs = 24,
};
static struct pxa2xx_spi_chip cc2420_info = {
.tx_threshold = 8,
.rx_threshold = 8,
.dma_burst_size = 8,
.timeout = 235,
.gpio_cs = 39,
};
static struct spi_board_info spi_board_info[] __initdata = {
{
.modalias = "lis3l02dq",
.max_speed_hz = 8000000,/* 8MHz max spi frequency at 3V */
.bus_num = 1,
.chip_select = 0,
.controller_data = &staccel_chip_info,
.irq = IRQ_GPIO(96),
}, {
.modalias = "cc2420",
.max_speed_hz = 6500000,
.bus_num = 3,
.chip_select = 0,
.controller_data = &cc2420_info,
},
};
static void sg2_udc_command(int cmd)
{
switch (cmd) {
case PXA2XX_UDC_CMD_CONNECT:
UP2OCR |= UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE;
break;
case PXA2XX_UDC_CMD_DISCONNECT:
UP2OCR &= ~(UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE);
break;
}
}
/* Board doesn't support cable detection - so always lie and say
* something is there.
*/
static int sg2_udc_detect(void)
{
return 1;
}
static struct pxa2xx_udc_mach_info stargate2_udc_info __initdata = {
.udc_is_connected = sg2_udc_detect,
.udc_command = sg2_udc_command,
};
static struct platform_device *stargate2_devices[] = {
&stargate2_flash_device,
&stargate2_sram,
&smc91x_device,
&sht15,
};
static struct i2c_pxa_platform_data i2c_pwr_pdata = {
.fast_mode = 1,
};
static struct i2c_pxa_platform_data i2c_pdata = {
.fast_mode = 1,
};
static void __init stargate2_init(void)
{
/* This is probably a board specific hack as this must be set
prior to connecting the MFP stuff up. */
MECR &= ~MECR_NOS;
pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config));
/* spi chip selects */
gpio_direction_output(37, 0);
gpio_direction_output(24, 0);
gpio_direction_output(39, 0);
platform_add_devices(ARRAY_AND_SIZE(stargate2_devices));
pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info);
pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info);
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
i2c_register_board_info(0, ARRAY_AND_SIZE(stargate2_i2c_board_info));
i2c_register_board_info(1,
ARRAY_AND_SIZE(stargate2_pwr_i2c_board_info));
pxa27x_set_i2c_power_info(&i2c_pwr_pdata);
pxa_set_i2c_info(&i2c_pdata);
pxa_set_mci_info(&stargate2_mci_platform_data);
pxa_set_udc_info(&stargate2_udc_info);
stargate2_reset_bluetooth();
}
MACHINE_START(STARGATE2, "Stargate 2")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = stargate2_init,
.boot_params = 0xA0000100,
MACHINE_END
......@@ -40,7 +40,7 @@
#include <mach/pxa25x.h>
#include <mach/reset.h>
#include <mach/irda.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/tosa_bt.h>
......
......@@ -47,7 +47,7 @@
#include <mach/mmc.h>
#include <mach/irda.h>
#include <mach/ohci.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include "generic.h"
#include "devices.h"
......
......@@ -45,7 +45,7 @@
#include <mach/pxa25x.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/regs-uart.h>
#include <mach/viper.h>
......
......@@ -21,7 +21,7 @@
#include <linux/gpio.h>
#include <mach/pxa300.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
#include <mach/zylonite.h>
#include "generic.h"
......
/*
* Based on spitz_pm.c and sharp code.
*
* Copyright (C) 2001 SHARP
* Copyright 2005 Pavel Machek <pavel@suse.cz>
*
* Distribute under GPLv2.
*
* Li-ion batteries are angry beasts, and they like to explode. This driver is not finished,
* and sometimes charges them when it should not. If it makes angry lithium to come your way...
* ...well, you have been warned.
*
* Actually, this should be quite safe, it seems sharp leaves charger enabled by default,
* and my collie did not explode (yet).
*/
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <asm/hardware/scoop.h>
#include <mach/dma.h>
#include <mach/collie.h>
#include <asm/mach/sharpsl_param.h>
#include <asm/hardware/sharpsl_pm.h>
#include "../drivers/mfd/ucb1x00.h"
static struct ucb1x00 *ucb;
static int ad_revise;
#define ADCtoPower(x) ((330 * x * 2) / 1024)
static void collie_charger_init(void)
{
int err;
if (sharpsl_param.adadj != -1)
ad_revise = sharpsl_param.adadj;
/* Register interrupt handler. */
if ((err = request_irq(COLLIE_IRQ_GPIO_AC_IN, sharpsl_ac_isr, IRQF_DISABLED,
"ACIN", sharpsl_ac_isr))) {
printk("Could not get irq %d.\n", COLLIE_IRQ_GPIO_AC_IN);
return;
}
if ((err = request_irq(COLLIE_IRQ_GPIO_CO, sharpsl_chrg_full_isr, IRQF_DISABLED,
"CO", sharpsl_chrg_full_isr))) {
free_irq(COLLIE_IRQ_GPIO_AC_IN, sharpsl_ac_isr);
printk("Could not get irq %d.\n", COLLIE_IRQ_GPIO_CO);
return;
}
gpio_request(COLLIE_GPIO_CHARGE_ON, "charge on");
gpio_direction_output(COLLIE_GPIO_CHARGE_ON, 1);
ucb1x00_io_set_dir(ucb, 0, COLLIE_TC35143_GPIO_MBAT_ON | COLLIE_TC35143_GPIO_TMP_ON |
COLLIE_TC35143_GPIO_BBAT_ON);
return;
}
static void collie_measure_temp(int on)
{
if (on)
ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_TMP_ON, 0);
else
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_TMP_ON);
}
static void collie_charge(int on)
{
/* Zaurus seems to contain LTC1731; it should know when to
* stop charging itself, so setting charge on should be
* relatively harmless (as long as it is not done too often).
*/
gpio_set_value(COLLIE_GPIO_CHARGE_ON, on);
}
static void collie_discharge(int on)
{
}
static void collie_discharge1(int on)
{
}
static void collie_presuspend(void)
{
}
static void collie_postsuspend(void)
{
}
static int collie_should_wakeup(unsigned int resume_on_alarm)
{
return 0;
}
static unsigned long collie_charger_wakeup(void)
{
return 0;
}
int collie_read_backup_battery(void)
{
int voltage;
ucb1x00_adc_enable(ucb);
ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_BBAT_ON, 0);
voltage = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_SYNC);
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_BBAT_ON);
ucb1x00_adc_disable(ucb);
printk("Backup battery = %d(%d)\n", ADCtoPower(voltage), voltage);
return ADCtoPower(voltage);
}
int collie_read_main_battery(void)
{
int voltage, voltage_rev, voltage_volts;
ucb1x00_adc_enable(ucb);
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_BBAT_ON);
ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_MBAT_ON, 0);
mdelay(1);
voltage = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_SYNC);
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_MBAT_ON);
ucb1x00_adc_disable(ucb);
voltage_rev = voltage + ((ad_revise * voltage) / 652);
voltage_volts = ADCtoPower(voltage_rev);
printk("Main battery = %d(%d)\n", voltage_volts, voltage);
if (voltage != -1)
return voltage_volts;
else
return voltage;
}
int collie_read_temp(void)
{
int voltage;
/* According to Sharp, temp must be > 973, main battery must be < 465,
FIXME: sharpsl_pm.c has both conditions negated? FIXME: values
are way out of range? */
ucb1x00_adc_enable(ucb);
ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_TMP_ON, 0);
/* >1010 = battery removed, 460 = 22C ?, higher = lower temp ? */
voltage = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD0, UCB_SYNC);
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_TMP_ON);
ucb1x00_adc_disable(ucb);
printk("Battery temp = %d\n", voltage);
return voltage;
}
static unsigned long read_devdata(int which)
{
switch (which) {
case SHARPSL_BATT_VOLT:
return collie_read_main_battery();
case SHARPSL_BATT_TEMP:
return collie_read_temp();
case SHARPSL_ACIN_VOLT:
return 500;
case SHARPSL_STATUS_ACIN: {
int ret = GPLR & COLLIE_GPIO_AC_IN;
printk("AC status = %d\n", ret);
return ret;
}
case SHARPSL_STATUS_FATAL: {
int ret = GPLR & COLLIE_GPIO_MAIN_BAT_LOW;
printk("Fatal bat = %d\n", ret);
return ret;
}
default:
return ~0;
}
}
struct battery_thresh collie_battery_levels_acin[] = {
{ 420, 100},
{ 417, 95},
{ 415, 90},
{ 413, 80},
{ 411, 75},
{ 408, 70},
{ 406, 60},
{ 403, 50},
{ 398, 40},
{ 391, 25},
{ 10, 5},
{ 0, 0},
};
struct battery_thresh collie_battery_levels[] = {
{ 394, 100},
{ 390, 95},
{ 380, 90},
{ 370, 80},
{ 368, 75}, /* From sharp code: battery high with frontlight */
{ 366, 70}, /* 60..90 -- fake values invented by me for testing */
{ 364, 60},
{ 362, 50},
{ 360, 40},
{ 358, 25}, /* From sharp code: battery low with frontlight */
{ 356, 5}, /* From sharp code: battery verylow with frontlight */
{ 0, 0},
};
struct sharpsl_charger_machinfo collie_pm_machinfo = {
.init = collie_charger_init,
.read_devdata = read_devdata,
.discharge = collie_discharge,
.discharge1 = collie_discharge1,
.charge = collie_charge,
.measure_temp = collie_measure_temp,
.presuspend = collie_presuspend,
.postsuspend = collie_postsuspend,
.charger_wakeup = collie_charger_wakeup,
.should_wakeup = collie_should_wakeup,
.bat_levels = 12,
.bat_levels_noac = collie_battery_levels,
.bat_levels_acin = collie_battery_levels_acin,
.status_high_acin = 368,
.status_low_acin = 358,
.status_high_noac = 368,
.status_low_noac = 358,
.charge_on_volt = 350, /* spitz uses 2.90V, but lets play it safe. */
.charge_on_temp = 550,
.charge_acin_high = 550, /* collie does not seem to have sensor for this, anyway */
.charge_acin_low = 450, /* ignored, too */
.fatal_acin_volt = 356,
.fatal_noacin_volt = 356,
.batfull_irq = 1, /* We do not want periodical charge restarts */
};
static int __init collie_pm_ucb_add(struct ucb1x00_dev *pdev)
{
sharpsl_pm.machinfo = &collie_pm_machinfo;
ucb = pdev->ucb;
return 0;
}
static struct ucb1x00_driver collie_pm_ucb_driver = {
.add = collie_pm_ucb_add,
};
static struct platform_device *collie_pm_device;
static int __init collie_pm_init(void)
{
int ret;
collie_pm_device = platform_device_alloc("sharpsl-pm", -1);
if (!collie_pm_device)
return -ENOMEM;
collie_pm_device->dev.platform_data = &collie_pm_machinfo;
ret = platform_device_add(collie_pm_device);
if (ret)
platform_device_put(collie_pm_device);
if (!ret)
ret = ucb1x00_register_driver(&collie_pm_ucb_driver);
return ret;
}
static void __exit collie_pm_exit(void)
{
ucb1x00_unregister_driver(&collie_pm_ucb_driver);
platform_device_unregister(collie_pm_device);
}
module_init(collie_pm_init);
module_exit(collie_pm_exit);
......@@ -7,3 +7,5 @@ obj-y := dma.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_PXA3xx) += mfp.o
obj-$(CONFIG_ARCH_MMP) += mfp.o
obj-$(CONFIG_HAVE_PWM) += pwm.o
......@@ -21,6 +21,19 @@
#include <asm/div64.h>
#define HAS_SECONDARY_PWM 0x10
#define PWM_ID_BASE(d) ((d) & 0xf)
static const struct platform_device_id pwm_id_table[] = {
/* PWM has_secondary_pwm? */
{ "pxa25x-pwm", 0 },
{ "pxa27x-pwm", 0 | HAS_SECONDARY_PWM },
{ "pxa168-pwm", 1 },
{ "pxa910-pwm", 1 },
{ },
};
MODULE_DEVICE_TABLE(platform, pwm_id_table);
/* PWM registers and bits definitions */
#define PWMCR (0x00)
#define PWMDCR (0x04)
......@@ -31,6 +44,7 @@
struct pwm_device {
struct list_head node;
struct pwm_device *secondary;
struct platform_device *pdev;
const char *label;
......@@ -159,17 +173,17 @@ static inline void __add_pwm(struct pwm_device *pwm)
mutex_unlock(&pwm_lock);
}
static struct pwm_device *pwm_probe(struct platform_device *pdev,
unsigned int pwm_id, struct pwm_device *parent_pwm)
static int __devinit pwm_probe(struct platform_device *pdev)
{
struct pwm_device *pwm;
struct platform_device_id *id = platform_get_device_id(pdev);
struct pwm_device *pwm, *secondary = NULL;
struct resource *r;
int ret = 0;
pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
if (pwm == NULL) {
dev_err(&pdev->dev, "failed to allocate memory\n");
return ERR_PTR(-ENOMEM);
return -ENOMEM;
}
pwm->clk = clk_get(&pdev->dev, NULL);
......@@ -180,16 +194,9 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev,
pwm->clk_enabled = 0;
pwm->use_count = 0;
pwm->pwm_id = pwm_id;
pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id;
pwm->pdev = pdev;
if (parent_pwm != NULL) {
/* registers for the second PWM has offset of 0x10 */
pwm->mmio_base = parent_pwm->mmio_base + 0x10;
__add_pwm(pwm);
return pwm;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&pdev->dev, "no memory resource defined\n");
......@@ -211,9 +218,27 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev,
goto err_free_mem;
}
if (id->driver_data & HAS_SECONDARY_PWM) {
secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
if (secondary == NULL) {
ret = -ENOMEM;
goto err_free_mem;
}
*secondary = *pwm;
pwm->secondary = secondary;
/* registers for the second PWM has offset of 0x10 */
secondary->mmio_base = pwm->mmio_base + 0x10;
secondary->pwm_id = pdev->id + 2;
}
__add_pwm(pwm);
if (secondary)
__add_pwm(secondary);
platform_set_drvdata(pdev, pwm);
return pwm;
return 0;
err_free_mem:
release_mem_region(r->start, r->end - r->start + 1);
......@@ -221,32 +246,7 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev,
clk_put(pwm->clk);
err_free:
kfree(pwm);
return ERR_PTR(ret);
}
static int __devinit pxa25x_pwm_probe(struct platform_device *pdev)
{
struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL);
if (IS_ERR(pwm))
return PTR_ERR(pwm);
return 0;
}
static int __devinit pxa27x_pwm_probe(struct platform_device *pdev)
{
struct pwm_device *pwm;
pwm = pwm_probe(pdev, pdev->id, NULL);
if (IS_ERR(pwm))
return PTR_ERR(pwm);
pwm = pwm_probe(pdev, pdev->id + 2, pwm);
if (IS_ERR(pwm))
return PTR_ERR(pwm);
return 0;
return ret;
}
static int __devexit pwm_remove(struct platform_device *pdev)
......@@ -259,6 +259,12 @@ static int __devexit pwm_remove(struct platform_device *pdev)
return -ENODEV;
mutex_lock(&pwm_lock);
if (pwm->secondary) {
list_del(&pwm->secondary->node);
kfree(pwm->secondary);
}
list_del(&pwm->node);
mutex_unlock(&pwm_lock);
......@@ -272,46 +278,25 @@ static int __devexit pwm_remove(struct platform_device *pdev)
return 0;
}
static struct platform_driver pxa25x_pwm_driver = {
static struct platform_driver pwm_driver = {
.driver = {
.name = "pxa25x-pwm",
.owner = THIS_MODULE,
},
.probe = pxa25x_pwm_probe,
.remove = __devexit_p(pwm_remove),
};
static struct platform_driver pxa27x_pwm_driver = {
.driver = {
.name = "pxa27x-pwm",
},
.probe = pxa27x_pwm_probe,
.probe = pwm_probe,
.remove = __devexit_p(pwm_remove),
.id_table = pwm_id_table,
};
static int __init pwm_init(void)
{
int ret = 0;
ret = platform_driver_register(&pxa25x_pwm_driver);
if (ret) {
printk(KERN_ERR "failed to register pxa25x_pwm_driver\n");
return ret;
}
ret = platform_driver_register(&pxa27x_pwm_driver);
if (ret) {
printk(KERN_ERR "failed to register pxa27x_pwm_driver\n");
return ret;
}
return ret;
return platform_driver_register(&pwm_driver);
}
arch_initcall(pwm_init);
static void __exit pwm_exit(void)
{
platform_driver_unregister(&pxa25x_pwm_driver);
platform_driver_unregister(&pxa27x_pwm_driver);
platform_driver_unregister(&pwm_driver);
}
module_exit(pwm_exit);
......
......@@ -34,10 +34,24 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <mach/i2c.h>
#include <plat/i2c.h>
/*
* I2C register offsets will be shifted 0 or 1 bit left, depending on
* different SoCs
*/
#define REG_SHIFT_0 (0 << 0)
#define REG_SHIFT_1 (1 << 0)
#define REG_SHIFT(d) ((d) & 0x1)
static const struct platform_device_id i2c_pxa_id_table[] = {
{ "pxa2xx-i2c", REG_SHIFT_1 },
{ "pxa3xx-pwri2c", REG_SHIFT_0 },
{ },
};
MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
/*
* I2C registers and bit definitions
......@@ -985,6 +999,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
struct pxa_i2c *i2c;
struct resource *res;
struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
struct platform_device_id *id = platform_get_device_id(dev);
int ret;
int irq;
......@@ -1028,7 +1043,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
ret = -EIO;
goto eremap;
}
i2c->reg_shift = (cpu_is_pxa3xx() && (dev->id == 1)) ? 0 : 1;
i2c->reg_shift = REG_SHIFT(id->driver_data);
i2c->iobase = res->start;
i2c->iosize = res_len(res);
......@@ -1150,6 +1165,7 @@ static struct platform_driver i2c_pxa_driver = {
.name = "pxa2xx-i2c",
.owner = THIS_MODULE,
},
.id_table = i2c_pxa_id_table,
};
static int __init i2c_adap_pxa_init(void)
......
......@@ -45,7 +45,8 @@
defined(CONFIG_MACH_ZYLONITE) ||\
defined(CONFIG_MACH_LITTLETON) ||\
defined(CONFIG_MACH_ZYLONITE2) ||\
defined(CONFIG_ARCH_VIPER)
defined(CONFIG_ARCH_VIPER) ||\
defined(CONFIG_MACH_STARGATE2)
#include <asm/mach-types.h>
......@@ -73,7 +74,7 @@
/* We actually can't write halfwords properly if not word aligned */
static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
{
if (machine_is_mainstone() && reg & 2) {
if ((machine_is_mainstone() || machine_is_stargate2()) && reg & 2) {
unsigned int v = val << 16;
v |= readl(ioaddr + (reg & ~2)) & 0xffff;
writel(v, ioaddr + (reg & ~2));
......
......@@ -217,7 +217,7 @@ config PCMCIA_PXA2XX
depends on ARM && ARCH_PXA && PCMCIA
depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
|| MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
|| ARCH_VIPER || ARCH_PXA_ESERIES)
|| ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2)
help
Say Y here to include support for the PXA2xx PCMCIA controller
......
......@@ -73,5 +73,6 @@ pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps4.o
pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y)
/*
* linux/drivers/pcmcia/pxa2xx_stargate2.c
*
* Stargate 2 PCMCIA specific routines.
*
* Created: December 6, 2005
* Author: Ed C. Epp
* Copyright: Intel Corp 2005
* Jonathan Cameron <jic23@cam.ac.uk> 2009
*
* 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/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <pcmcia/ss.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include "soc_common.h"
#define SG2_S0_BUFF_CTL 120
#define SG2_S0_POWER_CTL 108
#define SG2_S0_GPIO_RESET 82
#define SG2_S0_GPIO_DETECT 53
#define SG2_S0_GPIO_READY 81
static struct pcmcia_irqs irqs[] = {
{ 0, IRQ_GPIO(SG2_S0_GPIO_DETECT), "PCMCIA0 CD" },
};
static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
skt->irq = IRQ_GPIO(SG2_S0_GPIO_READY);
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void sg2_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
state->detect = !gpio_get_value(SG2_S0_GPIO_DETECT);
state->ready = !!gpio_get_value(SG2_S0_GPIO_READY);
state->bvd1 = 0; /* not available - battery detect on card */
state->bvd2 = 0; /* not available */
state->vs_3v = 1; /* not available - voltage detect for card */
state->vs_Xv = 0; /* not available */
state->wrprot = 0; /* not available - write protect */
}
static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
/* Enable card power */
switch (state->Vcc) {
case 0:
/* sets power ctl register high */
gpio_set_value(SG2_S0_POWER_CTL, 1);
break;
case 33:
case 50:
/* sets power control register low (clear) */
gpio_set_value(SG2_S0_POWER_CTL, 0);
msleep(100);
break;
default:
pr_err("%s(): bad Vcc %u\n",
__func__, state->Vcc);
return -1;
}
/* reset */
gpio_set_value(SG2_S0_GPIO_RESET, !!(state->flags & SS_RESET));
return 0;
}
static void sg2_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static void sg2_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
}
static struct pcmcia_low_level sg2_pcmcia_ops __initdata = {
.owner = THIS_MODULE,
.hw_init = sg2_pcmcia_hw_init,
.hw_shutdown = sg2_pcmcia_hw_shutdown,
.socket_state = sg2_pcmcia_socket_state,
.configure_socket = sg2_pcmcia_configure_socket,
.socket_init = sg2_pcmcia_socket_init,
.socket_suspend = sg2_pcmcia_socket_suspend,
.nr = 1,
};
static struct platform_device *sg2_pcmcia_device;
static int __init sg2_pcmcia_init(void)
{
int ret;
if (!machine_is_stargate2())
return -ENODEV;
sg2_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
if (!sg2_pcmcia_device)
return -ENOMEM;
ret = gpio_request(SG2_S0_BUFF_CTL, "SG2 CF buff ctl");
if (ret)
goto error_put_platform_device;
ret = gpio_request(SG2_S0_POWER_CTL, "SG2 CF power ctl");
if (ret)
goto error_free_gpio_buff_ctl;
ret = gpio_request(SG2_S0_GPIO_RESET, "SG2 CF reset");
if (ret)
goto error_free_gpio_power_ctl;
/* Set gpio directions */
gpio_direction_output(SG2_S0_BUFF_CTL, 0);
gpio_direction_output(SG2_S0_POWER_CTL, 1);
gpio_direction_output(SG2_S0_GPIO_RESET, 1);
ret = platform_device_add_data(sg2_pcmcia_device,
&sg2_pcmcia_ops,
sizeof(sg2_pcmcia_ops));
if (ret)
goto error_free_gpio_reset;
ret = platform_device_add(sg2_pcmcia_device);
if (ret)
goto error_free_gpio_reset;
return 0;
error_free_gpio_reset:
gpio_free(SG2_S0_GPIO_RESET);
error_free_gpio_power_ctl:
gpio_free(SG2_S0_POWER_CTL);
error_free_gpio_buff_ctl:
gpio_free(SG2_S0_BUFF_CTL);
error_put_platform_device:
platform_device_put(sg2_pcmcia_device);
return ret;
}
static void __exit sg2_pcmcia_exit(void)
{
platform_device_unregister(sg2_pcmcia_device);
gpio_free(SG2_S0_BUFF_CTL);
gpio_free(SG2_S0_POWER_CTL);
gpio_free(SG2_S0_GPIO_RESET);
}
fs_initcall(sg2_pcmcia_init);
module_exit(sg2_pcmcia_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pxa2xx-pcmcia");
......@@ -1759,6 +1759,16 @@ config FB_68328
Say Y here if you want to support the built-in frame buffer of
the Motorola 68328 CPU family.
config FB_PXA168
tristate "PXA168/910 LCD framebuffer support"
depends on FB && (CPU_PXA168 || CPU_PXA910)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
Frame buffer driver for the built-in LCD controller in the Marvell
MMP processor.
config FB_PXA
tristate "PXA LCD framebuffer support"
depends on FB && ARCH_PXA
......
......@@ -97,6 +97,7 @@ obj-$(CONFIG_FB_GBE) += gbefb.o
obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
obj-$(CONFIG_FB_PXA) += pxafb.o
obj-$(CONFIG_FB_PXA168) += pxa168fb.o
obj-$(CONFIG_FB_W100) += w100fb.o
obj-$(CONFIG_FB_TMIO) += tmiofb.o
obj-$(CONFIG_FB_AU1100) += au1100fb.o
......
/*
* linux/drivers/video/pxa168fb.c -- Marvell PXA168 LCD Controller
*
* Copyright (C) 2008 Marvell International Ltd.
* All rights reserved.
*
* 2009-02-16 adapted from original version for PXA168/910
* Jun Nie <njun@marvell.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/uaccess.h>
#include <video/pxa168fb.h>
#include "pxa168fb.h"
#define DEFAULT_REFRESH 60 /* Hz */
static int determine_best_pix_fmt(struct fb_var_screeninfo *var)
{
/*
* Pseudocolor mode?
*/
if (var->bits_per_pixel == 8)
return PIX_FMT_PSEUDOCOLOR;
/*
* Check for 565/1555.
*/
if (var->bits_per_pixel == 16 && var->red.length <= 5 &&
var->green.length <= 6 && var->blue.length <= 5) {
if (var->transp.length == 0) {
if (var->red.offset >= var->blue.offset)
return PIX_FMT_RGB565;
else
return PIX_FMT_BGR565;
}
if (var->transp.length == 1 && var->green.length <= 5) {
if (var->red.offset >= var->blue.offset)
return PIX_FMT_RGB1555;
else
return PIX_FMT_BGR1555;
}
/* fall through */
}
/*
* Check for 888/A888.
*/
if (var->bits_per_pixel <= 32 && var->red.length <= 8 &&
var->green.length <= 8 && var->blue.length <= 8) {
if (var->bits_per_pixel == 24 && var->transp.length == 0) {
if (var->red.offset >= var->blue.offset)
return PIX_FMT_RGB888PACK;
else
return PIX_FMT_BGR888PACK;
}
if (var->bits_per_pixel == 32 && var->transp.length == 8) {
if (var->red.offset >= var->blue.offset)
return PIX_FMT_RGBA888;
else
return PIX_FMT_BGRA888;
} else {
if (var->red.offset >= var->blue.offset)
return PIX_FMT_RGB888UNPACK;
else
return PIX_FMT_BGR888UNPACK;
}
/* fall through */
}
return -EINVAL;
}
static void set_pix_fmt(struct fb_var_screeninfo *var, int pix_fmt)
{
switch (pix_fmt) {
case PIX_FMT_RGB565:
var->bits_per_pixel = 16;
var->red.offset = 11; var->red.length = 5;
var->green.offset = 5; var->green.length = 6;
var->blue.offset = 0; var->blue.length = 5;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIX_FMT_BGR565:
var->bits_per_pixel = 16;
var->red.offset = 0; var->red.length = 5;
var->green.offset = 5; var->green.length = 6;
var->blue.offset = 11; var->blue.length = 5;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIX_FMT_RGB1555:
var->bits_per_pixel = 16;
var->red.offset = 10; var->red.length = 5;
var->green.offset = 5; var->green.length = 5;
var->blue.offset = 0; var->blue.length = 5;
var->transp.offset = 15; var->transp.length = 1;
break;
case PIX_FMT_BGR1555:
var->bits_per_pixel = 16;
var->red.offset = 0; var->red.length = 5;
var->green.offset = 5; var->green.length = 5;
var->blue.offset = 10; var->blue.length = 5;
var->transp.offset = 15; var->transp.length = 1;
break;
case PIX_FMT_RGB888PACK:
var->bits_per_pixel = 24;
var->red.offset = 16; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 0; var->blue.length = 8;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIX_FMT_BGR888PACK:
var->bits_per_pixel = 24;
var->red.offset = 0; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 16; var->blue.length = 8;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIX_FMT_RGBA888:
var->bits_per_pixel = 32;
var->red.offset = 16; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 0; var->blue.length = 8;
var->transp.offset = 24; var->transp.length = 8;
break;
case PIX_FMT_BGRA888:
var->bits_per_pixel = 32;
var->red.offset = 0; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 16; var->blue.length = 8;
var->transp.offset = 24; var->transp.length = 8;
break;
case PIX_FMT_PSEUDOCOLOR:
var->bits_per_pixel = 8;
var->red.offset = 0; var->red.length = 8;
var->green.offset = 0; var->green.length = 8;
var->blue.offset = 0; var->blue.length = 8;
var->transp.offset = 0; var->transp.length = 0;
break;
}
}
static void set_mode(struct pxa168fb_info *fbi, struct fb_var_screeninfo *var,
struct fb_videomode *mode, int pix_fmt, int ystretch)
{
struct fb_info *info = fbi->info;
set_pix_fmt(var, pix_fmt);
var->xres = mode->xres;
var->yres = mode->yres;
var->xres_virtual = max(var->xres, var->xres_virtual);
if (ystretch)
var->yres_virtual = info->fix.smem_len /
(var->xres_virtual * (var->bits_per_pixel >> 3));
else
var->yres_virtual = max(var->yres, var->yres_virtual);
var->grayscale = 0;
var->accel_flags = FB_ACCEL_NONE;
var->pixclock = mode->pixclock;
var->left_margin = mode->left_margin;
var->right_margin = mode->right_margin;
var->upper_margin = mode->upper_margin;
var->lower_margin = mode->lower_margin;
var->hsync_len = mode->hsync_len;
var->vsync_len = mode->vsync_len;
var->sync = mode->sync;
var->vmode = FB_VMODE_NONINTERLACED;
var->rotate = FB_ROTATE_UR;
}
static int pxa168fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct pxa168fb_info *fbi = info->par;
int pix_fmt;
/*
* Determine which pixel format we're going to use.
*/
pix_fmt = determine_best_pix_fmt(var);
if (pix_fmt < 0)
return pix_fmt;
set_pix_fmt(var, pix_fmt);
fbi->pix_fmt = pix_fmt;
/*
* Basic geometry sanity checks.
*/
if (var->xoffset + var->xres > var->xres_virtual)
return -EINVAL;
if (var->yoffset + var->yres > var->yres_virtual)
return -EINVAL;
if (var->xres + var->right_margin +
var->hsync_len + var->left_margin > 2048)
return -EINVAL;
if (var->yres + var->lower_margin +
var->vsync_len + var->upper_margin > 2048)
return -EINVAL;
/*
* Check size of framebuffer.
*/
if (var->xres_virtual * var->yres_virtual *
(var->bits_per_pixel >> 3) > info->fix.smem_len)
return -EINVAL;
return 0;
}
/*
* The hardware clock divider has an integer and a fractional
* stage:
*
* clk2 = clk_in / integer_divider
* clk_out = clk2 * (1 - (fractional_divider >> 12))
*
* Calculate integer and fractional divider for given clk_in
* and clk_out.
*/
static void set_clock_divider(struct pxa168fb_info *fbi,
const struct fb_videomode *m)
{
int divider_int;
int needed_pixclk;
u64 div_result;
u32 x = 0;
/*
* Notice: The field pixclock is used by linux fb
* is in pixel second. E.g. struct fb_videomode &
* struct fb_var_screeninfo
*/
/*
* Check input values.
*/
if (!m || !m->pixclock || !m->refresh) {
dev_err(fbi->dev, "Input refresh or pixclock is wrong.\n");
return;
}
/*
* Using PLL/AXI clock.
*/
x = 0x80000000;
/*
* Calc divider according to refresh rate.
*/
div_result = 1000000000000ll;
do_div(div_result, m->pixclock);
needed_pixclk = (u32)div_result;
divider_int = clk_get_rate(fbi->clk) / needed_pixclk;
/* check whether divisor is too small. */
if (divider_int < 2) {
dev_warn(fbi->dev, "Warning: clock source is too slow."
"Try smaller resolution\n");
divider_int = 2;
}
/*
* Set setting to reg.
*/
x |= divider_int;
writel(x, fbi->reg_base + LCD_CFG_SCLK_DIV);
}
static void set_dma_control0(struct pxa168fb_info *fbi)
{
u32 x;
/*
* Set bit to enable graphics DMA.
*/
x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0);
x |= fbi->active ? 0x00000100 : 0;
fbi->active = 0;
/*
* If we are in a pseudo-color mode, we need to enable
* palette lookup.
*/
if (fbi->pix_fmt == PIX_FMT_PSEUDOCOLOR)
x |= 0x10000000;
/*
* Configure hardware pixel format.
*/
x &= ~(0xF << 16);
x |= (fbi->pix_fmt >> 1) << 16;
/*
* Check red and blue pixel swap.
* 1. source data swap
* 2. panel output data swap
*/
x &= ~(1 << 12);
x |= ((fbi->pix_fmt & 1) ^ (fbi->panel_rbswap)) << 12;
writel(x, fbi->reg_base + LCD_SPU_DMA_CTRL0);
}
static void set_dma_control1(struct pxa168fb_info *fbi, int sync)
{
u32 x;
/*
* Configure default bits: vsync triggers DMA, gated clock
* enable, power save enable, configure alpha registers to
* display 100% graphics, and set pixel command.
*/
x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL1);
x |= 0x2032ff81;
/*
* We trigger DMA on the falling edge of vsync if vsync is
* active low, or on the rising edge if vsync is active high.
*/
if (!(sync & FB_SYNC_VERT_HIGH_ACT))
x |= 0x08000000;
writel(x, fbi->reg_base + LCD_SPU_DMA_CTRL1);
}
static void set_graphics_start(struct fb_info *info, int xoffset, int yoffset)
{
struct pxa168fb_info *fbi = info->par;
struct fb_var_screeninfo *var = &info->var;
int pixel_offset;
unsigned long addr;
pixel_offset = (yoffset * var->xres_virtual) + xoffset;
addr = fbi->fb_start_dma + (pixel_offset * (var->bits_per_pixel >> 3));
writel(addr, fbi->reg_base + LCD_CFG_GRA_START_ADDR0);
}
static void set_dumb_panel_control(struct fb_info *info)
{
struct pxa168fb_info *fbi = info->par;
struct pxa168fb_mach_info *mi = fbi->dev->platform_data;
u32 x;
/*
* Preserve enable flag.
*/
x = readl(fbi->reg_base + LCD_SPU_DUMB_CTRL) & 0x00000001;
x |= (fbi->is_blanked ? 0x7 : mi->dumb_mode) << 28;
x |= mi->gpio_output_data << 20;
x |= mi->gpio_output_mask << 12;
x |= mi->panel_rgb_reverse_lanes ? 0x00000080 : 0;
x |= mi->invert_composite_blank ? 0x00000040 : 0;
x |= (info->var.sync & FB_SYNC_COMP_HIGH_ACT) ? 0x00000020 : 0;
x |= mi->invert_pix_val_ena ? 0x00000010 : 0;
x |= (info->var.sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x00000008;
x |= (info->var.sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x00000004;
x |= mi->invert_pixclock ? 0x00000002 : 0;
writel(x, fbi->reg_base + LCD_SPU_DUMB_CTRL);
}
static void set_dumb_screen_dimensions(struct fb_info *info)
{
struct pxa168fb_info *fbi = info->par;
struct fb_var_screeninfo *v = &info->var;
int x;
int y;
x = v->xres + v->right_margin + v->hsync_len + v->left_margin;
y = v->yres + v->lower_margin + v->vsync_len + v->upper_margin;
writel((y << 16) | x, fbi->reg_base + LCD_SPUT_V_H_TOTAL);
}
static int pxa168fb_set_par(struct fb_info *info)
{
struct pxa168fb_info *fbi = info->par;
struct fb_var_screeninfo *var = &info->var;
struct fb_videomode mode;
u32 x;
struct pxa168fb_mach_info *mi;
mi = fbi->dev->platform_data;
/*
* Set additional mode info.
*/
if (fbi->pix_fmt == PIX_FMT_PSEUDOCOLOR)
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
else
info->fix.visual = FB_VISUAL_TRUECOLOR;
info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
info->fix.ypanstep = var->yres;
/*
* Disable panel output while we setup the display.
*/
x = readl(fbi->reg_base + LCD_SPU_DUMB_CTRL);
writel(x & ~1, fbi->reg_base + LCD_SPU_DUMB_CTRL);
/*
* Configure global panel parameters.
*/
writel((var->yres << 16) | var->xres,
fbi->reg_base + LCD_SPU_V_H_ACTIVE);
/*
* convet var to video mode
*/
fb_var_to_videomode(&mode, &info->var);
/* Calculate clock divisor. */
set_clock_divider(fbi, &mode);
/* Configure dma ctrl regs. */
set_dma_control0(fbi);
set_dma_control1(fbi, info->var.sync);
/*
* Configure graphics DMA parameters.
*/
x = readl(fbi->reg_base + LCD_CFG_GRA_PITCH);
x = (x & ~0xFFFF) | ((var->xres_virtual * var->bits_per_pixel) >> 3);
writel(x, fbi->reg_base + LCD_CFG_GRA_PITCH);
writel((var->yres << 16) | var->xres,
fbi->reg_base + LCD_SPU_GRA_HPXL_VLN);
writel((var->yres << 16) | var->xres,
fbi->reg_base + LCD_SPU_GZM_HPXL_VLN);
/*
* Configure dumb panel ctrl regs & timings.
*/
set_dumb_panel_control(info);
set_dumb_screen_dimensions(info);
writel((var->left_margin << 16) | var->right_margin,
fbi->reg_base + LCD_SPU_H_PORCH);
writel((var->upper_margin << 16) | var->lower_margin,
fbi->reg_base + LCD_SPU_V_PORCH);
/*
* Re-enable panel output.
*/
x = readl(fbi->reg_base + LCD_SPU_DUMB_CTRL);
writel(x | 1, fbi->reg_base + LCD_SPU_DUMB_CTRL);
return 0;
}
static unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{
return ((chan & 0xffff) >> (16 - bf->length)) << bf->offset;
}
static u32 to_rgb(u16 red, u16 green, u16 blue)
{
red >>= 8;
green >>= 8;
blue >>= 8;
return (red << 16) | (green << 8) | blue;
}
static int
pxa168fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
unsigned int blue, unsigned int trans, struct fb_info *info)
{
struct pxa168fb_info *fbi = info->par;
u32 val;
if (info->var.grayscale)
red = green = blue = (19595 * red + 38470 * green +
7471 * blue) >> 16;
if (info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 16) {
val = chan_to_field(red, &info->var.red);
val |= chan_to_field(green, &info->var.green);
val |= chan_to_field(blue , &info->var.blue);
fbi->pseudo_palette[regno] = val;
}
if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) {
val = to_rgb(red, green, blue);
writel(val, fbi->reg_base + LCD_SPU_SRAM_WRDAT);
writel(0x8300 | regno, fbi->reg_base + LCD_SPU_SRAM_CTRL);
}
return 0;
}
static int pxa168fb_blank(int blank, struct fb_info *info)
{
struct pxa168fb_info *fbi = info->par;
fbi->is_blanked = (blank == FB_BLANK_UNBLANK) ? 0 : 1;
set_dumb_panel_control(info);
return 0;
}
static int pxa168fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
set_graphics_start(info, var->xoffset, var->yoffset);
return 0;
}
static irqreturn_t pxa168fb_handle_irq(int irq, void *dev_id)
{
struct pxa168fb_info *fbi = dev_id;
u32 isr = readl(fbi->reg_base + SPU_IRQ_ISR);
if ((isr & GRA_FRAME_IRQ0_ENA_MASK)) {
writel(isr & (~GRA_FRAME_IRQ0_ENA_MASK),
fbi->reg_base + SPU_IRQ_ISR);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
static struct fb_ops pxa168fb_ops = {
.owner = THIS_MODULE,
.fb_check_var = pxa168fb_check_var,
.fb_set_par = pxa168fb_set_par,
.fb_setcolreg = pxa168fb_setcolreg,
.fb_blank = pxa168fb_blank,
.fb_pan_display = pxa168fb_pan_display,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
};
static int __init pxa168fb_init_mode(struct fb_info *info,
struct pxa168fb_mach_info *mi)
{
struct pxa168fb_info *fbi = info->par;
struct fb_var_screeninfo *var = &info->var;
int ret = 0;
u32 total_w, total_h, refresh;
u64 div_result;
const struct fb_videomode *m;
/*
* Set default value
*/
refresh = DEFAULT_REFRESH;
/* try to find best video mode. */
m = fb_find_best_mode(&info->var, &info->modelist);
if (m)
fb_videomode_to_var(&info->var, m);
/* Init settings. */
var->xres_virtual = var->xres;
var->yres_virtual = info->fix.smem_len /
(var->xres_virtual * (var->bits_per_pixel >> 3));
dev_dbg(fbi->dev, "pxa168fb: find best mode: res = %dx%d\n",
var->xres, var->yres);
/* correct pixclock. */
total_w = var->xres + var->left_margin + var->right_margin +
var->hsync_len;
total_h = var->yres + var->upper_margin + var->lower_margin +
var->vsync_len;
div_result = 1000000000000ll;
do_div(div_result, total_w * total_h * refresh);
var->pixclock = (u32)div_result;
return ret;
}
static int __init pxa168fb_probe(struct platform_device *pdev)
{
struct pxa168fb_mach_info *mi;
struct fb_info *info = 0;
struct pxa168fb_info *fbi = 0;
struct resource *res;
struct clk *clk;
int irq, ret;
mi = pdev->dev.platform_data;
if (mi == NULL) {
dev_err(&pdev->dev, "no platform data defined\n");
return -EINVAL;
}
clk = clk_get(&pdev->dev, "LCDCLK");
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "unable to get LCDCLK");
return PTR_ERR(clk);
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "no IO memory defined\n");
return -ENOENT;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no IRQ defined\n");
return -ENOENT;
}
info = framebuffer_alloc(sizeof(struct pxa168fb_info), &pdev->dev);
if (info == NULL) {
clk_put(clk);
return -ENOMEM;
}
/* Initialize private data */
fbi = info->par;
fbi->info = info;
fbi->clk = clk;
fbi->dev = info->dev = &pdev->dev;
fbi->panel_rbswap = mi->panel_rbswap;
fbi->is_blanked = 0;
fbi->active = mi->active;
/*
* Initialise static fb parameters.
*/
info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK |
FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
info->node = -1;
strlcpy(info->fix.id, mi->id, 16);
info->fix.type = FB_TYPE_PACKED_PIXELS;
info->fix.type_aux = 0;
info->fix.xpanstep = 0;
info->fix.ypanstep = 0;
info->fix.ywrapstep = 0;
info->fix.mmio_start = res->start;
info->fix.mmio_len = res->end - res->start + 1;
info->fix.accel = FB_ACCEL_NONE;
info->fbops = &pxa168fb_ops;
info->pseudo_palette = fbi->pseudo_palette;
/*
* Map LCD controller registers.
*/
fbi->reg_base = ioremap_nocache(res->start, res->end - res->start);
if (fbi->reg_base == NULL) {
ret = -ENOMEM;
goto failed;
}
/*
* Allocate framebuffer memory.
*/
info->fix.smem_len = PAGE_ALIGN(DEFAULT_FB_SIZE);
info->screen_base = dma_alloc_writecombine(fbi->dev, info->fix.smem_len,
&fbi->fb_start_dma, GFP_KERNEL);
if (info->screen_base == NULL) {
ret = -ENOMEM;
goto failed;
}
info->fix.smem_start = (unsigned long)fbi->fb_start_dma;
/*
* Set video mode according to platform data.
*/
set_mode(fbi, &info->var, mi->modes, mi->pix_fmt, 1);
fb_videomode_to_modelist(mi->modes, mi->num_modes, &info->modelist);
/*
* init video mode data.
*/
pxa168fb_init_mode(info, mi);
ret = pxa168fb_check_var(&info->var, info);
if (ret)
goto failed_free_fbmem;
/*
* Fill in sane defaults.
*/
ret = pxa168fb_check_var(&info->var, info);
if (ret)
goto failed;
/*
* enable controller clock
*/
clk_enable(fbi->clk);
pxa168fb_set_par(info);
/*
* Configure default register values.
*/
writel(0, fbi->reg_base + LCD_SPU_BLANKCOLOR);
writel(mi->io_pin_allocation_mode, fbi->reg_base + SPU_IOPAD_CONTROL);
writel(0, fbi->reg_base + LCD_CFG_GRA_START_ADDR1);
writel(0, fbi->reg_base + LCD_SPU_GRA_OVSA_HPXL_VLN);
writel(0, fbi->reg_base + LCD_SPU_SRAM_PARA0);
writel(CFG_CSB_256x32(0x1)|CFG_CSB_256x24(0x1)|CFG_CSB_256x8(0x1),
fbi->reg_base + LCD_SPU_SRAM_PARA1);
/*
* Allocate color map.
*/
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
ret = -ENOMEM;
goto failed_free_clk;
}
/*
* Register irq handler.
*/
ret = request_irq(irq, pxa168fb_handle_irq, IRQF_SHARED,
info->fix.id, fbi);
if (ret < 0) {
dev_err(&pdev->dev, "unable to request IRQ\n");
ret = -ENXIO;
goto failed_free_cmap;
}
/*
* Enable GFX interrupt
*/
writel(GRA_FRAME_IRQ0_ENA(0x1), fbi->reg_base + SPU_IRQ_ENA);
/*
* Register framebuffer.
*/
ret = register_framebuffer(info);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register pxa168-fb: %d\n", ret);
ret = -ENXIO;
goto failed_free_irq;
}
platform_set_drvdata(pdev, fbi);
return 0;
failed_free_irq:
free_irq(irq, fbi);
failed_free_cmap:
fb_dealloc_cmap(&info->cmap);
failed_free_clk:
clk_disable(fbi->clk);
failed_free_fbmem:
dma_free_coherent(fbi->dev, info->fix.smem_len,
info->screen_base, fbi->fb_start_dma);
failed:
kfree(info);
clk_put(clk);
dev_err(&pdev->dev, "frame buffer device init failed with %d\n", ret);
return ret;
}
static struct platform_driver pxa168fb_driver = {
.driver = {
.name = "pxa168-fb",
.owner = THIS_MODULE,
},
.probe = pxa168fb_probe,
};
static int __devinit pxa168fb_init(void)
{
return platform_driver_register(&pxa168fb_driver);
}
module_init(pxa168fb_init);
MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com> "
"Green Wan <gwan@marvell.com>");
MODULE_DESCRIPTION("Framebuffer driver for PXA168/910");
MODULE_LICENSE("GPL");
#ifndef __PXA168FB_H__
#define __PXA168FB_H__
/* ------------< LCD register >------------ */
/* Video Frame 0&1 start address registers */
#define LCD_SPU_DMA_START_ADDR_Y0 0x00C0
#define LCD_SPU_DMA_START_ADDR_U0 0x00C4
#define LCD_SPU_DMA_START_ADDR_V0 0x00C8
#define LCD_CFG_DMA_START_ADDR_0 0x00CC /* Cmd address */
#define LCD_SPU_DMA_START_ADDR_Y1 0x00D0
#define LCD_SPU_DMA_START_ADDR_U1 0x00D4
#define LCD_SPU_DMA_START_ADDR_V1 0x00D8
#define LCD_CFG_DMA_START_ADDR_1 0x00DC /* Cmd address */
/* YC & UV Pitch */
#define LCD_SPU_DMA_PITCH_YC 0x00E0
#define SPU_DMA_PITCH_C(c) ((c) << 16)
#define SPU_DMA_PITCH_Y(y) (y)
#define LCD_SPU_DMA_PITCH_UV 0x00E4
#define SPU_DMA_PITCH_V(v) ((v) << 16)
#define SPU_DMA_PITCH_U(u) (u)
/* Video Starting Point on Screen Register */
#define LCD_SPUT_DMA_OVSA_HPXL_VLN 0x00E8
#define CFG_DMA_OVSA_VLN(y) ((y) << 16) /* 0~0xfff */
#define CFG_DMA_OVSA_HPXL(x) (x) /* 0~0xfff */
/* Video Size Register */
#define LCD_SPU_DMA_HPXL_VLN 0x00EC
#define CFG_DMA_VLN(y) ((y) << 16)
#define CFG_DMA_HPXL(x) (x)
/* Video Size After zooming Register */
#define LCD_SPU_DZM_HPXL_VLN 0x00F0
#define CFG_DZM_VLN(y) ((y) << 16)
#define CFG_DZM_HPXL(x) (x)
/* Graphic Frame 0&1 Starting Address Register */
#define LCD_CFG_GRA_START_ADDR0 0x00F4
#define LCD_CFG_GRA_START_ADDR1 0x00F8
/* Graphic Frame Pitch */
#define LCD_CFG_GRA_PITCH 0x00FC
/* Graphic Starting Point on Screen Register */
#define LCD_SPU_GRA_OVSA_HPXL_VLN 0x0100
#define CFG_GRA_OVSA_VLN(y) ((y) << 16)
#define CFG_GRA_OVSA_HPXL(x) (x)
/* Graphic Size Register */
#define LCD_SPU_GRA_HPXL_VLN 0x0104
#define CFG_GRA_VLN(y) ((y) << 16)
#define CFG_GRA_HPXL(x) (x)
/* Graphic Size after Zooming Register */
#define LCD_SPU_GZM_HPXL_VLN 0x0108
#define CFG_GZM_VLN(y) ((y) << 16)
#define CFG_GZM_HPXL(x) (x)
/* HW Cursor Starting Point on Screen Register */
#define LCD_SPU_HWC_OVSA_HPXL_VLN 0x010C
#define CFG_HWC_OVSA_VLN(y) ((y) << 16)
#define CFG_HWC_OVSA_HPXL(x) (x)
/* HW Cursor Size */
#define LCD_SPU_HWC_HPXL_VLN 0x0110
#define CFG_HWC_VLN(y) ((y) << 16)
#define CFG_HWC_HPXL(x) (x)
/* Total Screen Size Register */
#define LCD_SPUT_V_H_TOTAL 0x0114
#define CFG_V_TOTAL(y) ((y) << 16)
#define CFG_H_TOTAL(x) (x)
/* Total Screen Active Size Register */
#define LCD_SPU_V_H_ACTIVE 0x0118
#define CFG_V_ACTIVE(y) ((y) << 16)
#define CFG_H_ACTIVE(x) (x)
/* Screen H&V Porch Register */
#define LCD_SPU_H_PORCH 0x011C
#define CFG_H_BACK_PORCH(b) ((b) << 16)
#define CFG_H_FRONT_PORCH(f) (f)
#define LCD_SPU_V_PORCH 0x0120
#define CFG_V_BACK_PORCH(b) ((b) << 16)
#define CFG_V_FRONT_PORCH(f) (f)
/* Screen Blank Color Register */
#define LCD_SPU_BLANKCOLOR 0x0124
#define CFG_BLANKCOLOR_MASK 0x00FFFFFF
#define CFG_BLANKCOLOR_R_MASK 0x000000FF
#define CFG_BLANKCOLOR_G_MASK 0x0000FF00
#define CFG_BLANKCOLOR_B_MASK 0x00FF0000
/* HW Cursor Color 1&2 Register */
#define LCD_SPU_ALPHA_COLOR1 0x0128
#define CFG_HWC_COLOR1 0x00FFFFFF
#define CFG_HWC_COLOR1_R(red) ((red) << 16)
#define CFG_HWC_COLOR1_G(green) ((green) << 8)
#define CFG_HWC_COLOR1_B(blue) (blue)
#define CFG_HWC_COLOR1_R_MASK 0x000000FF
#define CFG_HWC_COLOR1_G_MASK 0x0000FF00
#define CFG_HWC_COLOR1_B_MASK 0x00FF0000
#define LCD_SPU_ALPHA_COLOR2 0x012C
#define CFG_HWC_COLOR2 0x00FFFFFF
#define CFG_HWC_COLOR2_R_MASK 0x000000FF
#define CFG_HWC_COLOR2_G_MASK 0x0000FF00
#define CFG_HWC_COLOR2_B_MASK 0x00FF0000
/* Video YUV Color Key Control */
#define LCD_SPU_COLORKEY_Y 0x0130
#define CFG_CKEY_Y2(y2) ((y2) << 24)
#define CFG_CKEY_Y2_MASK 0xFF000000
#define CFG_CKEY_Y1(y1) ((y1) << 16)
#define CFG_CKEY_Y1_MASK 0x00FF0000
#define CFG_CKEY_Y(y) ((y) << 8)
#define CFG_CKEY_Y_MASK 0x0000FF00
#define CFG_ALPHA_Y(y) (y)
#define CFG_ALPHA_Y_MASK 0x000000FF
#define LCD_SPU_COLORKEY_U 0x0134
#define CFG_CKEY_U2(u2) ((u2) << 24)
#define CFG_CKEY_U2_MASK 0xFF000000
#define CFG_CKEY_U1(u1) ((u1) << 16)
#define CFG_CKEY_U1_MASK 0x00FF0000
#define CFG_CKEY_U(u) ((u) << 8)
#define CFG_CKEY_U_MASK 0x0000FF00
#define CFG_ALPHA_U(u) (u)
#define CFG_ALPHA_U_MASK 0x000000FF
#define LCD_SPU_COLORKEY_V 0x0138
#define CFG_CKEY_V2(v2) ((v2) << 24)
#define CFG_CKEY_V2_MASK 0xFF000000
#define CFG_CKEY_V1(v1) ((v1) << 16)
#define CFG_CKEY_V1_MASK 0x00FF0000
#define CFG_CKEY_V(v) ((v) << 8)
#define CFG_CKEY_V_MASK 0x0000FF00
#define CFG_ALPHA_V(v) (v)
#define CFG_ALPHA_V_MASK 0x000000FF
/* SPI Read Data Register */
#define LCD_SPU_SPI_RXDATA 0x0140
/* Smart Panel Read Data Register */
#define LCD_SPU_ISA_RSDATA 0x0144
#define ISA_RXDATA_16BIT_1_DATA_MASK 0x000000FF
#define ISA_RXDATA_16BIT_2_DATA_MASK 0x0000FF00
#define ISA_RXDATA_16BIT_3_DATA_MASK 0x00FF0000
#define ISA_RXDATA_16BIT_4_DATA_MASK 0xFF000000
#define ISA_RXDATA_32BIT_1_DATA_MASK 0x00FFFFFF
/* HWC SRAM Read Data Register */
#define LCD_SPU_HWC_RDDAT 0x0158
/* Gamma Table SRAM Read Data Register */
#define LCD_SPU_GAMMA_RDDAT 0x015c
#define CFG_GAMMA_RDDAT_MASK 0x000000FF
/* Palette Table SRAM Read Data Register */
#define LCD_SPU_PALETTE_RDDAT 0x0160
#define CFG_PALETTE_RDDAT_MASK 0x00FFFFFF
/* I/O Pads Input Read Only Register */
#define LCD_SPU_IOPAD_IN 0x0178
#define CFG_IOPAD_IN_MASK 0x0FFFFFFF
/* Reserved Read Only Registers */
#define LCD_CFG_RDREG5F 0x017C
#define IRE_FRAME_CNT_MASK 0x000000C0
#define IPE_FRAME_CNT_MASK 0x00000030
#define GRA_FRAME_CNT_MASK 0x0000000C /* Graphic */
#define DMA_FRAME_CNT_MASK 0x00000003 /* Video */
/* SPI Control Register. */
#define LCD_SPU_SPI_CTRL 0x0180
#define CFG_SCLKCNT(div) ((div) << 24) /* 0xFF~0x2 */
#define CFG_SCLKCNT_MASK 0xFF000000
#define CFG_RXBITS(rx) ((rx) << 16) /* 0x1F~0x1 */
#define CFG_RXBITS_MASK 0x00FF0000
#define CFG_TXBITS(tx) ((tx) << 8) /* 0x1F~0x1 */
#define CFG_TXBITS_MASK 0x0000FF00
#define CFG_CLKINV(clk) ((clk) << 7)
#define CFG_CLKINV_MASK 0x00000080
#define CFG_KEEPXFER(transfer) ((transfer) << 6)
#define CFG_KEEPXFER_MASK 0x00000040
#define CFG_RXBITSTO0(rx) ((rx) << 5)
#define CFG_RXBITSTO0_MASK 0x00000020
#define CFG_TXBITSTO0(tx) ((tx) << 4)
#define CFG_TXBITSTO0_MASK 0x00000010
#define CFG_SPI_ENA(spi) ((spi) << 3)
#define CFG_SPI_ENA_MASK 0x00000008
#define CFG_SPI_SEL(spi) ((spi) << 2)
#define CFG_SPI_SEL_MASK 0x00000004
#define CFG_SPI_3W4WB(wire) ((wire) << 1)
#define CFG_SPI_3W4WB_MASK 0x00000002
#define CFG_SPI_START(start) (start)
#define CFG_SPI_START_MASK 0x00000001
/* SPI Tx Data Register */
#define LCD_SPU_SPI_TXDATA 0x0184
/*
1. Smart Pannel 8-bit Bus Control Register.
2. AHB Slave Path Data Port Register
*/
#define LCD_SPU_SMPN_CTRL 0x0188
/* DMA Control 0 Register */
#define LCD_SPU_DMA_CTRL0 0x0190
#define CFG_NOBLENDING(nb) ((nb) << 31)
#define CFG_NOBLENDING_MASK 0x80000000
#define CFG_GAMMA_ENA(gn) ((gn) << 30)
#define CFG_GAMMA_ENA_MASK 0x40000000
#define CFG_CBSH_ENA(cn) ((cn) << 29)
#define CFG_CBSH_ENA_MASK 0x20000000
#define CFG_PALETTE_ENA(pn) ((pn) << 28)
#define CFG_PALETTE_ENA_MASK 0x10000000
#define CFG_ARBFAST_ENA(an) ((an) << 27)
#define CFG_ARBFAST_ENA_MASK 0x08000000
#define CFG_HWC_1BITMOD(mode) ((mode) << 26)
#define CFG_HWC_1BITMOD_MASK 0x04000000
#define CFG_HWC_1BITENA(mn) ((mn) << 25)
#define CFG_HWC_1BITENA_MASK 0x02000000
#define CFG_HWC_ENA(cn) ((cn) << 24)
#define CFG_HWC_ENA_MASK 0x01000000
#define CFG_DMAFORMAT(dmaformat) ((dmaformat) << 20)
#define CFG_DMAFORMAT_MASK 0x00F00000
#define CFG_GRAFORMAT(graformat) ((graformat) << 16)
#define CFG_GRAFORMAT_MASK 0x000F0000
/* for graphic part */
#define CFG_GRA_FTOGGLE(toggle) ((toggle) << 15)
#define CFG_GRA_FTOGGLE_MASK 0x00008000
#define CFG_GRA_HSMOOTH(smooth) ((smooth) << 14)
#define CFG_GRA_HSMOOTH_MASK 0x00004000
#define CFG_GRA_TSTMODE(test) ((test) << 13)
#define CFG_GRA_TSTMODE_MASK 0x00002000
#define CFG_GRA_SWAPRB(swap) ((swap) << 12)
#define CFG_GRA_SWAPRB_MASK 0x00001000
#define CFG_GRA_SWAPUV(swap) ((swap) << 11)
#define CFG_GRA_SWAPUV_MASK 0x00000800
#define CFG_GRA_SWAPYU(swap) ((swap) << 10)
#define CFG_GRA_SWAPYU_MASK 0x00000400
#define CFG_YUV2RGB_GRA(cvrt) ((cvrt) << 9)
#define CFG_YUV2RGB_GRA_MASK 0x00000200
#define CFG_GRA_ENA(gra) ((gra) << 8)
#define CFG_GRA_ENA_MASK 0x00000100
/* for video part */
#define CFG_DMA_FTOGGLE(toggle) ((toggle) << 7)
#define CFG_DMA_FTOGGLE_MASK 0x00000080
#define CFG_DMA_HSMOOTH(smooth) ((smooth) << 6)
#define CFG_DMA_HSMOOTH_MASK 0x00000040
#define CFG_DMA_TSTMODE(test) ((test) << 5)
#define CFG_DMA_TSTMODE_MASK 0x00000020
#define CFG_DMA_SWAPRB(swap) ((swap) << 4)
#define CFG_DMA_SWAPRB_MASK 0x00000010
#define CFG_DMA_SWAPUV(swap) ((swap) << 3)
#define CFG_DMA_SWAPUV_MASK 0x00000008
#define CFG_DMA_SWAPYU(swap) ((swap) << 2)
#define CFG_DMA_SWAPYU_MASK 0x00000004
#define CFG_DMA_SWAP_MASK 0x0000001C
#define CFG_YUV2RGB_DMA(cvrt) ((cvrt) << 1)
#define CFG_YUV2RGB_DMA_MASK 0x00000002
#define CFG_DMA_ENA(video) (video)
#define CFG_DMA_ENA_MASK 0x00000001
/* DMA Control 1 Register */
#define LCD_SPU_DMA_CTRL1 0x0194
#define CFG_FRAME_TRIG(trig) ((trig) << 31)
#define CFG_FRAME_TRIG_MASK 0x80000000
#define CFG_VSYNC_TRIG(trig) ((trig) << 28)
#define CFG_VSYNC_TRIG_MASK 0x70000000
#define CFG_VSYNC_INV(inv) ((inv) << 27)
#define CFG_VSYNC_INV_MASK 0x08000000
#define CFG_COLOR_KEY_MODE(cmode) ((cmode) << 24)
#define CFG_COLOR_KEY_MASK 0x07000000
#define CFG_CARRY(carry) ((carry) << 23)
#define CFG_CARRY_MASK 0x00800000
#define CFG_LNBUF_ENA(lnbuf) ((lnbuf) << 22)
#define CFG_LNBUF_ENA_MASK 0x00400000
#define CFG_GATED_ENA(gated) ((gated) << 21)
#define CFG_GATED_ENA_MASK 0x00200000
#define CFG_PWRDN_ENA(power) ((power) << 20)
#define CFG_PWRDN_ENA_MASK 0x00100000
#define CFG_DSCALE(dscale) ((dscale) << 18)
#define CFG_DSCALE_MASK 0x000C0000
#define CFG_ALPHA_MODE(amode) ((amode) << 16)
#define CFG_ALPHA_MODE_MASK 0x00030000
#define CFG_ALPHA(alpha) ((alpha) << 8)
#define CFG_ALPHA_MASK 0x0000FF00
#define CFG_PXLCMD(pxlcmd) (pxlcmd)
#define CFG_PXLCMD_MASK 0x000000FF
/* SRAM Control Register */
#define LCD_SPU_SRAM_CTRL 0x0198
#define CFG_SRAM_INIT_WR_RD(mode) ((mode) << 14)
#define CFG_SRAM_INIT_WR_RD_MASK 0x0000C000
#define CFG_SRAM_ADDR_LCDID(id) ((id) << 8)
#define CFG_SRAM_ADDR_LCDID_MASK 0x00000F00
#define CFG_SRAM_ADDR(addr) (addr)
#define CFG_SRAM_ADDR_MASK 0x000000FF
/* SRAM Write Data Register */
#define LCD_SPU_SRAM_WRDAT 0x019C
/* SRAM RTC/WTC Control Register */
#define LCD_SPU_SRAM_PARA0 0x01A0
/* SRAM Power Down Control Register */
#define LCD_SPU_SRAM_PARA1 0x01A4
#define CFG_CSB_256x32(hwc) ((hwc) << 15) /* HWC */
#define CFG_CSB_256x32_MASK 0x00008000
#define CFG_CSB_256x24(palette) ((palette) << 14) /* Palette */
#define CFG_CSB_256x24_MASK 0x00004000
#define CFG_CSB_256x8(gamma) ((gamma) << 13) /* Gamma */
#define CFG_CSB_256x8_MASK 0x00002000
#define CFG_PDWN256x32(pdwn) ((pdwn) << 7) /* HWC */
#define CFG_PDWN256x32_MASK 0x00000080
#define CFG_PDWN256x24(pdwn) ((pdwn) << 6) /* Palette */
#define CFG_PDWN256x24_MASK 0x00000040
#define CFG_PDWN256x8(pdwn) ((pdwn) << 5) /* Gamma */
#define CFG_PDWN256x8_MASK 0x00000020
#define CFG_PDWN32x32(pdwn) ((pdwn) << 3)
#define CFG_PDWN32x32_MASK 0x00000008
#define CFG_PDWN16x66(pdwn) ((pdwn) << 2)
#define CFG_PDWN16x66_MASK 0x00000004
#define CFG_PDWN32x66(pdwn) ((pdwn) << 1)
#define CFG_PDWN32x66_MASK 0x00000002
#define CFG_PDWN64x66(pdwn) (pdwn)
#define CFG_PDWN64x66_MASK 0x00000001
/* Smart or Dumb Panel Clock Divider */
#define LCD_CFG_SCLK_DIV 0x01A8
#define SCLK_SOURCE_SELECT(src) ((src) << 31)
#define SCLK_SOURCE_SELECT_MASK 0x80000000
#define CLK_FRACDIV(frac) ((frac) << 16)
#define CLK_FRACDIV_MASK 0x0FFF0000
#define CLK_INT_DIV(div) (div)
#define CLK_INT_DIV_MASK 0x0000FFFF
/* Video Contrast Register */
#define LCD_SPU_CONTRAST 0x01AC
#define CFG_BRIGHTNESS(bright) ((bright) << 16)
#define CFG_BRIGHTNESS_MASK 0xFFFF0000
#define CFG_CONTRAST(contrast) (contrast)
#define CFG_CONTRAST_MASK 0x0000FFFF
/* Video Saturation Register */
#define LCD_SPU_SATURATION 0x01B0
#define CFG_C_MULTS(mult) ((mult) << 16)
#define CFG_C_MULTS_MASK 0xFFFF0000
#define CFG_SATURATION(sat) (sat)
#define CFG_SATURATION_MASK 0x0000FFFF
/* Video Hue Adjust Register */
#define LCD_SPU_CBSH_HUE 0x01B4
#define CFG_SIN0(sin0) ((sin0) << 16)
#define CFG_SIN0_MASK 0xFFFF0000
#define CFG_COS0(con0) (con0)
#define CFG_COS0_MASK 0x0000FFFF
/* Dump LCD Panel Control Register */
#define LCD_SPU_DUMB_CTRL 0x01B8
#define CFG_DUMBMODE(mode) ((mode) << 28)
#define CFG_DUMBMODE_MASK 0xF0000000
#define CFG_LCDGPIO_O(data) ((data) << 20)
#define CFG_LCDGPIO_O_MASK 0x0FF00000
#define CFG_LCDGPIO_ENA(gpio) ((gpio) << 12)
#define CFG_LCDGPIO_ENA_MASK 0x000FF000
#define CFG_BIAS_OUT(bias) ((bias) << 8)
#define CFG_BIAS_OUT_MASK 0x00000100
#define CFG_REVERSE_RGB(rRGB) ((rRGB) << 7)
#define CFG_REVERSE_RGB_MASK 0x00000080
#define CFG_INV_COMPBLANK(blank) ((blank) << 6)
#define CFG_INV_COMPBLANK_MASK 0x00000040
#define CFG_INV_COMPSYNC(sync) ((sync) << 5)
#define CFG_INV_COMPSYNC_MASK 0x00000020
#define CFG_INV_HENA(hena) ((hena) << 4)
#define CFG_INV_HENA_MASK 0x00000010
#define CFG_INV_VSYNC(vsync) ((vsync) << 3)
#define CFG_INV_VSYNC_MASK 0x00000008
#define CFG_INV_HSYNC(hsync) ((hsync) << 2)
#define CFG_INV_HSYNC_MASK 0x00000004
#define CFG_INV_PCLK(pclk) ((pclk) << 1)
#define CFG_INV_PCLK_MASK 0x00000002
#define CFG_DUMB_ENA(dumb) (dumb)
#define CFG_DUMB_ENA_MASK 0x00000001
/* LCD I/O Pads Control Register */
#define SPU_IOPAD_CONTROL 0x01BC
#define CFG_GRA_VM_ENA(vm) ((vm) << 15) /* gfx */
#define CFG_GRA_VM_ENA_MASK 0x00008000
#define CFG_DMA_VM_ENA(vm) ((vm) << 13) /* video */
#define CFG_DMA_VM_ENA_MASK 0x00002000
#define CFG_CMD_VM_ENA(vm) ((vm) << 13)
#define CFG_CMD_VM_ENA_MASK 0x00000800
#define CFG_CSC(csc) ((csc) << 8) /* csc */
#define CFG_CSC_MASK 0x00000300
#define CFG_AXICTRL(axi) ((axi) << 4)
#define CFG_AXICTRL_MASK 0x000000F0
#define CFG_IOPADMODE(iopad) (iopad)
#define CFG_IOPADMODE_MASK 0x0000000F
/* LCD Interrupt Control Register */
#define SPU_IRQ_ENA 0x01C0
#define DMA_FRAME_IRQ0_ENA(irq) ((irq) << 31)
#define DMA_FRAME_IRQ0_ENA_MASK 0x80000000
#define DMA_FRAME_IRQ1_ENA(irq) ((irq) << 30)
#define DMA_FRAME_IRQ1_ENA_MASK 0x40000000
#define DMA_FF_UNDERFLOW_ENA(ff) ((ff) << 29)
#define DMA_FF_UNDERFLOW_ENA_MASK 0x20000000
#define GRA_FRAME_IRQ0_ENA(irq) ((irq) << 27)
#define GRA_FRAME_IRQ0_ENA_MASK 0x08000000
#define GRA_FRAME_IRQ1_ENA(irq) ((irq) << 26)
#define GRA_FRAME_IRQ1_ENA_MASK 0x04000000
#define GRA_FF_UNDERFLOW_ENA(ff) ((ff) << 25)
#define GRA_FF_UNDERFLOW_ENA_MASK 0x02000000
#define VSYNC_IRQ_ENA(vsync_irq) ((vsync_irq) << 23)
#define VSYNC_IRQ_ENA_MASK 0x00800000
#define DUMB_FRAMEDONE_ENA(fdone) ((fdone) << 22)
#define DUMB_FRAMEDONE_ENA_MASK 0x00400000
#define TWC_FRAMEDONE_ENA(fdone) ((fdone) << 21)
#define TWC_FRAMEDONE_ENA_MASK 0x00200000
#define HWC_FRAMEDONE_ENA(fdone) ((fdone) << 20)
#define HWC_FRAMEDONE_ENA_MASK 0x00100000
#define SLV_IRQ_ENA(irq) ((irq) << 19)
#define SLV_IRQ_ENA_MASK 0x00080000
#define SPI_IRQ_ENA(irq) ((irq) << 18)
#define SPI_IRQ_ENA_MASK 0x00040000
#define PWRDN_IRQ_ENA(irq) ((irq) << 17)
#define PWRDN_IRQ_ENA_MASK 0x00020000
#define ERR_IRQ_ENA(irq) ((irq) << 16)
#define ERR_IRQ_ENA_MASK 0x00010000
#define CLEAN_SPU_IRQ_ISR(irq) (irq)
#define CLEAN_SPU_IRQ_ISR_MASK 0x0000FFFF
/* LCD Interrupt Status Register */
#define SPU_IRQ_ISR 0x01C4
#define DMA_FRAME_IRQ0(irq) ((irq) << 31)
#define DMA_FRAME_IRQ0_MASK 0x80000000
#define DMA_FRAME_IRQ1(irq) ((irq) << 30)
#define DMA_FRAME_IRQ1_MASK 0x40000000
#define DMA_FF_UNDERFLOW(ff) ((ff) << 29)
#define DMA_FF_UNDERFLOW_MASK 0x20000000
#define GRA_FRAME_IRQ0(irq) ((irq) << 27)
#define GRA_FRAME_IRQ0_MASK 0x08000000
#define GRA_FRAME_IRQ1(irq) ((irq) << 26)
#define GRA_FRAME_IRQ1_MASK 0x04000000
#define GRA_FF_UNDERFLOW(ff) ((ff) << 25)
#define GRA_FF_UNDERFLOW_MASK 0x02000000
#define VSYNC_IRQ(vsync_irq) ((vsync_irq) << 23)
#define VSYNC_IRQ_MASK 0x00800000
#define DUMB_FRAMEDONE(fdone) ((fdone) << 22)
#define DUMB_FRAMEDONE_MASK 0x00400000
#define TWC_FRAMEDONE(fdone) ((fdone) << 21)
#define TWC_FRAMEDONE_MASK 0x00200000
#define HWC_FRAMEDONE(fdone) ((fdone) << 20)
#define HWC_FRAMEDONE_MASK 0x00100000
#define SLV_IRQ(irq) ((irq) << 19)
#define SLV_IRQ_MASK 0x00080000
#define SPI_IRQ(irq) ((irq) << 18)
#define SPI_IRQ_MASK 0x00040000
#define PWRDN_IRQ(irq) ((irq) << 17)
#define PWRDN_IRQ_MASK 0x00020000
#define ERR_IRQ(irq) ((irq) << 16)
#define ERR_IRQ_MASK 0x00010000
/* read-only */
#define DMA_FRAME_IRQ0_LEVEL_MASK 0x00008000
#define DMA_FRAME_IRQ1_LEVEL_MASK 0x00004000
#define DMA_FRAME_CNT_ISR_MASK 0x00003000
#define GRA_FRAME_IRQ0_LEVEL_MASK 0x00000800
#define GRA_FRAME_IRQ1_LEVEL_MASK 0x00000400
#define GRA_FRAME_CNT_ISR_MASK 0x00000300
#define VSYNC_IRQ_LEVEL_MASK 0x00000080
#define DUMB_FRAMEDONE_LEVEL_MASK 0x00000040
#define TWC_FRAMEDONE_LEVEL_MASK 0x00000020
#define HWC_FRAMEDONE_LEVEL_MASK 0x00000010
#define SLV_FF_EMPTY_MASK 0x00000008
#define DMA_FF_ALLEMPTY_MASK 0x00000004
#define GRA_FF_ALLEMPTY_MASK 0x00000002
#define PWRDN_IRQ_LEVEL_MASK 0x00000001
/*
* defined Video Memory Color format for DMA control 0 register
* DMA0 bit[23:20]
*/
#define VMODE_RGB565 0x0
#define VMODE_RGB1555 0x1
#define VMODE_RGB888PACKED 0x2
#define VMODE_RGB888UNPACKED 0x3
#define VMODE_RGBA888 0x4
#define VMODE_YUV422PACKED 0x5
#define VMODE_YUV422PLANAR 0x6
#define VMODE_YUV420PLANAR 0x7
#define VMODE_SMPNCMD 0x8
#define VMODE_PALETTE4BIT 0x9
#define VMODE_PALETTE8BIT 0xa
#define VMODE_RESERVED 0xb
/*
* defined Graphic Memory Color format for DMA control 0 register
* DMA0 bit[19:16]
*/
#define GMODE_RGB565 0x0
#define GMODE_RGB1555 0x1
#define GMODE_RGB888PACKED 0x2
#define GMODE_RGB888UNPACKED 0x3
#define GMODE_RGBA888 0x4
#define GMODE_YUV422PACKED 0x5
#define GMODE_YUV422PLANAR 0x6
#define GMODE_YUV420PLANAR 0x7
#define GMODE_SMPNCMD 0x8
#define GMODE_PALETTE4BIT 0x9
#define GMODE_PALETTE8BIT 0xa
#define GMODE_RESERVED 0xb
/*
* define for DMA control 1 register
*/
#define DMA1_FRAME_TRIG 31 /* bit location */
#define DMA1_VSYNC_MODE 28
#define DMA1_VSYNC_INV 27
#define DMA1_CKEY 24
#define DMA1_CARRY 23
#define DMA1_LNBUF_ENA 22
#define DMA1_GATED_ENA 21
#define DMA1_PWRDN_ENA 20
#define DMA1_DSCALE 18
#define DMA1_ALPHA_MODE 16
#define DMA1_ALPHA 08
#define DMA1_PXLCMD 00
/*
* defined for Configure Dumb Mode
* DUMB LCD Panel bit[31:28]
*/
#define DUMB16_RGB565_0 0x0
#define DUMB16_RGB565_1 0x1
#define DUMB18_RGB666_0 0x2
#define DUMB18_RGB666_1 0x3
#define DUMB12_RGB444_0 0x4
#define DUMB12_RGB444_1 0x5
#define DUMB24_RGB888_0 0x6
#define DUMB_BLANK 0x7
/*
* defined for Configure I/O Pin Allocation Mode
* LCD LCD I/O Pads control register bit[3:0]
*/
#define IOPAD_DUMB24 0x0
#define IOPAD_DUMB18SPI 0x1
#define IOPAD_DUMB18GPIO 0x2
#define IOPAD_DUMB16SPI 0x3
#define IOPAD_DUMB16GPIO 0x4
#define IOPAD_DUMB12 0x5
#define IOPAD_SMART18SPI 0x6
#define IOPAD_SMART16SPI 0x7
#define IOPAD_SMART8BOTH 0x8
#endif /* __PXA168FB_H__ */
/*
* linux/arch/arm/mach-mmp/include/mach/pxa168fb.h
*
* Copyright (C) 2009 Marvell International Ltd.
*
* 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 __ASM_MACH_PXA168FB_H
#define __ASM_MACH_PXA168FB_H
#include <linux/fb.h>
#include <linux/interrupt.h>
/* Dumb interface */
#define PIN_MODE_DUMB_24 0
#define PIN_MODE_DUMB_18_SPI 1
#define PIN_MODE_DUMB_18_GPIO 2
#define PIN_MODE_DUMB_16_SPI 3
#define PIN_MODE_DUMB_16_GPIO 4
#define PIN_MODE_DUMB_12_SPI_GPIO 5
#define PIN_MODE_SMART_18_SPI 6
#define PIN_MODE_SMART_16_SPI 7
#define PIN_MODE_SMART_8_SPI_GPIO 8
/* Dumb interface pin allocation */
#define DUMB_MODE_RGB565 0
#define DUMB_MODE_RGB565_UPPER 1
#define DUMB_MODE_RGB666 2
#define DUMB_MODE_RGB666_UPPER 3
#define DUMB_MODE_RGB444 4
#define DUMB_MODE_RGB444_UPPER 5
#define DUMB_MODE_RGB888 6
/* default fb buffer size WVGA-32bits */
#define DEFAULT_FB_SIZE (800 * 480 * 4)
/*
* Buffer pixel format
* bit0 is for rb swap.
* bit12 is for Y UorV swap
*/
#define PIX_FMT_RGB565 0
#define PIX_FMT_BGR565 1
#define PIX_FMT_RGB1555 2
#define PIX_FMT_BGR1555 3
#define PIX_FMT_RGB888PACK 4
#define PIX_FMT_BGR888PACK 5
#define PIX_FMT_RGB888UNPACK 6
#define PIX_FMT_BGR888UNPACK 7
#define PIX_FMT_RGBA888 8
#define PIX_FMT_BGRA888 9
#define PIX_FMT_YUV422PACK 10
#define PIX_FMT_YVU422PACK 11
#define PIX_FMT_YUV422PLANAR 12
#define PIX_FMT_YVU422PLANAR 13
#define PIX_FMT_YUV420PLANAR 14
#define PIX_FMT_YVU420PLANAR 15
#define PIX_FMT_PSEUDOCOLOR 20
#define PIX_FMT_UYVY422PACK (0x1000|PIX_FMT_YUV422PACK)
/*
* PXA LCD controller private state.
*/
struct pxa168fb_info {
struct device *dev;
struct clk *clk;
struct fb_info *info;
void __iomem *reg_base;
dma_addr_t fb_start_dma;
u32 pseudo_palette[16];
int pix_fmt;
unsigned is_blanked:1;
unsigned panel_rbswap:1;
unsigned active:1;
};
/*
* PXA fb machine information
*/
struct pxa168fb_mach_info {
char id[16];
int num_modes;
struct fb_videomode *modes;
/*
* Pix_fmt
*/
unsigned pix_fmt;
/*
* I/O pin allocation.
*/
unsigned io_pin_allocation_mode:4;
/*
* Dumb panel -- assignment of R/G/B component info to the 24
* available external data lanes.
*/
unsigned dumb_mode:4;
unsigned panel_rgb_reverse_lanes:1;
/*
* Dumb panel -- GPIO output data.
*/
unsigned gpio_output_mask:8;
unsigned gpio_output_data:8;
/*
* Dumb panel -- configurable output signal polarity.
*/
unsigned invert_composite_blank:1;
unsigned invert_pix_val_ena:1;
unsigned invert_pixclock:1;
unsigned invert_vsync:1;
unsigned invert_hsync:1;
unsigned panel_rbswap:1;
unsigned active:1;
unsigned enable_lcd:1;
};
#endif /* __ASM_MACH_PXA168FB_H */
......@@ -98,13 +98,14 @@ config SND_PXA2XX_SOC_EM_X270
CompuLab EM-x270.
config SND_PXA2XX_SOC_PALM27X
bool "SoC Audio support for Palm T|X, T5 and LifeDrive"
depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || MACH_PALMT5)
bool "SoC Audio support for Palm T|X, T5, E2 and LifeDrive"
depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || \
MACH_PALMT5 || MACH_PALMTE2)
select SND_PXA2XX_SOC_AC97
select SND_SOC_WM9712
help
Say Y if you want to add support for SoC audio on
Palm T|X, T5 or LifeDrive handheld computer.
Palm T|X, T5, E2 or LifeDrive handheld computer.
config SND_SOC_ZYLONITE
tristate "SoC Audio support for Marvell Zylonite"
......
......@@ -205,7 +205,7 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
int ret;
if (!(machine_is_palmtx() || machine_is_palmt5() ||
machine_is_palmld()))
machine_is_palmld() || machine_is_palmte2()))
return -ENODEV;
if (pdev->dev.platform_data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment