Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
ba71e172
Commit
ba71e172
authored
Dec 06, 2009
by
Russell King
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-lak' of
git://git.linuxtogo.org/home/thesing/collie
into sa1100
parents
729fae44
9823b2d0
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
649 additions
and
63 deletions
+649
-63
arch/arm/mach-sa1100/collie.c
arch/arm/mach-sa1100/collie.c
+74
-5
arch/arm/mach-sa1100/include/mach/collie.h
arch/arm/mach-sa1100/include/mach/collie.h
+44
-33
arch/arm/mach-sa1100/include/mach/gpio.h
arch/arm/mach-sa1100/include/mach/gpio.h
+4
-15
arch/arm/mach-sa1100/include/mach/mcp.h
arch/arm/mach-sa1100/include/mach/mcp.h
+1
-0
drivers/leds/leds-locomo.c
drivers/leds/leds-locomo.c
+1
-1
drivers/mfd/mcp-core.c
drivers/mfd/mcp-core.c
+1
-1
drivers/mfd/mcp-sa11x0.c
drivers/mfd/mcp-sa11x0.c
+2
-1
drivers/mfd/ucb1x00-assabet.c
drivers/mfd/ucb1x00-assabet.c
+1
-1
drivers/mfd/ucb1x00-core.c
drivers/mfd/ucb1x00-core.c
+86
-3
drivers/mfd/ucb1x00-ts.c
drivers/mfd/ucb1x00-ts.c
+1
-1
drivers/power/Kconfig
drivers/power/Kconfig
+7
-0
drivers/power/Makefile
drivers/power/Makefile
+1
-0
drivers/power/collie_battery.c
drivers/power/collie_battery.c
+418
-0
include/linux/mfd/mcp.h
include/linux/mfd/mcp.h
+3
-0
include/linux/mfd/ucb1x00.h
include/linux/mfd/ucb1x00.h
+5
-2
No files found.
arch/arm/mach-sa1100/collie.c
View file @
ba71e172
...
...
@@ -26,6 +26,7 @@
#include <linux/mtd/partitions.h>
#include <linux/timer.h>
#include <linux/gpio.h>
#include <linux/pda_power.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -56,6 +57,7 @@ static struct resource collie_scoop_resources[] = {
static
struct
scoop_config
collie_scoop_setup
=
{
.
io_dir
=
COLLIE_SCOOP_IO_DIR
,
.
io_out
=
COLLIE_SCOOP_IO_OUT
,
.
gpio_base
=
COLLIE_SCOOP_GPIO_BASE
,
};
struct
platform_device
colliescoop_device
=
{
...
...
@@ -85,6 +87,70 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
static
struct
mcp_plat_data
collie_mcp_data
=
{
.
mccr0
=
MCCR0_ADM
|
MCCR0_ExtClk
,
.
sclk_rate
=
9216000
,
.
gpio_base
=
COLLIE_TC35143_GPIO_BASE
,
};
/*
* Collie AC IN
*/
static
int
collie_power_init
(
struct
device
*
dev
)
{
int
ret
=
gpio_request
(
COLLIE_GPIO_AC_IN
,
"ac in"
);
if
(
ret
)
goto
err_gpio_req
;
ret
=
gpio_direction_input
(
COLLIE_GPIO_AC_IN
);
if
(
ret
)
goto
err_gpio_in
;
return
0
;
err_gpio_in:
gpio_free
(
COLLIE_GPIO_AC_IN
);
err_gpio_req:
return
ret
;
}
static
void
collie_power_exit
(
struct
device
*
dev
)
{
gpio_free
(
COLLIE_GPIO_AC_IN
);
}
static
int
collie_power_ac_online
(
void
)
{
return
gpio_get_value
(
COLLIE_GPIO_AC_IN
)
==
2
;
}
static
char
*
collie_ac_supplied_to
[]
=
{
"main-battery"
,
"backup-battery"
,
};
static
struct
pda_power_pdata
collie_power_data
=
{
.
init
=
collie_power_init
,
.
is_ac_online
=
collie_power_ac_online
,
.
exit
=
collie_power_exit
,
.
supplied_to
=
collie_ac_supplied_to
,
.
num_supplicants
=
ARRAY_SIZE
(
collie_ac_supplied_to
),
};
static
struct
resource
collie_power_resource
[]
=
{
{
.
name
=
"ac"
,
.
start
=
gpio_to_irq
(
COLLIE_GPIO_AC_IN
),
.
end
=
gpio_to_irq
(
COLLIE_GPIO_AC_IN
),
.
flags
=
IORESOURCE_IRQ
|
IORESOURCE_IRQ_HIGHEDGE
|
IORESOURCE_IRQ_LOWEDGE
,
},
};
static
struct
platform_device
collie_power_device
=
{
.
name
=
"pda-power"
,
.
id
=
-
1
,
.
dev
.
platform_data
=
&
collie_power_data
,
.
resource
=
collie_power_resource
,
.
num_resources
=
ARRAY_SIZE
(
collie_power_resource
),
};
#ifdef CONFIG_SHARP_LOCOMO
...
...
@@ -178,6 +244,7 @@ struct platform_device collie_locomo_device = {
static
struct
platform_device
*
devices
[]
__initdata
=
{
&
collie_locomo_device
,
&
colliescoop_device
,
&
collie_power_device
,
};
static
struct
mtd_partition
collie_partitions
[]
=
{
...
...
@@ -248,22 +315,24 @@ static void __init collie_init(void)
GPDR
=
GPIO_LDD8
|
GPIO_LDD9
|
GPIO_LDD10
|
GPIO_LDD11
|
GPIO_LDD12
|
GPIO_LDD13
|
GPIO_LDD14
|
GPIO_LDD15
|
GPIO_SSP_TXD
|
GPIO_SSP_SCLK
|
GPIO_SSP_SFRM
|
GPIO_SDLC_SCLK
|
COLLIE_GPIO_UCB1x00_RESET
|
COLLIE_GPIO_nMIC_ON
|
COLLIE_GPIO_nREMOCON_ON
|
GPIO_32_768kHz
;
_COLLIE_GPIO_UCB1x00_RESET
|
_
COLLIE_GPIO_nMIC_ON
|
_
COLLIE_GPIO_nREMOCON_ON
|
GPIO_32_768kHz
;
PPDR
=
PPC_LDD0
|
PPC_LDD1
|
PPC_LDD2
|
PPC_LDD3
|
PPC_LDD4
|
PPC_LDD5
|
PPC_LDD6
|
PPC_LDD7
|
PPC_L_PCLK
|
PPC_L_LCLK
|
PPC_L_FCLK
|
PPC_L_BIAS
|
PPC_TXD1
|
PPC_TXD2
|
PPC_TXD3
|
PPC_TXD4
|
PPC_SCLK
|
PPC_SFRM
;
PWER
=
COLLIE_GPIO_AC_IN
|
COLLIE_GPIO_CO
|
COLLIE_GPIO_ON_KEY
|
COLLIE_GPIO_WAKEUP
|
COLLIE_GPIO_nREMOCON_INT
|
PWER_RTC
;
PWER
=
_COLLIE_GPIO_AC_IN
|
_COLLIE_GPIO_CO
|
_
COLLIE_GPIO_ON_KEY
|
_COLLIE_GPIO_WAKEUP
|
_
COLLIE_GPIO_nREMOCON_INT
|
PWER_RTC
;
PGSR
=
COLLIE_GPIO_nREMOCON_ON
;
PGSR
=
_
COLLIE_GPIO_nREMOCON_ON
;
PSDR
=
PPC_RXD1
|
PPC_RXD2
|
PPC_RXD3
|
PPC_RXD4
;
PCFR
=
PCFR_OPDE
;
GPSR
|=
_COLLIE_GPIO_UCB1x00_RESET
;
platform_scoop_config
=
&
collie_pcmcia_config
;
...
...
arch/arm/mach-sa1100/include/mach/collie.h
View file @
ba71e172
...
...
@@ -25,29 +25,39 @@
#define COLLIE_GPIO_VPEN (COLLIE_SCOOP_GPIO_BASE + 7)
#define COLLIE_SCP_LB_VOL_CHG SCOOP_GPCR_PA19
#define COLLIE_SCOOP_IO_DIR (
COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
#define COLLIE_SCOOP_IO_DIR (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
COLLIE_SCP_LB_VOL_CHG
)
#define COLLIE_SCOOP_IO_OUT (
COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R
)
COLLIE_SCP_LB_VOL_CHG)
#define COLLIE_SCOOP_IO_OUT (
COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R
)
/* GPIOs for
which the generic definition doesn't say much
*/
/* GPIOs for
gpiolib
*/
#define COLLIE_GPIO_ON_KEY
GPIO_GPIO
(0)
#define COLLIE_GPIO_AC_IN
GPIO_GPIO
(1)
#define COLLIE_GPIO_SDIO_INT
GPIO_GPIO
(11)
#define COLLIE_GPIO_CF_IRQ
GPIO_GPIO
(14)
#define COLLIE_GPIO_nREMOCON_INT
GPIO_GPIO
(15)
#define COLLIE_GPIO_UCB1x00_RESET
GPIO_GPIO
(16)
#define COLLIE_GPIO_nMIC_ON
GPIO_GPIO
(17)
#define COLLIE_GPIO_nREMOCON_ON
GPIO_GPIO
(18)
#define COLLIE_GPIO_CO
GPIO_GPIO
(20)
#define COLLIE_GPIO_MCP_CLK
GPIO_GPIO
(21)
#define COLLIE_GPIO_CF_CD
GPIO_GPIO
(22)
#define COLLIE_GPIO_UCB1x00_IRQ
GPIO_GPIO
(23)
#define COLLIE_GPIO_WAKEUP
GPIO_GPIO
(24)
#define COLLIE_GPIO_GA_INT
GPIO_GPIO
(25)
#define COLLIE_GPIO_MAIN_BAT_LOW
GPIO_GPIO
(26)
#define COLLIE_GPIO_ON_KEY (0)
#define COLLIE_GPIO_AC_IN (1)
#define COLLIE_GPIO_SDIO_INT (11)
#define COLLIE_GPIO_CF_IRQ (14)
#define COLLIE_GPIO_nREMOCON_INT (15)
#define COLLIE_GPIO_UCB1x00_RESET (16)
#define COLLIE_GPIO_nMIC_ON (17)
#define COLLIE_GPIO_nREMOCON_ON (18)
#define COLLIE_GPIO_CO (20)
#define COLLIE_GPIO_MCP_CLK (21)
#define COLLIE_GPIO_CF_CD (22)
#define COLLIE_GPIO_UCB1x00_IRQ (23)
#define COLLIE_GPIO_WAKEUP (24)
#define COLLIE_GPIO_GA_INT (25)
#define COLLIE_GPIO_MAIN_BAT_LOW (26)
/* GPIO definitions for direct register access */
#define _COLLIE_GPIO_ON_KEY GPIO_GPIO(0)
#define _COLLIE_GPIO_AC_IN GPIO_GPIO(1)
#define _COLLIE_GPIO_nREMOCON_INT GPIO_GPIO(15)
#define _COLLIE_GPIO_UCB1x00_RESET GPIO_GPIO(16)
#define _COLLIE_GPIO_nMIC_ON GPIO_GPIO(17)
#define _COLLIE_GPIO_nREMOCON_ON GPIO_GPIO(18)
#define _COLLIE_GPIO_CO GPIO_GPIO(20)
#define _COLLIE_GPIO_WAKEUP GPIO_GPIO(24)
/* Interrupts */
#define COLLIE_IRQ_GPIO_ON_KEY IRQ_GPIO0
...
...
@@ -70,19 +80,20 @@
#define COLLIE_LCM_IRQ_GPIO_nSD_WP IRQ_LOCOMO_GPIO14
/* GPIO's on the TC35143AF (Toshiba Analog Frontend) */
#define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0
/* GPIO0=Version */
#define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1
/* GPIO1=TBL_CHK */
#define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2
/* GPIO2=VPNE_ON */
#define COLLIE_TC35143_GPIO_IR_ON UCB_IO_3
/* GPIO3=IR_ON */
#define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4
/* GPIO4=AMP_ON */
#define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5
/* GPIO5=Version */
#define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5
/* GPIO5=fs 8k LPF */
#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
/* GPIO6=BUZZER BIAS */
#define COLLIE_TC35143_GPIO_MBAT_ON UCB_IO_7
/* GPIO7=MBAT_ON */
#define COLLIE_TC35143_GPIO_BBAT_ON UCB_IO_8
/* GPIO8=BBAT_ON */
#define COLLIE_TC35143_GPIO_TMP_ON UCB_IO_9
/* GPIO9=TMP_ON */
#define COLLIE_TC35143_GPIO_IN ( UCB_IO_0 | UCB_IO_2 | UCB_IO_5 )
#define COLLIE_TC35143_GPIO_OUT ( UCB_IO_1 | UCB_IO_3 | UCB_IO_4 | UCB_IO_6 | \
UCB_IO_7 | UCB_IO_8 | UCB_IO_9 )
#define COLLIE_TC35143_GPIO_BASE (GPIO_MAX + 13)
#define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0
#define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1
#define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2
#define COLLIE_TC35143_GPIO_IR_ON UCB_IO_3
#define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4
#define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5
#define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5
#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
#define COLLIE_GPIO_MBAT_ON (COLLIE_TC35143_GPIO_BASE + 7)
#define COLLIE_GPIO_BBAT_ON (COLLIE_TC35143_GPIO_BASE + 8)
#define COLLIE_GPIO_TMP_ON (COLLIE_TC35143_GPIO_BASE + 9)
#define COLLIE_TC35143_GPIO_IN (UCB_IO_0 | UCB_IO_2 | UCB_IO_5)
#define COLLIE_TC35143_GPIO_OUT (UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
| UCB_IO_6)
#endif
arch/arm/mach-sa1100/include/mach/gpio.h
View file @
ba71e172
...
...
@@ -49,20 +49,9 @@ static inline void gpio_set_value(unsigned gpio, int value)
#define gpio_cansleep __gpio_cansleep
static
inline
unsigned
gpio_to_irq
(
unsigned
gpio
)
{
if
(
gpio
<
11
)
return
IRQ_GPIO0
+
gpio
;
else
return
IRQ_GPIO11
-
11
+
gpio
;
}
static
inline
unsigned
irq_to_gpio
(
unsigned
irq
)
{
if
(
irq
<
IRQ_GPIO11_27
)
return
irq
-
IRQ_GPIO0
;
else
return
irq
-
IRQ_GPIO11
+
11
;
}
#define gpio_to_irq(gpio) ((gpio < 11) ? (IRQ_GPIO0 + gpio) : \
(IRQ_GPIO11 - 11 + gpio))
#define irq_to_gpio(irq) ((irq < IRQ_GPIO11_27) ? (irq - IRQ_GPIO0) : \
(irq - IRQ_GPIO11 + 11))
#endif
arch/arm/mach-sa1100/include/mach/mcp.h
View file @
ba71e172
...
...
@@ -16,6 +16,7 @@ struct mcp_plat_data {
u32
mccr0
;
u32
mccr1
;
unsigned
int
sclk_rate
;
int
gpio_base
;
};
#endif
drivers/leds/leds-locomo.c
View file @
ba71e172
...
...
@@ -44,7 +44,7 @@ static void locomoled_brightness_set1(struct led_classdev *led_cdev,
static
struct
led_classdev
locomo_led0
=
{
.
name
=
"locomo:amber:charge"
,
.
default_trigger
=
"
sharpsl-charge
"
,
.
default_trigger
=
"
main-battery-charging
"
,
.
brightness_set
=
locomoled_brightness_set0
,
};
...
...
drivers/mfd/mcp-core.c
View file @
ba71e172
...
...
@@ -17,11 +17,11 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/mfd/mcp.h>
#include <mach/dma.h>
#include <asm/system.h>
#include "mcp.h"
#define to_mcp(d) container_of(d, struct mcp, attached_device)
#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
...
...
drivers/mfd/mcp-sa11x0.c
View file @
ba71e172
...
...
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/mfd/mcp.h>
#include <mach/dma.h>
#include <mach/hardware.h>
...
...
@@ -28,7 +29,6 @@
#include <mach/assabet.h>
#include "mcp.h"
struct
mcp_sa11x0
{
u32
mccr0
;
...
...
@@ -163,6 +163,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
mcp
->
dma_audio_wr
=
DMA_Ser4MCP0Wr
;
mcp
->
dma_telco_rd
=
DMA_Ser4MCP1Rd
;
mcp
->
dma_telco_wr
=
DMA_Ser4MCP1Wr
;
mcp
->
gpio_base
=
data
->
gpio_base
;
platform_set_drvdata
(
pdev
,
mcp
);
...
...
drivers/mfd/ucb1x00-assabet.c
View file @
ba71e172
...
...
@@ -14,10 +14,10 @@
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/device.h>
#include <linux/mfd/ucb1x00.h>
#include <mach/dma.h>
#include "ucb1x00.h"
#define UCB1X00_ATTR(name,input)\
static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
...
...
drivers/mfd/ucb1x00-core.c
View file @
ba71e172
...
...
@@ -25,12 +25,12 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/gpio.h>
#include <mach/dma.h>
#include <mach/hardware.h>
#include "ucb1x00.h"
static
DEFINE_MUTEX
(
ucb1x00_mutex
);
static
LIST_HEAD
(
ucb1x00_drivers
);
static
LIST_HEAD
(
ucb1x00_devices
);
...
...
@@ -108,6 +108,60 @@ unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
return
ucb1x00_reg_read
(
ucb
,
UCB_IO_DATA
);
}
static
void
ucb1x00_gpio_set
(
struct
gpio_chip
*
chip
,
unsigned
offset
,
int
value
)
{
struct
ucb1x00
*
ucb
=
container_of
(
chip
,
struct
ucb1x00
,
gpio
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
ucb
->
io_lock
,
flags
);
if
(
value
)
ucb
->
io_out
|=
1
<<
offset
;
else
ucb
->
io_out
&=
~
(
1
<<
offset
);
ucb1x00_reg_write
(
ucb
,
UCB_IO_DATA
,
ucb
->
io_out
);
spin_unlock_irqrestore
(
&
ucb
->
io_lock
,
flags
);
}
static
int
ucb1x00_gpio_get
(
struct
gpio_chip
*
chip
,
unsigned
offset
)
{
struct
ucb1x00
*
ucb
=
container_of
(
chip
,
struct
ucb1x00
,
gpio
);
return
ucb1x00_reg_read
(
ucb
,
UCB_IO_DATA
)
&
(
1
<<
offset
);
}
static
int
ucb1x00_gpio_direction_input
(
struct
gpio_chip
*
chip
,
unsigned
offset
)
{
struct
ucb1x00
*
ucb
=
container_of
(
chip
,
struct
ucb1x00
,
gpio
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
ucb
->
io_lock
,
flags
);
ucb
->
io_dir
&=
~
(
1
<<
offset
);
ucb1x00_reg_write
(
ucb
,
UCB_IO_DIR
,
ucb
->
io_dir
);
spin_unlock_irqrestore
(
&
ucb
->
io_lock
,
flags
);
return
0
;
}
static
int
ucb1x00_gpio_direction_output
(
struct
gpio_chip
*
chip
,
unsigned
offset
,
int
value
)
{
struct
ucb1x00
*
ucb
=
container_of
(
chip
,
struct
ucb1x00
,
gpio
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
ucb
->
io_lock
,
flags
);
ucb
->
io_dir
|=
(
1
<<
offset
);
ucb1x00_reg_write
(
ucb
,
UCB_IO_DIR
,
ucb
->
io_dir
);
if
(
value
)
ucb
->
io_out
|=
1
<<
offset
;
else
ucb
->
io_out
&=
~
(
1
<<
offset
);
ucb1x00_reg_write
(
ucb
,
UCB_IO_DATA
,
ucb
->
io_out
);
spin_unlock_irqrestore
(
&
ucb
->
io_lock
,
flags
);
return
0
;
}
/*
* UCB1300 data sheet says we must:
* 1. enable ADC => 5us (including reference startup time)
...
...
@@ -476,6 +530,7 @@ static int ucb1x00_probe(struct mcp *mcp)
struct
ucb1x00_driver
*
drv
;
unsigned
int
id
;
int
ret
=
-
ENODEV
;
int
temp
;
mcp_enable
(
mcp
);
id
=
mcp_reg_read
(
mcp
,
UCB_ID
);
...
...
@@ -508,12 +563,27 @@ static int ucb1x00_probe(struct mcp *mcp)
goto
err_free
;
}
ucb
->
gpio
.
base
=
-
1
;
if
(
mcp
->
gpio_base
!=
0
)
{
ucb
->
gpio
.
label
=
dev_name
(
&
ucb
->
dev
);
ucb
->
gpio
.
base
=
mcp
->
gpio_base
;
ucb
->
gpio
.
ngpio
=
10
;
ucb
->
gpio
.
set
=
ucb1x00_gpio_set
;
ucb
->
gpio
.
get
=
ucb1x00_gpio_get
;
ucb
->
gpio
.
direction_input
=
ucb1x00_gpio_direction_input
;
ucb
->
gpio
.
direction_output
=
ucb1x00_gpio_direction_output
;
ret
=
gpiochip_add
(
&
ucb
->
gpio
);
if
(
ret
)
goto
err_free
;
}
else
dev_info
(
&
ucb
->
dev
,
"gpio_base not set so no gpiolib support"
);
ret
=
request_irq
(
ucb
->
irq
,
ucb1x00_irq
,
IRQF_TRIGGER_RISING
,
"UCB1x00"
,
ucb
);
if
(
ret
)
{
printk
(
KERN_ERR
"ucb1x00: unable to grab irq%d: %d
\n
"
,
ucb
->
irq
,
ret
);
goto
err_
free
;
goto
err_
gpio
;
}
mcp_set_drvdata
(
mcp
,
ucb
);
...
...
@@ -522,6 +592,7 @@ static int ucb1x00_probe(struct mcp *mcp)
if
(
ret
)
goto
err_irq
;
INIT_LIST_HEAD
(
&
ucb
->
devs
);
mutex_lock
(
&
ucb1x00_mutex
);
list_add
(
&
ucb
->
node
,
&
ucb1x00_devices
);
...
...
@@ -529,10 +600,14 @@ static int ucb1x00_probe(struct mcp *mcp)
ucb1x00_add_dev
(
ucb
,
drv
);
}
mutex_unlock
(
&
ucb1x00_mutex
);
goto
out
;
err_irq:
free_irq
(
ucb
->
irq
,
ucb
);
err_gpio:
if
(
ucb
->
gpio
.
base
!=
-
1
)
temp
=
gpiochip_remove
(
&
ucb
->
gpio
);
err_free:
kfree
(
ucb
);
err_disable:
...
...
@@ -545,6 +620,7 @@ static void ucb1x00_remove(struct mcp *mcp)
{
struct
ucb1x00
*
ucb
=
mcp_get_drvdata
(
mcp
);
struct
list_head
*
l
,
*
n
;
int
ret
;
mutex_lock
(
&
ucb1x00_mutex
);
list_del
(
&
ucb
->
node
);
...
...
@@ -554,6 +630,12 @@ static void ucb1x00_remove(struct mcp *mcp)
}
mutex_unlock
(
&
ucb1x00_mutex
);
if
(
ucb
->
gpio
.
base
!=
-
1
)
{
ret
=
gpiochip_remove
(
&
ucb
->
gpio
);
if
(
ret
)
dev_err
(
&
ucb
->
dev
,
"Can't remove gpio chip: %d
\n
"
,
ret
);
}
free_irq
(
ucb
->
irq
,
ucb
);
device_unregister
(
&
ucb
->
dev
);
}
...
...
@@ -604,6 +686,7 @@ static int ucb1x00_resume(struct mcp *mcp)
struct
ucb1x00
*
ucb
=
mcp_get_drvdata
(
mcp
);
struct
ucb1x00_dev
*
dev
;
ucb1x00_reg_write
(
ucb
,
UCB_IO_DIR
,
ucb
->
io_dir
);
mutex_lock
(
&
ucb1x00_mutex
);
list_for_each_entry
(
dev
,
&
ucb
->
devs
,
dev_node
)
{
if
(
dev
->
drv
->
resume
)
...
...
drivers/mfd/ucb1x00-ts.c
View file @
ba71e172
...
...
@@ -30,12 +30,12 @@
#include <linux/freezer.h>
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/mfd/ucb1x00.h>
#include <mach/dma.h>
#include <mach/collie.h>
#include <asm/mach-types.h>
#include "ucb1x00.h"
struct
ucb1x00_ts
{
...
...
drivers/power/Kconfig
View file @
ba71e172
...
...
@@ -77,6 +77,13 @@ config BATTERY_TOSA
Say Y to enable support for the battery on the Sharp Zaurus
SL-6000 (tosa) models.
config BATTERY_COLLIE
tristate "Sharp SL-5500 (collie) battery"
depends on SA1100_COLLIE && MCP_UCB1200
help
Say Y to enable support for the battery on the Sharp Zaurus
SL-5500 (collie) models.
config BATTERY_WM97XX
bool "WM97xx generic battery driver"
depends on TOUCHSCREEN_WM97XX=y
...
...
drivers/power/Makefile
View file @
ba71e172
...
...
@@ -24,6 +24,7 @@ obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o
obj-$(CONFIG_BATTERY_PMU)
+=
pmu_battery.o
obj-$(CONFIG_BATTERY_OLPC)
+=
olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA)
+=
tosa_battery.o
obj-$(CONFIG_BATTERY_COLLIE)
+=
collie_battery.o
obj-$(CONFIG_BATTERY_WM97XX)
+=
wm97xx_battery.o
obj-$(CONFIG_BATTERY_BQ27x00)
+=
bq27x00_battery.o
obj-$(CONFIG_BATTERY_DA9030)
+=
da9030_battery.o
...
...
drivers/power/collie_battery.c
0 → 100644
View file @
ba71e172
/*
* Battery and Power Management code for the Sharp SL-5x00
*
* Copyright (C) 2009 Thomas Kunze
*
* based on tosa_battery.c
*
* 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/module.h>
#include <linux/power_supply.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/mfd/ucb1x00.h>
#include <asm/mach/sharpsl_param.h>
#include <asm/mach-types.h>
#include <mach/collie.h>
static
DEFINE_MUTEX
(
bat_lock
);
/* protects gpio pins */
static
struct
work_struct
bat_work
;
static
struct
ucb1x00
*
ucb
;
struct
collie_bat
{
int
status
;
struct
power_supply
psy
;
int
full_chrg
;
struct
mutex
work_lock
;
/* protects data */
bool
(
*
is_present
)(
struct
collie_bat
*
bat
);
int
gpio_full
;
int
gpio_charge_on
;
int
technology
;
int
gpio_bat
;
int
adc_bat
;
int
adc_bat_divider
;
int
bat_max
;
int
bat_min
;
int
gpio_temp
;
int
adc_temp
;
int
adc_temp_divider
;
};
static
struct
collie_bat
collie_bat_main
;
static
unsigned
long
collie_read_bat
(
struct
collie_bat
*
bat
)
{
unsigned
long
value
=
0
;
if
(
bat
->
gpio_bat
<
0
||
bat
->
adc_bat
<
0
)
return
0
;
mutex_lock
(
&
bat_lock
);
gpio_set_value
(
bat
->
gpio_bat
,
1
);
msleep
(
5
);
ucb1x00_adc_enable
(
ucb
);
value
=
ucb1x00_adc_read
(
ucb
,
bat
->
adc_bat
,
UCB_SYNC
);
ucb1x00_adc_disable
(
ucb
);
gpio_set_value
(
bat
->
gpio_bat
,
0
);
mutex_unlock
(
&
bat_lock
);
value
=
value
*
1000000
/
bat
->
adc_bat_divider
;
return
value
;
}
static
unsigned
long
collie_read_temp
(
struct
collie_bat
*
bat
)
{
unsigned
long
value
=
0
;
if
(
bat
->
gpio_temp
<
0
||
bat
->
adc_temp
<
0
)
return
0
;
mutex_lock
(
&
bat_lock
);
gpio_set_value
(
bat
->
gpio_temp
,
1
);
msleep
(
5
);
ucb1x00_adc_enable
(
ucb
);
value
=
ucb1x00_adc_read
(
ucb
,
bat
->
adc_temp
,
UCB_SYNC
);
ucb1x00_adc_disable
(
ucb
);
gpio_set_value
(
bat
->
gpio_temp
,
0
);
mutex_unlock
(
&
bat_lock
);
value
=
value
*
10000
/
bat
->
adc_temp_divider
;
return
value
;
}
static
int
collie_bat_get_property
(
struct
power_supply
*
psy
,
enum
power_supply_property
psp
,
union
power_supply_propval
*
val
)
{
int
ret
=
0
;
struct
collie_bat
*
bat
=
container_of
(
psy
,
struct
collie_bat
,
psy
);
if
(
bat
->
is_present
&&
!
bat
->
is_present
(
bat
)
&&
psp
!=
POWER_SUPPLY_PROP_PRESENT
)
{
return
-
ENODEV
;
}
switch
(
psp
)
{
case
POWER_SUPPLY_PROP_STATUS
:
val
->
intval
=
bat
->
status
;
break
;
case
POWER_SUPPLY_PROP_TECHNOLOGY
:
val
->
intval
=
bat
->
technology
;
break
;
case
POWER_SUPPLY_PROP_VOLTAGE_NOW
:
val
->
intval
=
collie_read_bat
(
bat
);
break
;
case
POWER_SUPPLY_PROP_VOLTAGE_MAX
:
if
(
bat
->
full_chrg
==
-
1
)
val
->
intval
=
bat
->
bat_max
;
else
val
->
intval
=
bat
->
full_chrg
;
break
;
case
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN
:
val
->
intval
=
bat
->
bat_max
;
break
;
case
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN
:
val
->
intval
=
bat
->
bat_min
;
break
;
case
POWER_SUPPLY_PROP_TEMP
:
val
->
intval
=
collie_read_temp
(
bat
);
break
;
case
POWER_SUPPLY_PROP_PRESENT
:
val
->
intval
=
bat
->
is_present
?
bat
->
is_present
(
bat
)
:
1
;
break
;
default:
ret
=
-
EINVAL
;
break
;
}
return
ret
;
}
static
void
collie_bat_external_power_changed
(
struct
power_supply
*
psy
)
{
schedule_work
(
&
bat_work
);
}
static
irqreturn_t
collie_bat_gpio_isr
(
int
irq
,
void
*
data
)
{
pr_info
(
"collie_bat_gpio irq: %d
\n
"
,
gpio_get_value
(
irq_to_gpio
(
irq
)));
schedule_work
(
&
bat_work
);
return
IRQ_HANDLED
;
}
static
void
collie_bat_update
(
struct
collie_bat
*
bat
)
{
int
old
;
struct
power_supply
*
psy
=
&
bat
->
psy
;
mutex_lock
(
&
bat
->
work_lock
);
old
=
bat
->
status
;
if
(
bat
->
is_present
&&
!
bat
->
is_present
(
bat
))
{
printk
(
KERN_NOTICE
"%s not present
\n
"
,
psy
->
name
);
bat
->
status
=
POWER_SUPPLY_STATUS_UNKNOWN
;
bat
->
full_chrg
=
-
1
;
}
else
if
(
power_supply_am_i_supplied
(
psy
))
{
if
(
bat
->
status
==
POWER_SUPPLY_STATUS_DISCHARGING
)
{
gpio_set_value
(
bat
->
gpio_charge_on
,
1
);
mdelay
(
15
);
}
if
(
gpio_get_value
(
bat
->
gpio_full
))
{
if
(
old
==
POWER_SUPPLY_STATUS_CHARGING
||
bat
->
full_chrg
==
-
1
)
bat
->
full_chrg
=
collie_read_bat
(
bat
);
gpio_set_value
(
bat
->
gpio_charge_on
,
0
);
bat
->
status
=
POWER_SUPPLY_STATUS_FULL
;
}
else
{
gpio_set_value
(
bat
->
gpio_charge_on
,
1
);
bat
->
status
=
POWER_SUPPLY_STATUS_CHARGING
;
}
}
else
{
gpio_set_value
(
bat
->
gpio_charge_on
,
0
);
bat
->
status
=
POWER_SUPPLY_STATUS_DISCHARGING
;
}
if
(
old
!=
bat
->
status
)
power_supply_changed
(
psy
);
mutex_unlock
(
&
bat
->
work_lock
);
}
static
void
collie_bat_work
(
struct
work_struct
*
work
)
{
collie_bat_update
(
&
collie_bat_main
);
}
static
enum
power_supply_property
collie_bat_main_props
[]
=
{
POWER_SUPPLY_PROP_STATUS
,
POWER_SUPPLY_PROP_TECHNOLOGY
,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN
,
POWER_SUPPLY_PROP_VOLTAGE_NOW
,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN
,
POWER_SUPPLY_PROP_VOLTAGE_MAX
,
POWER_SUPPLY_PROP_PRESENT
,
POWER_SUPPLY_PROP_TEMP
,
};
static
enum
power_supply_property
collie_bat_bu_props
[]
=
{
POWER_SUPPLY_PROP_STATUS
,
POWER_SUPPLY_PROP_TECHNOLOGY
,
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN
,
POWER_SUPPLY_PROP_VOLTAGE_NOW
,
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN
,
POWER_SUPPLY_PROP_VOLTAGE_MAX
,
POWER_SUPPLY_PROP_PRESENT
,
};
static
struct
collie_bat
collie_bat_main
=
{
.
status
=
POWER_SUPPLY_STATUS_DISCHARGING
,
.
full_chrg
=
-
1
,
.
psy
=
{
.
name
=
"main-battery"
,
.
type
=
POWER_SUPPLY_TYPE_BATTERY
,
.
properties
=
collie_bat_main_props
,
.
num_properties
=
ARRAY_SIZE
(
collie_bat_main_props
),
.
get_property
=
collie_bat_get_property
,
.
external_power_changed
=
collie_bat_external_power_changed
,
.
use_for_apm
=
1
,
},
.
gpio_full
=
COLLIE_GPIO_CO
,
.
gpio_charge_on
=
COLLIE_GPIO_CHARGE_ON
,
.
technology
=
POWER_SUPPLY_TECHNOLOGY_LIPO
,
.
gpio_bat
=
COLLIE_GPIO_MBAT_ON
,
.
adc_bat
=
UCB_ADC_INP_AD1
,
.
adc_bat_divider
=
155
,
.
bat_max
=
4310000
,
.
bat_min
=
1551
*
1000000
/
414
,
.
gpio_temp
=
COLLIE_GPIO_TMP_ON
,
.
adc_temp
=
UCB_ADC_INP_AD0
,
.
adc_temp_divider
=
10000
,
};
static
struct
collie_bat
collie_bat_bu
=
{
.
status
=
POWER_SUPPLY_STATUS_UNKNOWN
,
.
full_chrg
=
-
1
,
.
psy
=
{
.
name
=
"backup-battery"
,
.
type
=
POWER_SUPPLY_TYPE_BATTERY
,
.
properties
=
collie_bat_bu_props
,
.
num_properties
=
ARRAY_SIZE
(
collie_bat_bu_props
),
.
get_property
=
collie_bat_get_property
,
.
external_power_changed
=
collie_bat_external_power_changed
,
},
.
gpio_full
=
-
1
,
.
gpio_charge_on
=
-
1
,
.
technology
=
POWER_SUPPLY_TECHNOLOGY_LiMn
,
.
gpio_bat
=
COLLIE_GPIO_BBAT_ON
,
.
adc_bat
=
UCB_ADC_INP_AD1
,
.
adc_bat_divider
=
155
,
.
bat_max
=
3000000
,
.
bat_min
=
1900000
,
.
gpio_temp
=
-
1
,
.
adc_temp
=
-
1
,
.
adc_temp_divider
=
-
1
,
};
static
struct
{
int
gpio
;
char
*
name
;
bool
output
;
int
value
;
}
gpios
[]
=
{
{
COLLIE_GPIO_CO
,
"main battery full"
,
0
,
0
},
{
COLLIE_GPIO_MAIN_BAT_LOW
,
"main battery low"
,
0
,
0
},
{
COLLIE_GPIO_CHARGE_ON
,
"main charge on"
,
1
,
0
},
{
COLLIE_GPIO_MBAT_ON
,
"main battery"
,
1
,
0
},
{
COLLIE_GPIO_TMP_ON
,
"main battery temp"
,
1
,
0
},
{
COLLIE_GPIO_BBAT_ON
,
"backup battery"
,
1
,
0
},
};
#ifdef CONFIG_PM
static
int
collie_bat_suspend
(
struct
ucb1x00_dev
*
dev
,
pm_message_t
state
)
{
/* flush all pending status updates */
flush_scheduled_work
();
return
0
;
}
static
int
collie_bat_resume
(
struct
ucb1x00_dev
*
dev
)
{
/* things may have changed while we were away */
schedule_work
(
&
bat_work
);
return
0
;
}
#else
#define collie_bat_suspend NULL
#define collie_bat_resume NULL
#endif
static
int
__devinit
collie_bat_probe
(
struct
ucb1x00_dev
*
dev
)
{
int
ret
;
int
i
;
if
(
!
machine_is_collie
())
return
-
ENODEV
;
ucb
=
dev
->
ucb
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
gpios
);
i
++
)
{
ret
=
gpio_request
(
gpios
[
i
].
gpio
,
gpios
[
i
].
name
);
if
(
ret
)
{
i
--
;
goto
err_gpio
;
}
if
(
gpios
[
i
].
output
)
ret
=
gpio_direction_output
(
gpios
[
i
].
gpio
,
gpios
[
i
].
value
);
else
ret
=
gpio_direction_input
(
gpios
[
i
].
gpio
);
if
(
ret
)
goto
err_gpio
;
}
mutex_init
(
&
collie_bat_main
.
work_lock
);
INIT_WORK
(
&
bat_work
,
collie_bat_work
);
ret
=
power_supply_register
(
&
dev
->
ucb
->
dev
,
&
collie_bat_main
.
psy
);
if
(
ret
)
goto
err_psy_reg_main
;
ret
=
power_supply_register
(
&
dev
->
ucb
->
dev
,
&
collie_bat_bu
.
psy
);
if
(
ret
)
goto
err_psy_reg_bu
;
ret
=
request_irq
(
gpio_to_irq
(
COLLIE_GPIO_CO
),
collie_bat_gpio_isr
,
IRQF_TRIGGER_RISING
|
IRQF_TRIGGER_FALLING
,
"main full"
,
&
collie_bat_main
);
if
(
!
ret
)
{
schedule_work
(
&
bat_work
);
return
0
;
}
power_supply_unregister
(
&
collie_bat_bu
.
psy
);
err_psy_reg_bu:
power_supply_unregister
(
&
collie_bat_main
.
psy
);
err_psy_reg_main:
/* see comment in collie_bat_remove */
flush_scheduled_work
();
i
--
;
err_gpio:
for
(;
i
>=
0
;
i
--
)
gpio_free
(
gpios
[
i
].
gpio
);
return
ret
;
}
static
void
__devexit
collie_bat_remove
(
struct
ucb1x00_dev
*
dev
)
{
int
i
;
free_irq
(
gpio_to_irq
(
COLLIE_GPIO_CO
),
&
collie_bat_main
);
power_supply_unregister
(
&
collie_bat_bu
.
psy
);
power_supply_unregister
(
&
collie_bat_main
.
psy
);
/*
* now flush all pending work.
* we won't get any more schedules, since all
* sources (isr and external_power_changed)
* are unregistered now.
*/
flush_scheduled_work
();
for
(
i
=
ARRAY_SIZE
(
gpios
)
-
1
;
i
>=
0
;
i
--
)
gpio_free
(
gpios
[
i
].
gpio
);
}
static
struct
ucb1x00_driver
collie_bat_driver
=
{
.
add
=
collie_bat_probe
,
.
remove
=
__devexit_p
(
collie_bat_remove
),
.
suspend
=
collie_bat_suspend
,
.
resume
=
collie_bat_resume
,
};
static
int
__init
collie_bat_init
(
void
)
{
return
ucb1x00_register_driver
(
&
collie_bat_driver
);
}
static
void
__exit
collie_bat_exit
(
void
)
{
ucb1x00_unregister_driver
(
&
collie_bat_driver
);
}
module_init
(
collie_bat_init
);
module_exit
(
collie_bat_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Thomas Kunze"
);
MODULE_DESCRIPTION
(
"Collie battery driver"
);
drivers
/mfd/mcp.h
→
include/linux
/mfd/mcp.h
View file @
ba71e172
...
...
@@ -10,6 +10,8 @@
#ifndef MCP_H
#define MCP_H
#include <mach/dma.h>
struct
mcp_ops
;
struct
mcp
{
...
...
@@ -24,6 +26,7 @@ struct mcp {
dma_device_t
dma_telco_rd
;
dma_device_t
dma_telco_wr
;
struct
device
attached_device
;
int
gpio_base
;
};
struct
mcp_ops
{
...
...
drivers
/mfd/ucb1x00.h
→
include/linux
/mfd/ucb1x00.h
View file @
ba71e172
/*
* linux/
drivers
/mfd/ucb1x00.h
* linux/
include
/mfd/ucb1x00.h
*
* Copyright (C) 2001 Russell King, All Rights Reserved.
*
...
...
@@ -10,6 +10,9 @@
#ifndef UCB1200_H
#define UCB1200_H
#include <linux/mfd/mcp.h>
#include <linux/gpio.h>
#define UCB_IO_DATA 0x00
#define UCB_IO_DIR 0x01
...
...
@@ -100,7 +103,6 @@
#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
#define UCB_MODE_AUD_OFF_CAN (1 << 13)
#include "mcp.h"
struct
ucb1x00_irq
{
void
*
devid
;
...
...
@@ -123,6 +125,7 @@ struct ucb1x00 {
struct
device
dev
;
struct
list_head
node
;
struct
list_head
devs
;
struct
gpio_chip
gpio
;
};
struct
ucb1x00_driver
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment