summaryrefslogtreecommitdiff
path: root/firmware/drivers/pcf50635.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/pcf50635.c')
-rw-r--r--firmware/drivers/pcf50635.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/firmware/drivers/pcf50635.c b/firmware/drivers/pcf50635.c
new file mode 100644
index 0000000000..c436498670
--- /dev/null
+++ b/firmware/drivers/pcf50635.c
@@ -0,0 +1,132 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Rob Purchase
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "pcf50635.h"
22#include "i2c.h"
23#include "system.h"
24
25#define PCF50635_ADDR 0xe6
26
27int pcf50635_write(int address, unsigned char val)
28{
29 unsigned char data[] = { address, val };
30 return i2c_write(PCF50635_ADDR, data, 2);
31}
32
33int pcf50635_write_multiple(int address, const unsigned char* buf, int count)
34{
35 int i;
36
37 for (i = 0; i < count; i++)
38 pcf50635_write(address + i, buf[i]);
39
40 return 0;
41}
42
43int pcf50635_read(int address)
44{
45 unsigned char val = -1;
46 i2c_readmem(PCF50635_ADDR, address, &val, 1);
47 return val;
48}
49
50int pcf50635_read_multiple(int address, unsigned char* buf, int count)
51{
52 return i2c_readmem(PCF50635_ADDR, address, buf, count);
53}
54
55void pcf50635_init(void)
56{
57#ifdef COWON_D2
58 /* Configure outputs as per OF */
59 pcf50635_write(PCF5063X_REG_DOWN1OUT, 0x13); /* DOWN1 = 1.2V */
60 pcf50635_write(PCF5063X_REG_DOWN1CTL, 0x1e); /* DOWN1 DVM step = max */
61 pcf50635_write(PCF5063X_REG_DOWN1ENA, 0x1); /* DOWN1 enable */
62 pcf50635_write(PCF5063X_REG_DOWN2OUT, 0x2f); /* DOWN2 = 1.8V */
63 pcf50635_write(PCF5063X_REG_DOWN2CTL, 0x1e); /* DOWN2 DVM step = max */
64 pcf50635_write(PCF5063X_REG_DOWN2ENA, 0x1); /* DOWN2 enable */
65 pcf50635_write(PCF5063X_REG_AUTOOUT, 0x5f); /* AUTO = 3.0V */
66 pcf50635_write(PCF5063X_REG_AUTOENA, 0x1); /* AUTO enable */
67 pcf50635_write(PCF5063X_REG_LDO1OUT, 0x18); /* LDO1 = 3.3V */
68 pcf50635_write(PCF5063X_REG_LDO1ENA, 0x1); /* LDO1 enable */
69 pcf50635_write(PCF5063X_REG_LDO2OUT, 0x15); /* LDO2 = 3.0V */
70 pcf50635_write(PCF5063X_REG_LDO2ENA, 0x1); /* LDO2 enable */
71 pcf50635_write(PCF5063X_REG_LDO3ENA, 0x0); /* LDO3 disable */
72 pcf50635_write(PCF5063X_REG_LDO4OUT, 0x15); /* LDO4 = 3.0V */
73 pcf50635_write(PCF5063X_REG_LDO4ENA, 0x1); /* LDO4 enable */
74 pcf50635_write(PCF5063X_REG_LDO5OUT, 0x9); /* LDO5 = 1.8V */
75 pcf50635_write(PCF5063X_REG_LDO5ENA, 0x1); /* LDO4 enable */
76 pcf50635_write(PCF5063X_REG_LDO6OUT, 0xc); /* LDO6 = 2.1V */
77 pcf50635_write(PCF5063X_REG_LDO6ENA, 0x1); /* LDO4 enable */
78 pcf50635_write(PCF5063X_REG_HCLDOENA, 0x0); /* HCLDO disable */
79
80 /* Configure automatic battery charging as per OF */
81 pcf50635_write(PCF5063X_REG_MBCC1,
82 pcf50635_read(PCF5063X_REG_MBCC1) | 7); /* auto charge termination & resume */
83 pcf50635_write(PCF5063X_REG_MBCC2, 0xa8); /* Vmax = 4.2V, Vbatcond = 2.7V, long debounce */
84 pcf50635_write(PCF5063X_REG_MBCC3, 0x2a); /* precharge level = 16% */
85 pcf50635_write(PCF5063X_REG_MBCC4, 0x94); /* fastcharge level = 58% */
86 pcf50635_write(PCF5063X_REG_MBCC5, 0xff); /* fastcharge level (usb) = 100% */
87 pcf50635_write(PCF5063X_REG_MBCC6, 0x4); /* cutoff level = 12.5% */
88 pcf50635_write(PCF5063X_REG_MBCC7, 0xc1); /* bat-sysimax = 2.2A, USB = 500mA */
89 pcf50635_write(PCF5063X_REG_BVMCTL, 0xe); /* batok level = 3.4V */
90
91 /* IRQ masks */
92 pcf50635_write(PCF5063X_REG_INT1M, 0x8a); /* enable alarm, usbins, adpins */
93 pcf50635_write(PCF5063X_REG_INT2M, 0xff); /* mask all */
94 pcf50635_write(PCF5063X_REG_INT3M, 0x7f); /* enable onkey1s */
95 pcf50635_write(PCF5063X_REG_INT4M, 0xfd); /* enable lowbat */
96 pcf50635_write(PCF5063X_REG_INT5M, 0xff); /* mask all */
97
98 pcf50635_write(PCF5063X_REG_OOCMODE, 0x0);
99 pcf50635_write(PCF5063X_REG_OOCCTL, 0x2); /* actphrst = phase 3 */
100 pcf50635_write(PCF5063X_REG_OOCWAKE, /* adapter, usb, (rtc) wake */
101 (pcf50635_read(PCF5063X_REG_OOCWAKE) & 0x10) | 0xc1);
102
103 /* We don't care about the GPIOs, disable them */
104 pcf50635_write(PCF5063X_REG_GPIOCTL, 0x0);
105 pcf50635_write(PCF5063X_REG_GPIO1CFG, 0x0);
106 pcf50635_write(PCF5063X_REG_GPIO2CFG, 0x0);
107 pcf50635_write(PCF5063X_REG_GPIO3CFG, 0x0);
108#endif
109}
110
111void pcf50635_read_adc(int adc, short* res1, short* res2)
112{
113 int adcs1 = 0, adcs2 = 0, adcs3 = 0;
114
115 int level = disable_irq_save();
116
117 pcf50635_write(PCF5063X_REG_ADCC1, PCF5063X_ADCC1_ADCSTART | adc);
118
119 do {
120 adcs3 = pcf50635_read(PCF5063X_REG_ADCS3);
121 } while (!(adcs3 & PCF5063X_ADCS3_ADCRDY));
122
123 if (res1 != NULL) adcs1 = pcf50635_read(PCF5063X_REG_ADCS1);
124 if (res2 != NULL) adcs2 = pcf50635_read(PCF5063X_REG_ADCS2);
125
126 pcf50635_write(PCF5063X_REG_ADCC1, 0);
127
128 restore_interrupt(level);
129
130 if (res1 != NULL) *res1 = (adcs1 << 2) | (adcs3 & 3);
131 if (res2 != NULL) *res2 = (adcs2 << 2) | ((adcs3 & 0xC) >> 2);
132}