summaryrefslogtreecommitdiff
path: root/firmware/drivers/pcf50605.c
blob: 122ba6ee3816126ece47f1e660ab897296e8bca7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Driver for pcf50605 PMU and RTC
 *
 * Based on code from the ipodlinux project - http://ipodlinux.org/
 * Adapted for Rockbox in December 2005
 *
 * Original file: linux/arch/armnommu/mach-ipod/pcf50605.c
 *
 * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
 *
 * All files in this archive are subject to the GNU General Public License.
 * See the file COPYING in the source tree root for full license agreement.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/
#include "config.h"
#if CONFIG_I2C == I2C_PP5020
#include "i2c-pp5020.h"
#elif CONFIG_I2C == I2C_PP5002
#include "i2c-pp5002.h"
#endif
#include "rtc.h"

#define OOCS  0x01
#define INT1  0x02
#define INT2  0x03
#define INT3  0x04
#define INT1M 0x05
#define INT2M 0x06
#define INT3M 0x07
#define OOCC1 0x08
  #define GOSTDBY  0x1
  #define TOTRST   (0x1 << 1)
  #define CLK32ON  (0x1 << 2)
  #define WDTRST   (0x1 << 3)
  #define RTCWAK   (0x1 << 4)
  #define CHGWAK   (0x1 << 5)
  #define EXTONWAK (0x01 << 6)
#define OOCC2 0x09
#define RTCSC 0x0a
#define RTCMN 0x0b
#define RTCHR 0x0c
#define RTCWD 0x0d
#define RTCDT 0x0e
#define RTCMT 0x0f
#define RTCYR 0x10
#define RTCSCA 0x11
#define RTCMNA 0x12
#define RTCHRA 0x13
#define RTCWDA 0x14
#define RTCDTA 0x15
#define RTCMTA 0x16
#define RTCYRA 0x17
#define PSSC   0x18
#define PWROKM 0x19
#define PWROKS 0x1a

int pcf50605_read(int address)
{
    return i2c_readbyte(0x8,address);
}

int pcf50605_read_multiple(int address, unsigned char* buf, int count)
{
    int i;

    for (i=0;i<count;i++)
    {
        buf[i]=pcf50605_read(address);
        address++;
    }

    return 0;
}

int pcf50605_write(int address, unsigned char val)
{
    ipod_i2c_send(0x8, address, val);
    return 0;
}

int pcf50605_write_multiple(int address, const unsigned char* buf, int count)
{
    /* TODO */
    (void)address;
    (void)buf;
    (void)count;
    return 0;
}

static int pcf50605_a2d_read(int adc_input)
{
    int hi, lo;

    /* Enable ACD module */
    ipod_i2c_send(0x8, 0x33, 0x80); /* ACDC1, ACDAPE = 1 */

    /* select ADCIN1 - subtractor, and start sampling process */
    ipod_i2c_send(0x8, 0x2f, (adc_input<<1) | 0x1); /* ADCC2, ADCMUX = adc_input, ADCSTART = 1 */

    /* ADCC2, wait for ADCSTART = 0 (wait for sampling to start) */
    while ((i2c_readbyte(0x8, 0x2f) & 1)) /* do nothing */;

    /* ADCS2, wait ADCRDY = 0 (wait for sampling to end) */
    while (!(i2c_readbyte(0x8, 0x31) & 0x80)) /* do nothing */;

    hi = i2c_readbyte(0x8, 0x30);           /* ADCS1 */
    lo = (i2c_readbyte(0x8, 0x31) & 0x3);   /* ADCS2 */

    return (hi << 2) | lo;
}

/* The following command puts the iPod into a deep sleep.  Warning
   from the good people of ipodlinux - never issue this command
   without setting CHGWAK or EXTONWAK if you ever want to be able to
   power on your iPod again. */
void pcf50605_standby_mode(void)
{
    pcf50605_write(OOCC1, GOSTDBY | CHGWAK | EXTONWAK);
}

int pcf50605_battery_read(void)
{
    return pcf50605_a2d_read(0x3);       /* ADCIN1, subtractor */
}

void rtc_init(void)
{
    /* Nothing to do. */
}

int rtc_read_datetime(unsigned char* buf)
{
    int rc;

    rc = pcf50605_read_multiple(0x0a, buf, 7);

    return rc;
}


int rtc_write_datetime(unsigned char* buf)
{
    int i;

    for (i=0;i<7;i++) {
        ipod_i2c_send(0x8, 0x0a+i, buf[i]);
    }

    return 1;
}