Trim down peak calculation a bit.
[kugel-rb.git] / firmware / drivers / pcf50635.c
blob9ccf5e29e26be382fef7c1f7ae715701f88cb497
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2009 by Rob Purchase
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "pcf50635.h"
22 #include "i2c.h"
23 #include "system.h"
25 #define PCF50635_ADDR 0xe6
27 int pcf50635_write(int address, unsigned char val)
29 unsigned char data[] = { address, val };
30 return i2c_write(PCF50635_ADDR, data, 2);
33 int pcf50635_write_multiple(int address, const unsigned char* buf, int count)
35 int i;
37 for (i = 0; i < count; i++)
38 pcf50635_write(address + i, buf[i]);
40 return 0;
43 int pcf50635_read(int address)
45 unsigned char val = -1;
46 i2c_readmem(PCF50635_ADDR, address, &val, 1);
47 return val;
50 int pcf50635_read_multiple(int address, unsigned char* buf, int count)
52 return i2c_readmem(PCF50635_ADDR, address, buf, count);
55 void pcf50635_init(void)
57 #ifdef COWON_D2
58 static const char init_data[] =
60 /* DOWN1: 1.2V, max DVM step, enabled */
61 PCF5063X_REG_DOWN1OUT, 0x13,
62 PCF5063X_REG_DOWN1CTL, 0x1e,
63 PCF5063X_REG_DOWN1ENA, 0x1,
65 /* DOWN2: 1.8V, max DVM step, enabled */
66 PCF5063X_REG_DOWN2OUT, 0x2f,
67 PCF5063X_REG_DOWN2CTL, 0x1e,
68 PCF5063X_REG_DOWN2ENA, 0x1,
70 /* AUTO: 3.0V, enabled */
71 PCF5063X_REG_AUTOOUT, 0x5f,
72 PCF5063X_REG_AUTOENA, 0x1,
74 /* LDO1: 3.3V, enabled */
75 PCF5063X_REG_LDO1OUT, 0x18,
76 PCF5063X_REG_LDO1ENA, 0x1,
78 /* LDO2: 3.0V, enabled */
79 PCF5063X_REG_LDO2OUT, 0x15,
80 PCF5063X_REG_LDO2ENA, 0x1,
82 /* LDO4: 3.0V, enabled */
83 PCF5063X_REG_LDO4OUT, 0x15,
84 PCF5063X_REG_LDO4ENA, 0x1,
86 /* LDO5: 1.8V, enabled */
87 PCF5063X_REG_LDO5OUT, 0x9,
88 PCF5063X_REG_LDO5ENA, 0x1,
90 /* LDO6: 2.1V, enabled */
91 PCF5063X_REG_LDO6OUT, 0xc,
92 PCF5063X_REG_LDO6ENA, 0x1,
94 /* LDO3 and HCLDO disabled */
95 PCF5063X_REG_LDO3ENA, 0x0,
96 PCF5063X_REG_HCLDOENA, 0x0,
98 /* Disable GPIOs */
99 PCF5063X_REG_GPIOCTL, 0x0,
100 PCF5063X_REG_GPIO1CFG, 0x0,
101 PCF5063X_REG_GPIO2CFG, 0x0,
102 PCF5063X_REG_GPIO3CFG, 0x0,
104 /* IRQ masks (OF values in brackets) */
105 PCF5063X_REG_INT1M, 0xff, /* (0x8a enable alarm, usbins, adpins) */
106 PCF5063X_REG_INT2M, 0xff, /* (0xff all masked) */
107 PCF5063X_REG_INT3M, 0xff, /* (0x7f enable onkey1s) */
108 PCF5063X_REG_INT4M, 0xff, /* (0xfd enable lowbat) */
109 PCF5063X_REG_INT5M, 0xff, /* (0xff all masked) */
111 /* Wakeup mode */
112 PCF5063X_REG_OOCMODE, 0x0, /* onkey falling edge */
113 PCF5063X_REG_OOCCTL, 0x2, /* actphrst = phase 3 */
114 PCF5063X_REG_OOCWAKE, 0xc1, /* wakeup on adapter, usb, onkey */
116 /* Configure battery charger as per OF */
117 PCF5063X_REG_MBCC2, 0xa8, /* Vmax = 4.2V, Vbatcond = 2.7V, long debounce */
118 PCF5063X_REG_MBCC3, 0x2a, /* precharge level = 16% */
119 PCF5063X_REG_MBCC4, 0x94, /* fastcharge level = 58% */
120 PCF5063X_REG_MBCC5, 0xff, /* fastcharge level (usb) = 100% */
121 PCF5063X_REG_MBCC6, 0x4, /* cutoff level = 12.5% */
122 PCF5063X_REG_MBCC7, 0xc1, /* bat-sysImax = 2.2A, USB = 500mA */
123 PCF5063X_REG_BVMCTL, 0xe, /* batok level = 3.4V */
125 /* end marker */
128 const char* ptr;
129 for (ptr = init_data; *ptr != 0; ptr += 2)
130 pcf50635_write(ptr[0], ptr[1]);
132 /* Enable automatic charging, preserving default values */
133 pcf50635_write(PCF5063X_REG_MBCC1,
134 pcf50635_read(PCF5063X_REG_MBCC1) | 7);
136 #endif
139 void pcf50635_read_adc(int adc, short* res1, short* res2)
141 int adcs1 = 0, adcs2 = 0, adcs3 = 0;
143 int level = disable_irq_save();
145 pcf50635_write(PCF5063X_REG_ADCC1, PCF5063X_ADCC1_ADCSTART | adc);
147 do {
148 adcs3 = pcf50635_read(PCF5063X_REG_ADCS3);
149 } while (!(adcs3 & PCF5063X_ADCS3_ADCRDY));
151 if (res1 != NULL) adcs1 = pcf50635_read(PCF5063X_REG_ADCS1);
152 if (res2 != NULL) adcs2 = pcf50635_read(PCF5063X_REG_ADCS2);
154 pcf50635_write(PCF5063X_REG_ADCC1, 0);
156 restore_interrupt(level);
158 if (res1 != NULL) *res1 = (adcs1 << 2) | (adcs3 & 3);
159 if (res2 != NULL) *res2 = (adcs2 << 2) | ((adcs3 & 0xC) >> 2);