On Tue, Feb 21, 2012 at 9:15 PM, Marko Katić <drom...@gmail.com> wrote:
> This experimental patch enables offline charging. It was tested on a C-1000
> and it applies to 3.2.0. Basically, i reintroduced the old way of reading
> the MAX1111 chip, as it was done in older kernels (older than 2.6.34 i
> think). This is by no means an ideal solution. The real problem was detailed
> earlier in this post:
>
> http://lists.linuxtogo.org/pipermail/zaurus-devel/2010-July/000346.html
>
> Sharpsl_pm debug output after suspend:
>
> sharpsl-pm sharpsl-pm: SharpSL suspending for first time.
> sharpsl-pm sharpsl-pm: Time is: 000009ed
> sharpsl-pm sharpsl-pm: Offline Charge Activate = 16
> sharpsl-pm sharpsl-pm: Activating Offline Charger...
> sharpsl-pm sharpsl-pm: Charge Mode: 0
> sharpsl-pm sharpsl-pm: Offline Charger: Step 1
> sharpsl-pm sharpsl-pm: Average: 130 from values: 130, 131, 131, 130, 130
> sharpsl-pm sharpsl-pm: AC Voltage: 130
> sharpsl-pm sharpsl-pm: Average: 122 from values: 122, 122, 122, 123, 123
> sharpsl-pm sharpsl-pm: Temperature: 122
> sharpsl-pm sharpsl-pm: Charge LED On
> sharpsl-pm sharpsl-pm: Charging alarm at: 00000c45
> sharpsl-pm sharpsl-pm: Corgi woken up from suspend: 00000001
> sharpsl-pm sharpsl-pm: SharpSL resuming...
>
> So the output suggests that offline charging is active, yet both leds are
> turned off during suspend. So i discharged the battery as much as i could
> and i left it to charge during suspend for two hours. The battery went from
> ~4.8V to ~5.3V in that period. At least that's what my multimeter claims.
> I'm not skilled in electronics, someone else should test this further.
>
> Here's the patch:
>
> diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
> index 32318ba..ece52e2 100644
> --- a/arch/arm/mach-pxa/sharpsl_pm.c
> +++ b/arch/arm/mach-pxa/sharpsl_pm.c
> @@ -12,7 +12,7 @@
>   *
>   */
>
> -#undef DEBUG
> +#define DEBUG
>
>  #include <linux/module.h>
>  #include <linux/kernel.h>
> @@ -24,12 +24,14 @@
>  #include <linux/leds.h>
>  #include <linux/suspend.h>
>  #include <linux/gpio.h>
> -
> +#include <linux/pxa2xx_ssp.h>
>  #include <asm/mach-types.h>
>  #include <mach/pm.h>
>  #include <mach/pxa2xx-regs.h>
>  #include <mach/regs-rtc.h>
>  #include <mach/sharpsl_pm.h>
> +#include <mach/gpio-pxa.h>
> +#include <mach/spitz.h>
>
>  /*
>   * Prototypes
> @@ -154,18 +156,139 @@ struct battery_thresh sharpsl_battery_levels_noac[] =
> {
>  /*
>   * Read MAX1111 ADC
>   */
> +
> +#define SSP2_REGS_START 0x41700000
> +#define SSP2_REG_SIZE 64
> +#define TIMEOUT 100000
> +#define SSCR0_SerClkDiv(x) (((x) - 1) << 8)
> +
> +static void __iomem *ssp2_reg_base;
> +static volatile unsigned int sscr0, sscr1;
> +struct mutex ssp_lock;
> +
> +static void init_ssp2() {
> + ssp2_reg_base = ioremap(SSP2_REGS_START, SSP2_REG_SIZE);
> +}
> +
> +static void ssp_enable()
> +{
> + *((u32 *)ssp2_reg_base + SSCR0) |= SSCR0_SSE;
> +}
> +
> +static void ssp_disable()
> +{
> + *((u32 *)ssp2_reg_base + SSCR0) &= ~SSCR0_SSE;
> +}
> +
> +static int ssp_read_word(u32 *data) {
> +
> + int timeout = TIMEOUT;
> +
> + while (!(__raw_readl(ssp2_reg_base + SSSR) & SSSR_RNE)) {
> +        if (!--timeout)
> +         return -ETIMEDOUT;
> + cpu_relax();
> + }
> +
> + *data = __raw_readl(ssp2_reg_base + SSDR);
> + return 0;
> +}
> +
> +static int ssp_write_word(u32 data) {
> + int timeout = TIMEOUT;
> +
> + while (!(__raw_readl(ssp2_reg_base + SSSR) & SSSR_TNF)) {
> +        if (!--timeout)
> +         return -ETIMEDOUT;
> + cpu_relax();
> + }
> +
> + __raw_writel(data, ssp2_reg_base + SSDR);
> +
> + return 0;
> +}
> +
> +static void save_sscr() {
> + sscr0 = *((u32 *)ssp2_reg_base + SSCR0);
> + sscr1 = *((u32 *)ssp2_reg_base + SSCR1);
> +}
> +
> +static void restore_sscr () {
> + *((u32 *)ssp2_reg_base + SSCR0) = sscr0;
> + *((u32 *)ssp2_reg_base + SSCR1) = sscr1;
> +}
> +
> +static void ssp_config () {
> + *((u32 *)ssp2_reg_base + SSCR0) = (SSCR0_Motorola | (SSCR0_DSS & 0x07) |
> SSCR0_SerClkDiv(56));
> + *((u32 *)ssp2_reg_base + SSCR1) = 0x0;
> +}
> +
> +static int max1111_raw_read(int channel) {
> +
> +
> + CKEN |= (1 << 3);
> + long voltage = 0, voltage1 = 0, voltage2 = 0;
> +
> + save_sscr();
> + ssp_disable();
> + ssp_config();
> + mdelay(1);
> + ssp_enable();
> +
> + int max1111_cmd = (channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
> + | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR;
> +
> + gpio_set_value(SPITZ_GPIO_MAX1111_CS, 0); /*pull CS low */
> + /* TB1/RB1 */
> + ssp_write_word(max1111_cmd);
> + ssp_read_word((u32*)&voltage1); /* null read */
> +
> + /* TB12/RB2 */
> + ssp_write_word(0);
> + ssp_read_word((u32*)&voltage1);
> +
> + /* TB13/RB3*/
> + ssp_write_word(0);
> + ssp_read_word((u32*)&voltage2);
> +
> + gpio_set_value(SPITZ_GPIO_MAX1111_CS, 1);
> +
> + ssp_disable();
> + restore_sscr();
> + ssp_enable();
> +
> + CKEN &= ~(1 << 3);
> +
> + if ((voltage1 & 0xc0) || (voltage2 & 0x3f))
> + voltage = -1;
> + else
> + voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
> +
> + if (voltage <= 0)
> + printk (KERN_ALERT "voltage raw %d\n", voltage);
> +
> + return voltage;
> +}
> +
>  int sharpsl_pm_pxa_read_max1111(int channel)
>  {
> +
>   /* Ugly, better move this function into another module */
>   if (machine_is_tosa())
>      return 0;
>
> + int ret;
>   extern int max1111_read_channel(int);
> -
>   /* max1111 accepts channels from 0-3, however,
>   * it is encoded from 0-7 here in the code.
>   */
> - return max1111_read_channel(channel >> 1);
> + ret = max1111_read_channel(channel >> 1);
> +
> + if (ret <= 0)
> + return max1111_raw_read(channel);
> + else
> + return ret;
> +
>  }
>
>  static int get_percentage(int voltage)
> @@ -926,6 +1049,8 @@ static int __devinit sharpsl_pm_probe(struct
> platform_device *pdev)
>   suspend_set_ops(&sharpsl_pm_ops);
>  #endif
>
> + init_ssp2();
> +
>   mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
>
>   return 0;
> @@ -959,6 +1084,8 @@ static int sharpsl_pm_remove(struct platform_device
> *pdev)
>   del_timer_sync(&sharpsl_pm.chrg_full_timer);
>   del_timer_sync(&sharpsl_pm.ac_timer);
>
> + iounmap(ssp2_reg_base);
> +
>   return 0;
>  }
>
>
>
> _______________________________________________
> Zaurus-devel mailing list
> Zaurus-devel@lists.linuxtogo.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/zaurus-devel
>

I'll send the meta-handheld Zaurus defconfigs for 3.2.8 this evening.
Then testing your patch will be easier.

Cheers

Andrea

_______________________________________________
Zaurus-devel mailing list
Zaurus-devel@lists.linuxtogo.org
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/zaurus-devel

Reply via email to