diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-06 11:53:09 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-06 11:53:12 -0500 |
| commit | ba71e17269633ea36e776d744d5cc0fcb5a41f93 (patch) | |
| tree | 0a51c86e5c218ac2ae74ff8193880a64053a77bc | |
| parent | 729fae44dd8332cbf5b9d05a9af17a7455e165b2 (diff) | |
| parent | 9823b2d0f9547742fc40857f9ef153d6956266f2 (diff) | |
Merge branch 'for-lak' of git://git.linuxtogo.org/home/thesing/collie into sa1100
| -rw-r--r-- | arch/arm/mach-sa1100/collie.c | 79 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/include/mach/collie.h | 77 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/include/mach/gpio.h | 19 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/include/mach/mcp.h | 1 | ||||
| -rw-r--r-- | drivers/leds/leds-locomo.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/mcp-core.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/mcp-sa11x0.c | 3 | ||||
| -rw-r--r-- | drivers/mfd/ucb1x00-assabet.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/ucb1x00-core.c | 89 | ||||
| -rw-r--r-- | drivers/mfd/ucb1x00-ts.c | 2 | ||||
| -rw-r--r-- | drivers/power/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/power/Makefile | 1 | ||||
| -rw-r--r-- | drivers/power/collie_battery.c | 418 | ||||
| -rw-r--r-- | include/linux/mfd/mcp.h (renamed from drivers/mfd/mcp.h) | 3 | ||||
| -rw-r--r-- | include/linux/mfd/ucb1x00.h (renamed from drivers/mfd/ucb1x00.h) | 7 |
15 files changed, 649 insertions, 63 deletions
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index be7e5a3c47d0..9982c5c28edf 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/mtd/partitions.h> | 26 | #include <linux/mtd/partitions.h> |
| 27 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
| 28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
| 29 | #include <linux/pda_power.h> | ||
| 29 | 30 | ||
| 30 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
| 31 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
| @@ -56,6 +57,7 @@ static struct resource collie_scoop_resources[] = { | |||
| 56 | static struct scoop_config collie_scoop_setup = { | 57 | static struct scoop_config collie_scoop_setup = { |
| 57 | .io_dir = COLLIE_SCOOP_IO_DIR, | 58 | .io_dir = COLLIE_SCOOP_IO_DIR, |
| 58 | .io_out = COLLIE_SCOOP_IO_OUT, | 59 | .io_out = COLLIE_SCOOP_IO_OUT, |
| 60 | .gpio_base = COLLIE_SCOOP_GPIO_BASE, | ||
| 59 | }; | 61 | }; |
| 60 | 62 | ||
| 61 | struct platform_device colliescoop_device = { | 63 | struct platform_device colliescoop_device = { |
| @@ -85,6 +87,70 @@ static struct scoop_pcmcia_config collie_pcmcia_config = { | |||
| 85 | static struct mcp_plat_data collie_mcp_data = { | 87 | static struct mcp_plat_data collie_mcp_data = { |
| 86 | .mccr0 = MCCR0_ADM | MCCR0_ExtClk, | 88 | .mccr0 = MCCR0_ADM | MCCR0_ExtClk, |
| 87 | .sclk_rate = 9216000, | 89 | .sclk_rate = 9216000, |
| 90 | .gpio_base = COLLIE_TC35143_GPIO_BASE, | ||
| 91 | }; | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Collie AC IN | ||
| 95 | */ | ||
| 96 | static int collie_power_init(struct device *dev) | ||
| 97 | { | ||
| 98 | int ret = gpio_request(COLLIE_GPIO_AC_IN, "ac in"); | ||
| 99 | if (ret) | ||
| 100 | goto err_gpio_req; | ||
| 101 | |||
| 102 | ret = gpio_direction_input(COLLIE_GPIO_AC_IN); | ||
| 103 | if (ret) | ||
| 104 | goto err_gpio_in; | ||
| 105 | |||
| 106 | return 0; | ||
| 107 | |||
| 108 | err_gpio_in: | ||
| 109 | gpio_free(COLLIE_GPIO_AC_IN); | ||
| 110 | err_gpio_req: | ||
| 111 | return ret; | ||
| 112 | } | ||
| 113 | |||
| 114 | static void collie_power_exit(struct device *dev) | ||
| 115 | { | ||
| 116 | gpio_free(COLLIE_GPIO_AC_IN); | ||
| 117 | } | ||
| 118 | |||
| 119 | static int collie_power_ac_online(void) | ||
| 120 | { | ||
| 121 | return gpio_get_value(COLLIE_GPIO_AC_IN) == 2; | ||
| 122 | } | ||
| 123 | |||
| 124 | static char *collie_ac_supplied_to[] = { | ||
| 125 | "main-battery", | ||
| 126 | "backup-battery", | ||
| 127 | }; | ||
| 128 | |||
| 129 | static struct pda_power_pdata collie_power_data = { | ||
| 130 | .init = collie_power_init, | ||
| 131 | .is_ac_online = collie_power_ac_online, | ||
| 132 | .exit = collie_power_exit, | ||
| 133 | .supplied_to = collie_ac_supplied_to, | ||
| 134 | .num_supplicants = ARRAY_SIZE(collie_ac_supplied_to), | ||
| 135 | }; | ||
| 136 | |||
| 137 | static struct resource collie_power_resource[] = { | ||
| 138 | { | ||
| 139 | .name = "ac", | ||
| 140 | .start = gpio_to_irq(COLLIE_GPIO_AC_IN), | ||
| 141 | .end = gpio_to_irq(COLLIE_GPIO_AC_IN), | ||
| 142 | .flags = IORESOURCE_IRQ | | ||
| 143 | IORESOURCE_IRQ_HIGHEDGE | | ||
| 144 | IORESOURCE_IRQ_LOWEDGE, | ||
| 145 | }, | ||
| 146 | }; | ||
| 147 | |||
| 148 | static struct platform_device collie_power_device = { | ||
| 149 | .name = "pda-power", | ||
| 150 | .id = -1, | ||
| 151 | .dev.platform_data = &collie_power_data, | ||
| 152 | .resource = collie_power_resource, | ||
| 153 | .num_resources = ARRAY_SIZE(collie_power_resource), | ||
| 88 | }; | 154 | }; |
| 89 | 155 | ||
| 90 | #ifdef CONFIG_SHARP_LOCOMO | 156 | #ifdef CONFIG_SHARP_LOCOMO |
| @@ -178,6 +244,7 @@ struct platform_device collie_locomo_device = { | |||
| 178 | static struct platform_device *devices[] __initdata = { | 244 | static struct platform_device *devices[] __initdata = { |
| 179 | &collie_locomo_device, | 245 | &collie_locomo_device, |
| 180 | &colliescoop_device, | 246 | &colliescoop_device, |
| 247 | &collie_power_device, | ||
| 181 | }; | 248 | }; |
| 182 | 249 | ||
| 183 | static struct mtd_partition collie_partitions[] = { | 250 | static struct mtd_partition collie_partitions[] = { |
| @@ -248,22 +315,24 @@ static void __init collie_init(void) | |||
| 248 | GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 | | 315 | GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 | |
| 249 | GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD | | 316 | GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD | |
| 250 | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK | | 317 | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK | |
| 251 | COLLIE_GPIO_UCB1x00_RESET | COLLIE_GPIO_nMIC_ON | | 318 | _COLLIE_GPIO_UCB1x00_RESET | _COLLIE_GPIO_nMIC_ON | |
| 252 | COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz; | 319 | _COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz; |
| 253 | 320 | ||
| 254 | PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 | | 321 | PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 | |
| 255 | PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS | | 322 | PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS | |
| 256 | PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM; | 323 | PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM; |
| 257 | 324 | ||
| 258 | PWER = COLLIE_GPIO_AC_IN | COLLIE_GPIO_CO | COLLIE_GPIO_ON_KEY | | 325 | PWER = _COLLIE_GPIO_AC_IN | _COLLIE_GPIO_CO | _COLLIE_GPIO_ON_KEY | |
| 259 | COLLIE_GPIO_WAKEUP | COLLIE_GPIO_nREMOCON_INT | PWER_RTC; | 326 | _COLLIE_GPIO_WAKEUP | _COLLIE_GPIO_nREMOCON_INT | PWER_RTC; |
| 260 | 327 | ||
| 261 | PGSR = COLLIE_GPIO_nREMOCON_ON; | 328 | PGSR = _COLLIE_GPIO_nREMOCON_ON; |
| 262 | 329 | ||
| 263 | PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4; | 330 | PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4; |
| 264 | 331 | ||
| 265 | PCFR = PCFR_OPDE; | 332 | PCFR = PCFR_OPDE; |
| 266 | 333 | ||
| 334 | GPSR |= _COLLIE_GPIO_UCB1x00_RESET; | ||
| 335 | |||
| 267 | 336 | ||
| 268 | platform_scoop_config = &collie_pcmcia_config; | 337 | platform_scoop_config = &collie_pcmcia_config; |
| 269 | 338 | ||
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h index 9efb569cdb60..71a0b3fdcc8c 100644 --- a/arch/arm/mach-sa1100/include/mach/collie.h +++ b/arch/arm/mach-sa1100/include/mach/collie.h | |||
| @@ -25,29 +25,39 @@ | |||
| 25 | #define COLLIE_GPIO_VPEN (COLLIE_SCOOP_GPIO_BASE + 7) | 25 | #define COLLIE_GPIO_VPEN (COLLIE_SCOOP_GPIO_BASE + 7) |
| 26 | #define COLLIE_SCP_LB_VOL_CHG SCOOP_GPCR_PA19 | 26 | #define COLLIE_SCP_LB_VOL_CHG SCOOP_GPCR_PA19 |
| 27 | 27 | ||
| 28 | #define COLLIE_SCOOP_IO_DIR ( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \ | 28 | #define COLLIE_SCOOP_IO_DIR (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \ |
| 29 | COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \ | 29 | COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \ |
| 30 | COLLIE_SCP_LB_VOL_CHG ) | 30 | COLLIE_SCP_LB_VOL_CHG) |
| 31 | #define COLLIE_SCOOP_IO_OUT ( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R ) | 31 | #define COLLIE_SCOOP_IO_OUT (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R) |
| 32 | 32 | ||
| 33 | /* GPIOs for which the generic definition doesn't say much */ | 33 | /* GPIOs for gpiolib */ |
| 34 | 34 | ||
| 35 | #define COLLIE_GPIO_ON_KEY GPIO_GPIO (0) | 35 | #define COLLIE_GPIO_ON_KEY (0) |
| 36 | #define COLLIE_GPIO_AC_IN GPIO_GPIO (1) | 36 | #define COLLIE_GPIO_AC_IN (1) |
| 37 | #define COLLIE_GPIO_SDIO_INT GPIO_GPIO (11) | 37 | #define COLLIE_GPIO_SDIO_INT (11) |
| 38 | #define COLLIE_GPIO_CF_IRQ GPIO_GPIO (14) | 38 | #define COLLIE_GPIO_CF_IRQ (14) |
| 39 | #define COLLIE_GPIO_nREMOCON_INT GPIO_GPIO (15) | 39 | #define COLLIE_GPIO_nREMOCON_INT (15) |
| 40 | #define COLLIE_GPIO_UCB1x00_RESET GPIO_GPIO (16) | 40 | #define COLLIE_GPIO_UCB1x00_RESET (16) |
| 41 | #define COLLIE_GPIO_nMIC_ON GPIO_GPIO (17) | 41 | #define COLLIE_GPIO_nMIC_ON (17) |
| 42 | #define COLLIE_GPIO_nREMOCON_ON GPIO_GPIO (18) | 42 | #define COLLIE_GPIO_nREMOCON_ON (18) |
| 43 | #define COLLIE_GPIO_CO GPIO_GPIO (20) | 43 | #define COLLIE_GPIO_CO (20) |
| 44 | #define COLLIE_GPIO_MCP_CLK GPIO_GPIO (21) | 44 | #define COLLIE_GPIO_MCP_CLK (21) |
| 45 | #define COLLIE_GPIO_CF_CD GPIO_GPIO (22) | 45 | #define COLLIE_GPIO_CF_CD (22) |
| 46 | #define COLLIE_GPIO_UCB1x00_IRQ GPIO_GPIO (23) | 46 | #define COLLIE_GPIO_UCB1x00_IRQ (23) |
| 47 | #define COLLIE_GPIO_WAKEUP GPIO_GPIO (24) | 47 | #define COLLIE_GPIO_WAKEUP (24) |
| 48 | #define COLLIE_GPIO_GA_INT GPIO_GPIO (25) | 48 | #define COLLIE_GPIO_GA_INT (25) |
| 49 | #define COLLIE_GPIO_MAIN_BAT_LOW GPIO_GPIO (26) | 49 | #define COLLIE_GPIO_MAIN_BAT_LOW (26) |
| 50 | 50 | ||
| 51 | /* GPIO definitions for direct register access */ | ||
| 52 | |||
| 53 | #define _COLLIE_GPIO_ON_KEY GPIO_GPIO(0) | ||
| 54 | #define _COLLIE_GPIO_AC_IN GPIO_GPIO(1) | ||
| 55 | #define _COLLIE_GPIO_nREMOCON_INT GPIO_GPIO(15) | ||
| 56 | #define _COLLIE_GPIO_UCB1x00_RESET GPIO_GPIO(16) | ||
| 57 | #define _COLLIE_GPIO_nMIC_ON GPIO_GPIO(17) | ||
| 58 | #define _COLLIE_GPIO_nREMOCON_ON GPIO_GPIO(18) | ||
| 59 | #define _COLLIE_GPIO_CO GPIO_GPIO(20) | ||
| 60 | #define _COLLIE_GPIO_WAKEUP GPIO_GPIO(24) | ||
| 51 | /* Interrupts */ | 61 | /* Interrupts */ |
| 52 | 62 | ||
| 53 | #define COLLIE_IRQ_GPIO_ON_KEY IRQ_GPIO0 | 63 | #define COLLIE_IRQ_GPIO_ON_KEY IRQ_GPIO0 |
| @@ -70,19 +80,20 @@ | |||
| 70 | #define COLLIE_LCM_IRQ_GPIO_nSD_WP IRQ_LOCOMO_GPIO14 | 80 | #define COLLIE_LCM_IRQ_GPIO_nSD_WP IRQ_LOCOMO_GPIO14 |
| 71 | 81 | ||
| 72 | /* GPIO's on the TC35143AF (Toshiba Analog Frontend) */ | 82 | /* GPIO's on the TC35143AF (Toshiba Analog Frontend) */ |
| 73 | #define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0 /* GPIO0=Version */ | 83 | #define COLLIE_TC35143_GPIO_BASE (GPIO_MAX + 13) |
| 74 | #define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1 /* GPIO1=TBL_CHK */ | 84 | #define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0 |
| 75 | #define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2 /* GPIO2=VPNE_ON */ | 85 | #define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1 |
| 76 | #define COLLIE_TC35143_GPIO_IR_ON UCB_IO_3 /* GPIO3=IR_ON */ | 86 | #define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2 |
| 77 | #define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4 /* GPIO4=AMP_ON */ | 87 | #define COLLIE_TC35143_GPIO_IR_ON UCB_IO_3 |
| 78 | #define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5 /* GPIO5=Version */ | 88 | #define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4 |
| 79 | #define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5 /* GPIO5=fs 8k LPF */ | 89 | #define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5 |
| 80 | #define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6 /* GPIO6=BUZZER BIAS */ | 90 | #define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5 |
| 81 | #define COLLIE_TC35143_GPIO_MBAT_ON UCB_IO_7 /* GPIO7=MBAT_ON */ | 91 | #define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6 |
| 82 | #define COLLIE_TC35143_GPIO_BBAT_ON UCB_IO_8 /* GPIO8=BBAT_ON */ | 92 | #define COLLIE_GPIO_MBAT_ON (COLLIE_TC35143_GPIO_BASE + 7) |
| 83 | #define COLLIE_TC35143_GPIO_TMP_ON UCB_IO_9 /* GPIO9=TMP_ON */ | 93 | #define COLLIE_GPIO_BBAT_ON (COLLIE_TC35143_GPIO_BASE + 8) |
| 84 | #define COLLIE_TC35143_GPIO_IN ( UCB_IO_0 | UCB_IO_2 | UCB_IO_5 ) | 94 | #define COLLIE_GPIO_TMP_ON (COLLIE_TC35143_GPIO_BASE + 9) |
| 85 | #define COLLIE_TC35143_GPIO_OUT ( UCB_IO_1 | UCB_IO_3 | UCB_IO_4 | UCB_IO_6 | \ | 95 | #define COLLIE_TC35143_GPIO_IN (UCB_IO_0 | UCB_IO_2 | UCB_IO_5) |
| 86 | UCB_IO_7 | UCB_IO_8 | UCB_IO_9 ) | 96 | #define COLLIE_TC35143_GPIO_OUT (UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \ |
| 97 | | UCB_IO_6) | ||
| 87 | 98 | ||
| 88 | #endif | 99 | #endif |
diff --git a/arch/arm/mach-sa1100/include/mach/gpio.h b/arch/arm/mach-sa1100/include/mach/gpio.h index 582a0c92da53..7befc104e9a9 100644 --- a/arch/arm/mach-sa1100/include/mach/gpio.h +++ b/arch/arm/mach-sa1100/include/mach/gpio.h | |||
| @@ -49,20 +49,9 @@ static inline void gpio_set_value(unsigned gpio, int value) | |||
| 49 | 49 | ||
| 50 | #define gpio_cansleep __gpio_cansleep | 50 | #define gpio_cansleep __gpio_cansleep |
| 51 | 51 | ||
| 52 | static inline unsigned gpio_to_irq(unsigned gpio) | 52 | #define gpio_to_irq(gpio) ((gpio < 11) ? (IRQ_GPIO0 + gpio) : \ |
| 53 | { | 53 | (IRQ_GPIO11 - 11 + gpio)) |
| 54 | if (gpio < 11) | 54 | #define irq_to_gpio(irq) ((irq < IRQ_GPIO11_27) ? (irq - IRQ_GPIO0) : \ |
| 55 | return IRQ_GPIO0 + gpio; | 55 | (irq - IRQ_GPIO11 + 11)) |
| 56 | else | ||
| 57 | return IRQ_GPIO11 - 11 + gpio; | ||
| 58 | } | ||
| 59 | |||
| 60 | static inline unsigned irq_to_gpio(unsigned irq) | ||
| 61 | { | ||
| 62 | if (irq < IRQ_GPIO11_27) | ||
| 63 | return irq - IRQ_GPIO0; | ||
| 64 | else | ||
| 65 | return irq - IRQ_GPIO11 + 11; | ||
| 66 | } | ||
| 67 | 56 | ||
| 68 | #endif | 57 | #endif |
diff --git a/arch/arm/mach-sa1100/include/mach/mcp.h b/arch/arm/mach-sa1100/include/mach/mcp.h index fb8b09a57ad7..ed1a331508a7 100644 --- a/arch/arm/mach-sa1100/include/mach/mcp.h +++ b/arch/arm/mach-sa1100/include/mach/mcp.h | |||
| @@ -16,6 +16,7 @@ struct mcp_plat_data { | |||
| 16 | u32 mccr0; | 16 | u32 mccr0; |
| 17 | u32 mccr1; | 17 | u32 mccr1; |
| 18 | unsigned int sclk_rate; | 18 | unsigned int sclk_rate; |
| 19 | int gpio_base; | ||
| 19 | }; | 20 | }; |
| 20 | 21 | ||
| 21 | #endif | 22 | #endif |
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c index 5d91362e3066..1f7c10f6b7f2 100644 --- a/drivers/leds/leds-locomo.c +++ b/drivers/leds/leds-locomo.c | |||
| @@ -44,7 +44,7 @@ static void locomoled_brightness_set1(struct led_classdev *led_cdev, | |||
| 44 | 44 | ||
| 45 | static struct led_classdev locomo_led0 = { | 45 | static struct led_classdev locomo_led0 = { |
| 46 | .name = "locomo:amber:charge", | 46 | .name = "locomo:amber:charge", |
| 47 | .default_trigger = "sharpsl-charge", | 47 | .default_trigger = "main-battery-charging", |
| 48 | .brightness_set = locomoled_brightness_set0, | 48 | .brightness_set = locomoled_brightness_set0, |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index 57271cb3b316..84815f9ef636 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c | |||
| @@ -17,11 +17,11 @@ | |||
| 17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
| 20 | #include <linux/mfd/mcp.h> | ||
| 20 | 21 | ||
| 21 | #include <mach/dma.h> | 22 | #include <mach/dma.h> |
| 22 | #include <asm/system.h> | 23 | #include <asm/system.h> |
| 23 | 24 | ||
| 24 | #include "mcp.h" | ||
| 25 | 25 | ||
| 26 | #define to_mcp(d) container_of(d, struct mcp, attached_device) | 26 | #define to_mcp(d) container_of(d, struct mcp, attached_device) |
| 27 | #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) | 27 | #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) |
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index 62b32dabf629..258427232728 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/mfd/mcp.h> | ||
| 22 | 23 | ||
| 23 | #include <mach/dma.h> | 24 | #include <mach/dma.h> |
| 24 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
| @@ -28,7 +29,6 @@ | |||
| 28 | 29 | ||
| 29 | #include <mach/assabet.h> | 30 | #include <mach/assabet.h> |
| 30 | 31 | ||
| 31 | #include "mcp.h" | ||
| 32 | 32 | ||
| 33 | struct mcp_sa11x0 { | 33 | struct mcp_sa11x0 { |
| 34 | u32 mccr0; | 34 | u32 mccr0; |
| @@ -163,6 +163,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) | |||
| 163 | mcp->dma_audio_wr = DMA_Ser4MCP0Wr; | 163 | mcp->dma_audio_wr = DMA_Ser4MCP0Wr; |
| 164 | mcp->dma_telco_rd = DMA_Ser4MCP1Rd; | 164 | mcp->dma_telco_rd = DMA_Ser4MCP1Rd; |
| 165 | mcp->dma_telco_wr = DMA_Ser4MCP1Wr; | 165 | mcp->dma_telco_wr = DMA_Ser4MCP1Wr; |
| 166 | mcp->gpio_base = data->gpio_base; | ||
| 166 | 167 | ||
| 167 | platform_set_drvdata(pdev, mcp); | 168 | platform_set_drvdata(pdev, mcp); |
| 168 | 169 | ||
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c index 86fed4870f93..cea9da60850d 100644 --- a/drivers/mfd/ucb1x00-assabet.c +++ b/drivers/mfd/ucb1x00-assabet.c | |||
| @@ -14,10 +14,10 @@ | |||
| 14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
| 15 | #include <linux/proc_fs.h> | 15 | #include <linux/proc_fs.h> |
| 16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
| 17 | #include <linux/mfd/ucb1x00.h> | ||
| 17 | 18 | ||
| 18 | #include <mach/dma.h> | 19 | #include <mach/dma.h> |
| 19 | 20 | ||
| 20 | #include "ucb1x00.h" | ||
| 21 | 21 | ||
| 22 | #define UCB1X00_ATTR(name,input)\ | 22 | #define UCB1X00_ATTR(name,input)\ |
| 23 | static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ | 23 | static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ |
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index 60c3988f3cf3..252b74188ec2 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c | |||
| @@ -25,12 +25,12 @@ | |||
| 25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| 26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
| 27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
| 28 | #include <linux/mfd/ucb1x00.h> | ||
| 29 | #include <linux/gpio.h> | ||
| 28 | 30 | ||
| 29 | #include <mach/dma.h> | 31 | #include <mach/dma.h> |
| 30 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
| 31 | 33 | ||
| 32 | #include "ucb1x00.h" | ||
| 33 | |||
| 34 | static DEFINE_MUTEX(ucb1x00_mutex); | 34 | static DEFINE_MUTEX(ucb1x00_mutex); |
| 35 | static LIST_HEAD(ucb1x00_drivers); | 35 | static LIST_HEAD(ucb1x00_drivers); |
| 36 | static LIST_HEAD(ucb1x00_devices); | 36 | static LIST_HEAD(ucb1x00_devices); |
| @@ -108,6 +108,60 @@ unsigned int ucb1x00_io_read(struct ucb1x00 *ucb) | |||
| 108 | return ucb1x00_reg_read(ucb, UCB_IO_DATA); | 108 | return ucb1x00_reg_read(ucb, UCB_IO_DATA); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 112 | { | ||
| 113 | struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); | ||
| 114 | unsigned long flags; | ||
| 115 | |||
| 116 | spin_lock_irqsave(&ucb->io_lock, flags); | ||
| 117 | if (value) | ||
| 118 | ucb->io_out |= 1 << offset; | ||
| 119 | else | ||
| 120 | ucb->io_out &= ~(1 << offset); | ||
| 121 | |||
| 122 | ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); | ||
| 123 | spin_unlock_irqrestore(&ucb->io_lock, flags); | ||
| 124 | } | ||
| 125 | |||
| 126 | static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 127 | { | ||
| 128 | struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); | ||
| 129 | return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset); | ||
| 130 | } | ||
| 131 | |||
| 132 | static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 133 | { | ||
| 134 | struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); | ||
| 135 | unsigned long flags; | ||
| 136 | |||
| 137 | spin_lock_irqsave(&ucb->io_lock, flags); | ||
| 138 | ucb->io_dir &= ~(1 << offset); | ||
| 139 | ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); | ||
| 140 | spin_unlock_irqrestore(&ucb->io_lock, flags); | ||
| 141 | |||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset | ||
| 146 | , int value) | ||
| 147 | { | ||
| 148 | struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); | ||
| 149 | unsigned long flags; | ||
| 150 | |||
| 151 | spin_lock_irqsave(&ucb->io_lock, flags); | ||
| 152 | ucb->io_dir |= (1 << offset); | ||
| 153 | ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); | ||
| 154 | |||
| 155 | if (value) | ||
| 156 | ucb->io_out |= 1 << offset; | ||
| 157 | else | ||
| 158 | ucb->io_out &= ~(1 << offset); | ||
| 159 | ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); | ||
| 160 | spin_unlock_irqrestore(&ucb->io_lock, flags); | ||
| 161 | |||
| 162 | return 0; | ||
| 163 | } | ||
| 164 | |||
| 111 | /* | 165 | /* |
| 112 | * UCB1300 data sheet says we must: | 166 | * UCB1300 data sheet says we must: |
| 113 | * 1. enable ADC => 5us (including reference startup time) | 167 | * 1. enable ADC => 5us (including reference startup time) |
| @@ -476,6 +530,7 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
| 476 | struct ucb1x00_driver *drv; | 530 | struct ucb1x00_driver *drv; |
| 477 | unsigned int id; | 531 | unsigned int id; |
| 478 | int ret = -ENODEV; | 532 | int ret = -ENODEV; |
| 533 | int temp; | ||
| 479 | 534 | ||
| 480 | mcp_enable(mcp); | 535 | mcp_enable(mcp); |
| 481 | id = mcp_reg_read(mcp, UCB_ID); | 536 | id = mcp_reg_read(mcp, UCB_ID); |
| @@ -508,12 +563,27 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
| 508 | goto err_free; | 563 | goto err_free; |
| 509 | } | 564 | } |
| 510 | 565 | ||
| 566 | ucb->gpio.base = -1; | ||
| 567 | if (mcp->gpio_base != 0) { | ||
| 568 | ucb->gpio.label = dev_name(&ucb->dev); | ||
| 569 | ucb->gpio.base = mcp->gpio_base; | ||
| 570 | ucb->gpio.ngpio = 10; | ||
| 571 | ucb->gpio.set = ucb1x00_gpio_set; | ||
| 572 | ucb->gpio.get = ucb1x00_gpio_get; | ||
| 573 | ucb->gpio.direction_input = ucb1x00_gpio_direction_input; | ||
| 574 | ucb->gpio.direction_output = ucb1x00_gpio_direction_output; | ||
| 575 | ret = gpiochip_add(&ucb->gpio); | ||
| 576 | if (ret) | ||
| 577 | goto err_free; | ||
| 578 | } else | ||
| 579 | dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); | ||
| 580 | |||
| 511 | ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, | 581 | ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, |
| 512 | "UCB1x00", ucb); | 582 | "UCB1x00", ucb); |
| 513 | if (ret) { | 583 | if (ret) { |
| 514 | printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", | 584 | printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", |
| 515 | ucb->irq, ret); | 585 | ucb->irq, ret); |
| 516 | goto err_free; | 586 | goto err_gpio; |
| 517 | } | 587 | } |
| 518 | 588 | ||
| 519 | mcp_set_drvdata(mcp, ucb); | 589 | mcp_set_drvdata(mcp, ucb); |
| @@ -522,6 +592,7 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
| 522 | if (ret) | 592 | if (ret) |
| 523 | goto err_irq; | 593 | goto err_irq; |
| 524 | 594 | ||
| 595 | |||
| 525 | INIT_LIST_HEAD(&ucb->devs); | 596 | INIT_LIST_HEAD(&ucb->devs); |
| 526 | mutex_lock(&ucb1x00_mutex); | 597 | mutex_lock(&ucb1x00_mutex); |
| 527 | list_add(&ucb->node, &ucb1x00_devices); | 598 | list_add(&ucb->node, &ucb1x00_devices); |
| @@ -529,10 +600,14 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
| 529 | ucb1x00_add_dev(ucb, drv); | 600 | ucb1x00_add_dev(ucb, drv); |
| 530 | } | 601 | } |
| 531 | mutex_unlock(&ucb1x00_mutex); | 602 | mutex_unlock(&ucb1x00_mutex); |
| 603 | |||
| 532 | goto out; | 604 | goto out; |
| 533 | 605 | ||
| 534 | err_irq: | 606 | err_irq: |
| 535 | free_irq(ucb->irq, ucb); | 607 | free_irq(ucb->irq, ucb); |
| 608 | err_gpio: | ||
| 609 | if (ucb->gpio.base != -1) | ||
| 610 | temp = gpiochip_remove(&ucb->gpio); | ||
| 536 | err_free: | 611 | err_free: |
| 537 | kfree(ucb); | 612 | kfree(ucb); |
| 538 | err_disable: | 613 | err_disable: |
| @@ -545,6 +620,7 @@ static void ucb1x00_remove(struct mcp *mcp) | |||
| 545 | { | 620 | { |
| 546 | struct ucb1x00 *ucb = mcp_get_drvdata(mcp); | 621 | struct ucb1x00 *ucb = mcp_get_drvdata(mcp); |
| 547 | struct list_head *l, *n; | 622 | struct list_head *l, *n; |
| 623 | int ret; | ||
| 548 | 624 | ||
| 549 | mutex_lock(&ucb1x00_mutex); | 625 | mutex_lock(&ucb1x00_mutex); |
| 550 | list_del(&ucb->node); | 626 | list_del(&ucb->node); |
| @@ -554,6 +630,12 @@ static void ucb1x00_remove(struct mcp *mcp) | |||
| 554 | } | 630 | } |
| 555 | mutex_unlock(&ucb1x00_mutex); | 631 | mutex_unlock(&ucb1x00_mutex); |
| 556 | 632 | ||
| 633 | if (ucb->gpio.base != -1) { | ||
| 634 | ret = gpiochip_remove(&ucb->gpio); | ||
| 635 | if (ret) | ||
| 636 | dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret); | ||
| 637 | } | ||
| 638 | |||
| 557 | free_irq(ucb->irq, ucb); | 639 | free_irq(ucb->irq, ucb); |
| 558 | device_unregister(&ucb->dev); | 640 | device_unregister(&ucb->dev); |
| 559 | } | 641 | } |
| @@ -604,6 +686,7 @@ static int ucb1x00_resume(struct mcp *mcp) | |||
| 604 | struct ucb1x00 *ucb = mcp_get_drvdata(mcp); | 686 | struct ucb1x00 *ucb = mcp_get_drvdata(mcp); |
| 605 | struct ucb1x00_dev *dev; | 687 | struct ucb1x00_dev *dev; |
| 606 | 688 | ||
| 689 | ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); | ||
| 607 | mutex_lock(&ucb1x00_mutex); | 690 | mutex_lock(&ucb1x00_mutex); |
| 608 | list_for_each_entry(dev, &ucb->devs, dev_node) { | 691 | list_for_each_entry(dev, &ucb->devs, dev_node) { |
| 609 | if (dev->drv->resume) | 692 | if (dev->drv->resume) |
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 61b7d3eb9a2f..000cb414a78a 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c | |||
| @@ -30,12 +30,12 @@ | |||
| 30 | #include <linux/freezer.h> | 30 | #include <linux/freezer.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/kthread.h> | 32 | #include <linux/kthread.h> |
| 33 | #include <linux/mfd/ucb1x00.h> | ||
| 33 | 34 | ||
| 34 | #include <mach/dma.h> | 35 | #include <mach/dma.h> |
| 35 | #include <mach/collie.h> | 36 | #include <mach/collie.h> |
| 36 | #include <asm/mach-types.h> | 37 | #include <asm/mach-types.h> |
| 37 | 38 | ||
| 38 | #include "ucb1x00.h" | ||
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | struct ucb1x00_ts { | 41 | struct ucb1x00_ts { |
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index cea6cef27e89..118674925516 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
| @@ -77,6 +77,13 @@ config BATTERY_TOSA | |||
| 77 | Say Y to enable support for the battery on the Sharp Zaurus | 77 | Say Y to enable support for the battery on the Sharp Zaurus |
| 78 | SL-6000 (tosa) models. | 78 | SL-6000 (tosa) models. |
| 79 | 79 | ||
| 80 | config BATTERY_COLLIE | ||
| 81 | tristate "Sharp SL-5500 (collie) battery" | ||
| 82 | depends on SA1100_COLLIE && MCP_UCB1200 | ||
| 83 | help | ||
| 84 | Say Y to enable support for the battery on the Sharp Zaurus | ||
| 85 | SL-5500 (collie) models. | ||
| 86 | |||
| 80 | config BATTERY_WM97XX | 87 | config BATTERY_WM97XX |
| 81 | bool "WM97xx generic battery driver" | 88 | bool "WM97xx generic battery driver" |
| 82 | depends on TOUCHSCREEN_WM97XX=y | 89 | depends on TOUCHSCREEN_WM97XX=y |
diff --git a/drivers/power/Makefile b/drivers/power/Makefile index b96f29d91c28..356cdfd3c8b2 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile | |||
| @@ -24,6 +24,7 @@ obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o | |||
| 24 | obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o | 24 | obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o |
| 25 | obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o | 25 | obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o |
| 26 | obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o | 26 | obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o |
| 27 | obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o | ||
| 27 | obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o | 28 | obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o |
| 28 | obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o | 29 | obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o |
| 29 | obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o | 30 | obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o |
diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c new file mode 100644 index 000000000000..039f41ae217d --- /dev/null +++ b/drivers/power/collie_battery.c | |||
| @@ -0,0 +1,418 @@ | |||
| 1 | /* | ||
| 2 | * Battery and Power Management code for the Sharp SL-5x00 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Thomas Kunze | ||
| 5 | * | ||
| 6 | * based on tosa_battery.c | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/power_supply.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/spinlock.h> | ||
| 18 | #include <linux/interrupt.h> | ||
| 19 | #include <linux/gpio.h> | ||
| 20 | #include <linux/mfd/ucb1x00.h> | ||
| 21 | |||
| 22 | #include <asm/mach/sharpsl_param.h> | ||
| 23 | #include <asm/mach-types.h> | ||
| 24 | #include <mach/collie.h> | ||
| 25 | |||
| 26 | static DEFINE_MUTEX(bat_lock); /* protects gpio pins */ | ||
| 27 | static struct work_struct bat_work; | ||
| 28 | static struct ucb1x00 *ucb; | ||
| 29 | |||
| 30 | struct collie_bat { | ||
| 31 | int status; | ||
| 32 | struct power_supply psy; | ||
| 33 | int full_chrg; | ||
| 34 | |||
| 35 | struct mutex work_lock; /* protects data */ | ||
| 36 | |||
| 37 | bool (*is_present)(struct collie_bat *bat); | ||
| 38 | int gpio_full; | ||
| 39 | int gpio_charge_on; | ||
| 40 | |||
| 41 | int technology; | ||
| 42 | |||
| 43 | int gpio_bat; | ||
| 44 | int adc_bat; | ||
| 45 | int adc_bat_divider; | ||
| 46 | int bat_max; | ||
| 47 | int bat_min; | ||
| 48 | |||
| 49 | int gpio_temp; | ||
| 50 | int adc_temp; | ||
| 51 | int adc_temp_divider; | ||
| 52 | }; | ||
| 53 | |||
| 54 | static struct collie_bat collie_bat_main; | ||
| 55 | |||
| 56 | static unsigned long collie_read_bat(struct collie_bat *bat) | ||
| 57 | { | ||
| 58 | unsigned long value = 0; | ||
| 59 | |||
| 60 | if (bat->gpio_bat < 0 || bat->adc_bat < 0) | ||
| 61 | return 0; | ||
| 62 | mutex_lock(&bat_lock); | ||
| 63 | gpio_set_value(bat->gpio_bat, 1); | ||
| 64 | msleep(5); | ||
| 65 | ucb1x00_adc_enable(ucb); | ||
| 66 | value = ucb1x00_adc_read(ucb, bat->adc_bat, UCB_SYNC); | ||
| 67 | ucb1x00_adc_disable(ucb); | ||
| 68 | gpio_set_value(bat->gpio_bat, 0); | ||
| 69 | mutex_unlock(&bat_lock); | ||
| 70 | value = value * 1000000 / bat->adc_bat_divider; | ||
| 71 | |||
| 72 | return value; | ||
| 73 | } | ||
| 74 | |||
| 75 | static unsigned long collie_read_temp(struct collie_bat *bat) | ||
| 76 | { | ||
| 77 | unsigned long value = 0; | ||
| 78 | if (bat->gpio_temp < 0 || bat->adc_temp < 0) | ||
| 79 | return 0; | ||
| 80 | |||
| 81 | mutex_lock(&bat_lock); | ||
| 82 | gpio_set_value(bat->gpio_temp, 1); | ||
| 83 | msleep(5); | ||
| 84 | ucb1x00_adc_enable(ucb); | ||
| 85 | value = ucb1x00_adc_read(ucb, bat->adc_temp, UCB_SYNC); | ||
| 86 | ucb1x00_adc_disable(ucb); | ||
| 87 | gpio_set_value(bat->gpio_temp, 0); | ||
| 88 | mutex_unlock(&bat_lock); | ||
| 89 | |||
| 90 | value = value * 10000 / bat->adc_temp_divider; | ||
| 91 | |||
| 92 | return value; | ||
| 93 | } | ||
| 94 | |||
| 95 | static int collie_bat_get_property(struct power_supply *psy, | ||
| 96 | enum power_supply_property psp, | ||
| 97 | union power_supply_propval *val) | ||
| 98 | { | ||
| 99 | int ret = 0; | ||
| 100 | struct collie_bat *bat = container_of(psy, struct collie_bat, psy); | ||
| 101 | |||
| 102 | if (bat->is_present && !bat->is_present(bat) | ||
| 103 | && psp != POWER_SUPPLY_PROP_PRESENT) { | ||
| 104 | return -ENODEV; | ||
| 105 | } | ||
| 106 | |||
| 107 | switch (psp) { | ||
| 108 | case POWER_SUPPLY_PROP_STATUS: | ||
| 109 | val->intval = bat->status; | ||
| 110 | break; | ||
| 111 | case POWER_SUPPLY_PROP_TECHNOLOGY: | ||
| 112 | val->intval = bat->technology; | ||
| 113 | break; | ||
| 114 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
| 115 | val->intval = collie_read_bat(bat); | ||
| 116 | break; | ||
| 117 | case POWER_SUPPLY_PROP_VOLTAGE_MAX: | ||
| 118 | if (bat->full_chrg == -1) | ||
| 119 | val->intval = bat->bat_max; | ||
| 120 | else | ||
| 121 | val->intval = bat->full_chrg; | ||
| 122 | break; | ||
| 123 | case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: | ||
| 124 | val->intval = bat->bat_max; | ||
| 125 | break; | ||
| 126 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | ||
| 127 | val->intval = bat->bat_min; | ||
| 128 | break; | ||
| 129 | case POWER_SUPPLY_PROP_TEMP: | ||
| 130 | val->intval = collie_read_temp(bat); | ||
| 131 | break; | ||
| 132 | case POWER_SUPPLY_PROP_PRESENT: | ||
| 133 | val->intval = bat->is_present ? bat->is_present(bat) : 1; | ||
| 134 | break; | ||
| 135 | default: | ||
| 136 | ret = -EINVAL; | ||
| 137 | break; | ||
| 138 | } | ||
| 139 | return ret; | ||
| 140 | } | ||
| 141 | |||
| 142 | static void collie_bat_external_power_changed(struct power_supply *psy) | ||
| 143 | { | ||
| 144 | schedule_work(&bat_work); | ||
| 145 | } | ||
| 146 | |||
| 147 | static irqreturn_t collie_bat_gpio_isr(int irq, void *data) | ||
| 148 | { | ||
| 149 | pr_info("collie_bat_gpio irq: %d\n", gpio_get_value(irq_to_gpio(irq))); | ||
| 150 | schedule_work(&bat_work); | ||
| 151 | return IRQ_HANDLED; | ||
| 152 | } | ||
| 153 | |||
| 154 | static void collie_bat_update(struct collie_bat *bat) | ||
| 155 | { | ||
| 156 | int old; | ||
| 157 | struct power_supply *psy = &bat->psy; | ||
| 158 | |||
| 159 | mutex_lock(&bat->work_lock); | ||
| 160 | |||
| 161 | old = bat->status; | ||
| 162 | |||
| 163 | if (bat->is_present && !bat->is_present(bat)) { | ||
| 164 | printk(KERN_NOTICE "%s not present\n", psy->name); | ||
| 165 | bat->status = POWER_SUPPLY_STATUS_UNKNOWN; | ||
| 166 | bat->full_chrg = -1; | ||
| 167 | } else if (power_supply_am_i_supplied(psy)) { | ||
| 168 | if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) { | ||
| 169 | gpio_set_value(bat->gpio_charge_on, 1); | ||
| 170 | mdelay(15); | ||
| 171 | } | ||
| 172 | |||
| 173 | if (gpio_get_value(bat->gpio_full)) { | ||
| 174 | if (old == POWER_SUPPLY_STATUS_CHARGING || | ||
| 175 | bat->full_chrg == -1) | ||
| 176 | bat->full_chrg = collie_read_bat(bat); | ||
| 177 | |||
| 178 | gpio_set_value(bat->gpio_charge_on, 0); | ||
| 179 | bat->status = POWER_SUPPLY_STATUS_FULL; | ||
| 180 | } else { | ||
| 181 | gpio_set_value(bat->gpio_charge_on, 1); | ||
| 182 | bat->status = POWER_SUPPLY_STATUS_CHARGING; | ||
| 183 | } | ||
| 184 | } else { | ||
| 185 | gpio_set_value(bat->gpio_charge_on, 0); | ||
| 186 | bat->status = POWER_SUPPLY_STATUS_DISCHARGING; | ||
| 187 | } | ||
| 188 | |||
| 189 | if (old != bat->status) | ||
| 190 | power_supply_changed(psy); | ||
| 191 | |||
| 192 | mutex_unlock(&bat->work_lock); | ||
| 193 | } | ||
| 194 | |||
| 195 | static void collie_bat_work(struct work_struct *work) | ||
| 196 | { | ||
| 197 | collie_bat_update(&collie_bat_main); | ||
| 198 | } | ||
| 199 | |||
| 200 | |||
| 201 | static enum power_supply_property collie_bat_main_props[] = { | ||
| 202 | POWER_SUPPLY_PROP_STATUS, | ||
| 203 | POWER_SUPPLY_PROP_TECHNOLOGY, | ||
| 204 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | ||
| 205 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
| 206 | POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, | ||
| 207 | POWER_SUPPLY_PROP_VOLTAGE_MAX, | ||
| 208 | POWER_SUPPLY_PROP_PRESENT, | ||
| 209 | POWER_SUPPLY_PROP_TEMP, | ||
| 210 | }; | ||
| 211 | |||
| 212 | static enum power_supply_property collie_bat_bu_props[] = { | ||
| 213 | POWER_SUPPLY_PROP_STATUS, | ||
| 214 | POWER_SUPPLY_PROP_TECHNOLOGY, | ||
| 215 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | ||
| 216 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
| 217 | POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, | ||
| 218 | POWER_SUPPLY_PROP_VOLTAGE_MAX, | ||
| 219 | POWER_SUPPLY_PROP_PRESENT, | ||
| 220 | }; | ||
| 221 | |||
| 222 | static struct collie_bat collie_bat_main = { | ||
| 223 | .status = POWER_SUPPLY_STATUS_DISCHARGING, | ||
| 224 | .full_chrg = -1, | ||
| 225 | .psy = { | ||
| 226 | .name = "main-battery", | ||
| 227 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 228 | .properties = collie_bat_main_props, | ||
| 229 | .num_properties = ARRAY_SIZE(collie_bat_main_props), | ||
| 230 | .get_property = collie_bat_get_property, | ||
| 231 | .external_power_changed = collie_bat_external_power_changed, | ||
| 232 | .use_for_apm = 1, | ||
| 233 | }, | ||
| 234 | |||
| 235 | .gpio_full = COLLIE_GPIO_CO, | ||
| 236 | .gpio_charge_on = COLLIE_GPIO_CHARGE_ON, | ||
| 237 | |||
| 238 | .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, | ||
| 239 | |||
| 240 | .gpio_bat = COLLIE_GPIO_MBAT_ON, | ||
| 241 | .adc_bat = UCB_ADC_INP_AD1, | ||
| 242 | .adc_bat_divider = 155, | ||
| 243 | .bat_max = 4310000, | ||
| 244 | .bat_min = 1551 * 1000000 / 414, | ||
| 245 | |||
| 246 | .gpio_temp = COLLIE_GPIO_TMP_ON, | ||
| 247 | .adc_temp = UCB_ADC_INP_AD0, | ||
| 248 | .adc_temp_divider = 10000, | ||
| 249 | }; | ||
| 250 | |||
| 251 | static struct collie_bat collie_bat_bu = { | ||
| 252 | .status = POWER_SUPPLY_STATUS_UNKNOWN, | ||
| 253 | .full_chrg = -1, | ||
| 254 | |||
| 255 | .psy = { | ||
| 256 | .name = "backup-battery", | ||
| 257 | .type = POWER_SUPPLY_TYPE_BATTERY, | ||
| 258 | .properties = collie_bat_bu_props, | ||
| 259 | .num_properties = ARRAY_SIZE(collie_bat_bu_props), | ||
| 260 | .get_property = collie_bat_get_property, | ||
| 261 | .external_power_changed = collie_bat_external_power_changed, | ||
| 262 | }, | ||
| 263 | |||
| 264 | .gpio_full = -1, | ||
| 265 | .gpio_charge_on = -1, | ||
| 266 | |||
| 267 | .technology = POWER_SUPPLY_TECHNOLOGY_LiMn, | ||
| 268 | |||
| 269 | .gpio_bat = COLLIE_GPIO_BBAT_ON, | ||
| 270 | .adc_bat = UCB_ADC_INP_AD1, | ||
| 271 | .adc_bat_divider = 155, | ||
| 272 | .bat_max = 3000000, | ||
| 273 | .bat_min = 1900000, | ||
| 274 | |||
| 275 | .gpio_temp = -1, | ||
| 276 | .adc_temp = -1, | ||
| 277 | .adc_temp_divider = -1, | ||
| 278 | }; | ||
| 279 | |||
| 280 | static struct { | ||
| 281 | int gpio; | ||
| 282 | char *name; | ||
| 283 | bool output; | ||
| 284 | int value; | ||
| 285 | } gpios[] = { | ||
| 286 | { COLLIE_GPIO_CO, "main battery full", 0, 0 }, | ||
| 287 | { COLLIE_GPIO_MAIN_BAT_LOW, "main battery low", 0, 0 }, | ||
| 288 | { COLLIE_GPIO_CHARGE_ON, "main charge on", 1, 0 }, | ||
| 289 | { COLLIE_GPIO_MBAT_ON, "main battery", 1, 0 }, | ||
| 290 | { COLLIE_GPIO_TMP_ON, "main battery temp", 1, 0 }, | ||
| 291 | { COLLIE_GPIO_BBAT_ON, "backup battery", 1, 0 }, | ||
| 292 | }; | ||
| 293 | |||
| 294 | #ifdef CONFIG_PM | ||
| 295 | static int collie_bat_suspend(struct ucb1x00_dev *dev, pm_message_t state) | ||
| 296 | { | ||
| 297 | /* flush all pending status updates */ | ||
| 298 | flush_scheduled_work(); | ||
| 299 | return 0; | ||
| 300 | } | ||
| 301 | |||
| 302 | static int collie_bat_resume(struct ucb1x00_dev *dev) | ||
| 303 | { | ||
| 304 | /* things may have changed while we were away */ | ||
| 305 | schedule_work(&bat_work); | ||
| 306 | return 0; | ||
| 307 | } | ||
| 308 | #else | ||
| 309 | #define collie_bat_suspend NULL | ||
| 310 | #define collie_bat_resume NULL | ||
| 311 | #endif | ||
| 312 | |||
| 313 | static int __devinit collie_bat_probe(struct ucb1x00_dev *dev) | ||
| 314 | { | ||
| 315 | int ret; | ||
| 316 | int i; | ||
| 317 | |||
| 318 | if (!machine_is_collie()) | ||
| 319 | return -ENODEV; | ||
| 320 | |||
| 321 | ucb = dev->ucb; | ||
| 322 | |||
| 323 | for (i = 0; i < ARRAY_SIZE(gpios); i++) { | ||
| 324 | ret = gpio_request(gpios[i].gpio, gpios[i].name); | ||
| 325 | if (ret) { | ||
| 326 | i--; | ||
| 327 | goto err_gpio; | ||
| 328 | } | ||
| 329 | |||
| 330 | if (gpios[i].output) | ||
| 331 | ret = gpio_direction_output(gpios[i].gpio, | ||
| 332 | gpios[i].value); | ||
| 333 | else | ||
| 334 | ret = gpio_direction_input(gpios[i].gpio); | ||
| 335 | |||
| 336 | if (ret) | ||
| 337 | goto err_gpio; | ||
| 338 | } | ||
| 339 | |||
| 340 | mutex_init(&collie_bat_main.work_lock); | ||
| 341 | |||
| 342 | INIT_WORK(&bat_work, collie_bat_work); | ||
| 343 | |||
| 344 | ret = power_supply_register(&dev->ucb->dev, &collie_bat_main.psy); | ||
| 345 | if (ret) | ||
| 346 | goto err_psy_reg_main; | ||
| 347 | ret = power_supply_register(&dev->ucb->dev, &collie_bat_bu.psy); | ||
| 348 | if (ret) | ||
| 349 | goto err_psy_reg_bu; | ||
| 350 | |||
| 351 | ret = request_irq(gpio_to_irq(COLLIE_GPIO_CO), | ||
| 352 | collie_bat_gpio_isr, | ||
| 353 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
| 354 | "main full", &collie_bat_main); | ||
| 355 | if (!ret) { | ||
| 356 | schedule_work(&bat_work); | ||
| 357 | return 0; | ||
| 358 | } | ||
| 359 | power_supply_unregister(&collie_bat_bu.psy); | ||
| 360 | err_psy_reg_bu: | ||
| 361 | power_supply_unregister(&collie_bat_main.psy); | ||
| 362 | err_psy_reg_main: | ||
| 363 | |||
| 364 | /* see comment in collie_bat_remove */ | ||
| 365 | flush_scheduled_work(); | ||
| 366 | |||
| 367 | i--; | ||
| 368 | err_gpio: | ||
| 369 | for (; i >= 0; i--) | ||
| 370 | gpio_free(gpios[i].gpio); | ||
| 371 | |||
| 372 | return ret; | ||
| 373 | } | ||
| 374 | |||
| 375 | static void __devexit collie_bat_remove(struct ucb1x00_dev *dev) | ||
| 376 | { | ||
| 377 | int i; | ||
| 378 | |||
| 379 | free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main); | ||
| 380 | |||
| 381 | power_supply_unregister(&collie_bat_bu.psy); | ||
| 382 | power_supply_unregister(&collie_bat_main.psy); | ||
| 383 | |||
| 384 | /* | ||
| 385 | * now flush all pending work. | ||
| 386 | * we won't get any more schedules, since all | ||
| 387 | * sources (isr and external_power_changed) | ||
| 388 | * are unregistered now. | ||
| 389 | */ | ||
| 390 | flush_scheduled_work(); | ||
| 391 | |||
| 392 | for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--) | ||
| 393 | gpio_free(gpios[i].gpio); | ||
| 394 | } | ||
| 395 | |||
| 396 | static struct ucb1x00_driver collie_bat_driver = { | ||
| 397 | .add = collie_bat_probe, | ||
| 398 | .remove = __devexit_p(collie_bat_remove), | ||
| 399 | .suspend = collie_bat_suspend, | ||
| 400 | .resume = collie_bat_resume, | ||
| 401 | }; | ||
| 402 | |||
| 403 | static int __init collie_bat_init(void) | ||
| 404 | { | ||
| 405 | return ucb1x00_register_driver(&collie_bat_driver); | ||
| 406 | } | ||
| 407 | |||
| 408 | static void __exit collie_bat_exit(void) | ||
| 409 | { | ||
| 410 | ucb1x00_unregister_driver(&collie_bat_driver); | ||
| 411 | } | ||
| 412 | |||
| 413 | module_init(collie_bat_init); | ||
| 414 | module_exit(collie_bat_exit); | ||
| 415 | |||
| 416 | MODULE_LICENSE("GPL"); | ||
| 417 | MODULE_AUTHOR("Thomas Kunze"); | ||
| 418 | MODULE_DESCRIPTION("Collie battery driver"); | ||
diff --git a/drivers/mfd/mcp.h b/include/linux/mfd/mcp.h index c093a93b8808..ee496708e38b 100644 --- a/drivers/mfd/mcp.h +++ b/include/linux/mfd/mcp.h | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #ifndef MCP_H | 10 | #ifndef MCP_H |
| 11 | #define MCP_H | 11 | #define MCP_H |
| 12 | 12 | ||
| 13 | #include <mach/dma.h> | ||
| 14 | |||
| 13 | struct mcp_ops; | 15 | struct mcp_ops; |
| 14 | 16 | ||
| 15 | struct mcp { | 17 | struct mcp { |
| @@ -24,6 +26,7 @@ struct mcp { | |||
| 24 | dma_device_t dma_telco_rd; | 26 | dma_device_t dma_telco_rd; |
| 25 | dma_device_t dma_telco_wr; | 27 | dma_device_t dma_telco_wr; |
| 26 | struct device attached_device; | 28 | struct device attached_device; |
| 29 | int gpio_base; | ||
| 27 | }; | 30 | }; |
| 28 | 31 | ||
| 29 | struct mcp_ops { | 32 | struct mcp_ops { |
diff --git a/drivers/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h index a8ad8a0ed5db..aa9c3789bed4 100644 --- a/drivers/mfd/ucb1x00.h +++ b/include/linux/mfd/ucb1x00.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mfd/ucb1x00.h | 2 | * linux/include/mfd/ucb1x00.h |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2001 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2001 Russell King, All Rights Reserved. |
| 5 | * | 5 | * |
| @@ -10,6 +10,9 @@ | |||
| 10 | #ifndef UCB1200_H | 10 | #ifndef UCB1200_H |
| 11 | #define UCB1200_H | 11 | #define UCB1200_H |
| 12 | 12 | ||
| 13 | #include <linux/mfd/mcp.h> | ||
| 14 | #include <linux/gpio.h> | ||
| 15 | |||
| 13 | #define UCB_IO_DATA 0x00 | 16 | #define UCB_IO_DATA 0x00 |
| 14 | #define UCB_IO_DIR 0x01 | 17 | #define UCB_IO_DIR 0x01 |
| 15 | 18 | ||
| @@ -100,7 +103,6 @@ | |||
| 100 | #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) | 103 | #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) |
| 101 | #define UCB_MODE_AUD_OFF_CAN (1 << 13) | 104 | #define UCB_MODE_AUD_OFF_CAN (1 << 13) |
| 102 | 105 | ||
| 103 | #include "mcp.h" | ||
| 104 | 106 | ||
| 105 | struct ucb1x00_irq { | 107 | struct ucb1x00_irq { |
| 106 | void *devid; | 108 | void *devid; |
| @@ -123,6 +125,7 @@ struct ucb1x00 { | |||
| 123 | struct device dev; | 125 | struct device dev; |
| 124 | struct list_head node; | 126 | struct list_head node; |
| 125 | struct list_head devs; | 127 | struct list_head devs; |
| 128 | struct gpio_chip gpio; | ||
| 126 | }; | 129 | }; |
| 127 | 130 | ||
| 128 | struct ucb1x00_driver; | 131 | struct ucb1x00_driver; |
