1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
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
)
37 for (i
= 0; i
< count
; i
++)
38 pcf50635_write(address
+ i
, buf
[i
]);
43 int pcf50635_read(int address
)
45 unsigned char val
= -1;
46 i2c_readmem(PCF50635_ADDR
, address
, &val
, 1);
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)
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,
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) */
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 */
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);
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
);
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);