root/arch/arm/mach-pxa/spitz_pm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. spitz_charger_init
  2. spitz_measure_temp
  3. spitz_charge
  4. spitz_discharge
  5. spitz_discharge1
  6. spitz_presuspend
  7. spitz_postsuspend
  8. spitz_should_wakeup
  9. spitz_charger_wakeup
  10. spitzpm_read_devdata
  11. spitzpm_init
  12. spitzpm_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Battery and Power Management code for the Sharp SL-Cxx00
   4  *
   5  * Copyright (c) 2005 Richard Purdie
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/stat.h>
  10 #include <linux/init.h>
  11 #include <linux/kernel.h>
  12 #include <linux/delay.h>
  13 #include <linux/gpio.h>
  14 #include <linux/gpio-pxa.h>
  15 #include <linux/interrupt.h>
  16 #include <linux/platform_device.h>
  17 #include <linux/apm-emulation.h>
  18 
  19 #include <asm/irq.h>
  20 #include <asm/mach-types.h>
  21 #include <mach/hardware.h>
  22 
  23 #include <mach/spitz.h>
  24 #include "pxa27x.h"
  25 #include "sharpsl_pm.h"
  26 
  27 #include "generic.h"
  28 
  29 #define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
  30 #define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
  31 #define SHARPSL_CHARGE_ON_ACIN_HIGH    0x9b  /* 6V */
  32 #define SHARPSL_CHARGE_ON_ACIN_LOW     0x34  /* 2V */
  33 #define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
  34 #define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
  35 
  36 static int spitz_last_ac_status;
  37 
  38 static struct gpio spitz_charger_gpios[] = {
  39         { SPITZ_GPIO_KEY_INT,   GPIOF_IN, "Keyboard Interrupt" },
  40         { SPITZ_GPIO_SYNC,      GPIOF_IN, "Sync" },
  41         { SPITZ_GPIO_AC_IN,     GPIOF_IN, "Charger Detection" },
  42         { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
  43         { SPITZ_GPIO_JK_B,        GPIOF_OUT_INIT_LOW, "JK B" },
  44         { SPITZ_GPIO_CHRG_ON,     GPIOF_OUT_INIT_LOW, "Charger On" },
  45 };
  46 
  47 static void spitz_charger_init(void)
  48 {
  49         gpio_request_array(ARRAY_AND_SIZE(spitz_charger_gpios));
  50 }
  51 
  52 static void spitz_measure_temp(int on)
  53 {
  54         gpio_set_value(SPITZ_GPIO_ADC_TEMP_ON, on);
  55 }
  56 
  57 static void spitz_charge(int on)
  58 {
  59         if (on) {
  60                 if (sharpsl_pm.flags & SHARPSL_SUSPENDED) {
  61                         gpio_set_value(SPITZ_GPIO_JK_B, 1);
  62                         gpio_set_value(SPITZ_GPIO_CHRG_ON, 0);
  63                 } else {
  64                         gpio_set_value(SPITZ_GPIO_JK_B, 0);
  65                         gpio_set_value(SPITZ_GPIO_CHRG_ON, 0);
  66                 }
  67         } else {
  68                 gpio_set_value(SPITZ_GPIO_JK_B, 0);
  69                 gpio_set_value(SPITZ_GPIO_CHRG_ON, 1);
  70         }
  71 }
  72 
  73 static void spitz_discharge(int on)
  74 {
  75         gpio_set_value(SPITZ_GPIO_JK_A, on);
  76 }
  77 
  78 /* HACK - For unknown reasons, accurate voltage readings are only made with a load
  79    on the power bus which the green led on spitz provides */
  80 static void spitz_discharge1(int on)
  81 {
  82         gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
  83 }
  84 
  85 static unsigned long gpio18_config = GPIO18_GPIO;
  86 
  87 static void spitz_presuspend(void)
  88 {
  89         spitz_last_ac_status = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
  90 
  91         /* GPIO Sleep Register */
  92         PGSR0 = 0x00144018;
  93         PGSR1 = 0x00EF0000;
  94         if (machine_is_akita()) {
  95                 PGSR2 = 0x2121C000;
  96                 PGSR3 = 0x00600400;
  97         } else {
  98                 PGSR2 = 0x0121C000;
  99                 PGSR3 = 0x00600000;
 100         }
 101 
 102         PGSR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
 103         PGSR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
 104         PGSR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
 105         PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
 106         PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
 107 
 108         pxa2xx_mfp_config(&gpio18_config, 1);
 109         gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown");
 110         gpio_free(18);
 111 
 112         PRER = GPIO_bit(SPITZ_GPIO_KEY_INT);
 113         PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
 114         PWER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET) | PWER_RTC;
 115         PKWR = GPIO_bit(SPITZ_GPIO_SYNC) | GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
 116         PKSR = 0xffffffff; /* clear */
 117 
 118         /* nRESET_OUT Disable */
 119         PSLR |= PSLR_SL_ROD;
 120 
 121         /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
 122         PCFR = PCFR_GPR_EN | PCFR_OPDE;
 123 }
 124 
 125 static void spitz_postsuspend(void)
 126 {
 127 }
 128 
 129 static int spitz_should_wakeup(unsigned int resume_on_alarm)
 130 {
 131         int is_resume = 0;
 132         int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
 133 
 134         if (spitz_last_ac_status != acin) {
 135                 if (acin) {
 136                         /* charge on */
 137                         sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
 138                         dev_dbg(sharpsl_pm.dev, "AC Inserted\n");
 139                 } else {
 140                         /* charge off */
 141                         dev_dbg(sharpsl_pm.dev, "AC Removed\n");
 142                         sharpsl_pm_led(SHARPSL_LED_OFF);
 143                         sharpsl_pm.machinfo->charge(0);
 144                         sharpsl_pm.charge_mode = CHRG_OFF;
 145                 }
 146                 spitz_last_ac_status = acin;
 147                 /* Return to suspend as this must be what we were woken for */
 148                 return 0;
 149         }
 150 
 151         if (PEDR & GPIO_bit(SPITZ_GPIO_KEY_INT))
 152                 is_resume |= GPIO_bit(SPITZ_GPIO_KEY_INT);
 153 
 154         if (PKSR & GPIO_bit(SPITZ_GPIO_SYNC))
 155                 is_resume |= GPIO_bit(SPITZ_GPIO_SYNC);
 156 
 157         if (resume_on_alarm && (PEDR & PWER_RTC))
 158                 is_resume |= PWER_RTC;
 159 
 160         dev_dbg(sharpsl_pm.dev, "is_resume: %x\n", is_resume);
 161         return is_resume;
 162 }
 163 
 164 static bool spitz_charger_wakeup(void)
 165 {
 166         return !gpio_get_value(SPITZ_GPIO_KEY_INT) ||
 167                 gpio_get_value(SPITZ_GPIO_SYNC);
 168 }
 169 
 170 unsigned long spitzpm_read_devdata(int type)
 171 {
 172         switch (type) {
 173         case SHARPSL_STATUS_ACIN:
 174                 return !gpio_get_value(SPITZ_GPIO_AC_IN);
 175         case SHARPSL_STATUS_LOCK:
 176                 return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock);
 177         case SHARPSL_STATUS_CHRGFULL:
 178                 return gpio_get_value(sharpsl_pm.machinfo->gpio_batfull);
 179         case SHARPSL_STATUS_FATAL:
 180                 return gpio_get_value(sharpsl_pm.machinfo->gpio_fatal);
 181         case SHARPSL_ACIN_VOLT:
 182                 return sharpsl_pm_pxa_read_max1111(MAX1111_ACIN_VOLT);
 183         case SHARPSL_BATT_TEMP:
 184                 return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_TEMP);
 185         case SHARPSL_BATT_VOLT:
 186         default:
 187                 return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_VOLT);
 188         }
 189 }
 190 
 191 struct sharpsl_charger_machinfo spitz_pm_machinfo = {
 192         .init             = spitz_charger_init,
 193         .exit             = NULL,
 194         .gpio_batlock     = SPITZ_GPIO_BAT_COVER,
 195         .gpio_acin        = SPITZ_GPIO_AC_IN,
 196         .gpio_batfull     = SPITZ_GPIO_CHRG_FULL,
 197         .batfull_irq      = 1,
 198         .gpio_fatal       = SPITZ_GPIO_FATAL_BAT,
 199         .discharge        = spitz_discharge,
 200         .discharge1       = spitz_discharge1,
 201         .charge           = spitz_charge,
 202         .measure_temp     = spitz_measure_temp,
 203         .presuspend       = spitz_presuspend,
 204         .postsuspend      = spitz_postsuspend,
 205         .read_devdata     = spitzpm_read_devdata,
 206         .charger_wakeup   = spitz_charger_wakeup,
 207         .should_wakeup    = spitz_should_wakeup,
 208 #if defined(CONFIG_LCD_CORGI)
 209         .backlight_limit = corgi_lcd_limit_intensity,
 210 #endif
 211         .charge_on_volt   = SHARPSL_CHARGE_ON_VOLT,
 212         .charge_on_temp   = SHARPSL_CHARGE_ON_TEMP,
 213         .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH,
 214         .charge_acin_low  = SHARPSL_CHARGE_ON_ACIN_LOW,
 215         .fatal_acin_volt  = SHARPSL_FATAL_ACIN_VOLT,
 216         .fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
 217         .bat_levels       = 40,
 218         .bat_levels_noac  = sharpsl_battery_levels_noac,
 219         .bat_levels_acin  = sharpsl_battery_levels_acin,
 220         .status_high_acin = 188,
 221         .status_low_acin  = 178,
 222         .status_high_noac = 185,
 223         .status_low_noac  = 175,
 224 };
 225 
 226 static struct platform_device *spitzpm_device;
 227 
 228 static int spitzpm_init(void)
 229 {
 230         int ret;
 231 
 232         if (!machine_is_spitz() && !machine_is_akita()
 233                         && !machine_is_borzoi())
 234                 return -ENODEV;
 235 
 236         spitzpm_device = platform_device_alloc("sharpsl-pm", -1);
 237         if (!spitzpm_device)
 238                 return -ENOMEM;
 239 
 240         spitzpm_device->dev.platform_data = &spitz_pm_machinfo;
 241         ret = platform_device_add(spitzpm_device);
 242 
 243         if (ret)
 244                 platform_device_put(spitzpm_device);
 245 
 246         return ret;
 247 }
 248 
 249 static void spitzpm_exit(void)
 250 {
 251         platform_device_unregister(spitzpm_device);
 252 }
 253 
 254 module_init(spitzpm_init);
 255 module_exit(spitzpm_exit);

/* [<][>][^][v][top][bottom][index][help] */