summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/as3525/ascodec-target.h
blob: a92fea9f614468805bb2136120fa9ea6f7cdb48b (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 AS3514 audio codec
 *
 * Copyright (c) 2007 Daniel Ankers
 * Copyright (c) 2007 Christian Gmeiner
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

#ifndef _ASCODEC_TARGET_H
#define _ASCODEC_TARGET_H

#ifndef SIMULATOR

#include "as3514.h"
#include "kernel.h"       /* for struct wakeup */
#include "clock-target.h" /* for AS3525_I2C_PRESCALER */
#include "system-arm.h"

/*  Charge Pump and Power management Settings  */
#define AS314_CP_DCDC3_SETTING    \
               ((0<<7) |  /* CP_SW  Auto-Switch Margin 0=200/300 1=150/255 */  \
                (0<<6) |  /* CP_on  0=Normal op 1=Chg Pump Always On  */       \
                (0<<5) |  /* LREG_CPnot  Always write 0 */                     \
                (0<<3) |  /* DCDC3p  BVDD setting 3.6/3.2/3.1/3.0  */          \
                (1<<2) |  /* LREG_off 1=Auto mode switching 0=Length Reg only*/\
                (0<<0) )  /* CVDDp  Core Voltage Setting 1.2/1.15/1.10/1.05*/

#define CVDD_1_20          0
#define CVDD_1_15          1
#define CVDD_1_10          2
#define CVDD_1_05          3

#define ASCODEC_REQ_READ   0
#define ASCODEC_REQ_WRITE  1

/*
 * How many bytes we using in struct ascodec_request for the data buffer.
 * 4 fits the alignment best right now.
 * We don't actually use more than 3 at the moment (when reading interrupts)
 * Upper limit would be 255 since DACNT is 8 bits!
 */
#define ASCODEC_REQ_MAXLEN 4

typedef void (ascodec_cb_fn)(unsigned const char *data, unsigned cnt);

struct ascodec_request {
    unsigned char type;
    unsigned char index;
    unsigned char status;
    unsigned char cnt;
    unsigned char data[ASCODEC_REQ_MAXLEN];
    struct wakeup wkup;
    ascodec_cb_fn *callback;
    struct ascodec_request *next;
};

void ascodec_init(void) INIT_ATTR;

int ascodec_write(unsigned int index, unsigned int value);

int ascodec_read(unsigned int index);

int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data);

/*
 * The request struct passed in must be allocated statically.
 * If you call ascodec_async_write from different places, each
 * call needs it's own request struct.
 * This comment is duplicated in .c and .h for your convenience.
 */
void ascodec_async_write(unsigned index, unsigned int value, struct ascodec_request *req);

/*
 * The request struct passed in must be allocated statically.
 * If you call ascodec_async_read from different places, each
 * call needs it's own request struct.
 * If len is bigger than ASCODEC_REQ_MAXLEN it will be
 * set to ASCODEC_REQ_MAXLEN.
 * This comment is duplicated in .c and .h for your convenience.
 */
void ascodec_async_read(unsigned index, unsigned int len,
                        struct ascodec_request *req, ascodec_cb_fn *cb);

void ascodec_req_init(struct ascodec_request *req, int type,
                      unsigned int index, unsigned int cnt);

void ascodec_submit(struct ascodec_request *req);

void ascodec_lock(void);

void ascodec_unlock(void);

void ascodec_wait_adc_finished(void);

static inline void ascodec_monitor_endofch(void) {} /* already enabled */

bool ascodec_endofch(void);

bool ascodec_chg_status(void);

#if CONFIG_CPU == AS3525v2
static inline void ascodec_write_pmu(unsigned int index, unsigned int subreg,
                                     unsigned int value)
{
    /* we disable interrupts to make sure no operation happen on the i2c bus
     * between selecting the sub register and writing to it */
    int oldstatus = disable_irq_save();
    ascodec_write(AS3543_PMU_ENABLE, 8|subreg);
    ascodec_write(index, value);
    restore_irq(oldstatus);
}

static inline int ascodec_read_pmu(unsigned int index, unsigned int subreg)
{
    /* we disable interrupts to make sure no operation happen on the i2c bus
     * between selecting the sub register and reading it */
    int oldstatus = disable_irq_save();
    ascodec_write(AS3543_PMU_ENABLE, subreg);
    int ret = ascodec_read(index);
    restore_irq(oldstatus);
    return ret;
}
#endif /* CONFIG_CPU == AS3525v2 */

static inline void ascodec_write_charger(int value)
{
#if CONFIG_CPU == AS3525
    ascodec_write(AS3514_CHARGER, value);
#else
    ascodec_write_pmu(AS3543_CHARGER, 1, value);
#endif
}

static inline int ascodec_read_charger(void)
{
#if CONFIG_CPU == AS3525
    return ascodec_read(AS3514_CHARGER);
#else
    return ascodec_read_pmu(AS3543_CHARGER, 1);
#endif
}

#endif /* !SIMULATOR */

#endif /* !_ASCODEC_TARGET_H */