summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/i2s-pp.c
blob: c63287b72b5a59ffa8a50e28b4b2d7a4e373023c (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
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Portalplayer specific code for I2S
 *
 * Based on code from the ipodlinux project - http://ipodlinux.org/
 * Adapted for Rockbox in December 2005
 *
 * Original file: linux/arch/armnommu/mach-ipod/audio.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 "system.h"

/* TODO: Add in PP5002 defs */
#if CONFIG_CPU == PP5002
void i2s_reset(void)
{
    /* I2S device reset */
    DEV_RS |= 0x80;
    DEV_RS &= ~0x80;

    /* I2S controller enable */
    IISCONFIG |= 1;

    /* BIT.FORMAT [11:10] = I2S (default) */
    /* BIT.SIZE [9:8] = 24bit */
    /* FIFO.FORMAT = 24 bit LSB */

    /* reset DAC and ADC fifo */
    IISFIFO_CFG |= 0x30000;
}
#else /* PP502X */

/* All I2S formats send MSB first */

/* Data format on the I2S bus */
#define FORMAT_MASK  (0x3 << 10)
#define FORMAT_I2S   (0x0 << 10) /* Standard I2S - leading dummy bit */
#define FORMAT_1     (0x1 << 10)
#define FORMAT_LJUST (0x2 << 10) /* Left justified - no dummy bit */
#define FORMAT_3     (0x3 << 10)
/* Other formats not yet known  */

/* Data size on I2S bus */
#define SIZE_MASK   (0x3 << 8)
#define SIZE_16BIT  (0x0 << 8)
/* Other sizes not yet known */

/* Data size/format on I2S FIFO */
#define FIFO_FORMAT_MASK    (0x7 << 4)
#define FIFO_FORMAT_0       (0x0 << 4)
/* Big-endian formats - data sent to the FIFO must be big endian.
 * I forgot which is which size but did test them. */
#define FIFO_FORMAT_1       (0x1 << 4)
#define FIFO_FORMAT_2       (0x2 << 4)
 /* 32bit-MSB-little endian */
#define FIFO_FORMAT_LE32 (0x3 << 4)
 /* 16bit-MSB-little endian */
#define FIFO_FORMAT_LE16 (0x4 << 4)

/* FIFO formats 0x5 and above seem equivalent to 0x4 ?? */

/**
 * PP502x
 *
 * IISCONFIG bits:
 * |   31   |   30   |   29   |   28   |   27   |   26   |   25   |   24   |
 * | RESET  |        |TXFIFOEN|RXFIFOEN|        |  ????  |   MS   |  ????  |
 * |   23   |   22   |   21   |   20   |   19   |   18   |   17   |   16   |
 * |        |        |        |        |        |        |        |        |
 * |   15   |   14   |   13   |   12   |   11   |   10   |    9   |    8   |
 * |        |        |        |        | Bus Format[1:0] |     Size[1:0]   |
 * |    7   |    6   |    5   |    4   |    3   |    2   |    1   |    0   |
 * |        |     Size Format[2:0]     |  ????  |  ????  | IRQTX  | IRQRX  |
 *
 * IISFIFO_CFG bits:
 * |   31   |   30   |   29   |   28   |   27   |   26   |   25   |   24   |
 * |        |                         Free[6:0]                            |
 * |   23   |   22   |   21   |   20   |   19   |   18   |   17   |   16   |
 * |        |        |        |        |        |        |        |        |
 * |   15   |   14   |   13   |   12   |   11   |   10   |    9   |    8   |
 * |        |        |        | RXCLR  |        |        |        | TXCLR  |
 * |    7   |    6   |    5   |    4   |    3   |    2   |    1   |    0   |
 * |        |        |   RX_ATN_LEVEL  |        |        |   TX_ATN_LEVEL  |
 */

/* Are we I2S Master or slave? */
#define I2S_MASTER (1<<25)

#define I2S_RESET (0x1 << 31)

/*
 * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit
 */
void i2s_reset(void)
{
    /* I2S soft reset */
    IISCONFIG |= I2S_RESET;
    IISCONFIG &= ~I2S_RESET;

    /* BIT.FORMAT */
    IISCONFIG = ((IISCONFIG & ~FORMAT_MASK) | FORMAT_I2S);

    /* BIT.SIZE */
    IISCONFIG = ((IISCONFIG & ~SIZE_MASK) | SIZE_16BIT);

    /* FIFO.FORMAT */
    /* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */
#ifdef HAVE_AS3514
    /* AS3514 can only operate as I2S Slave */
    IISCONFIG |= I2S_MASTER;
    /* Set I2S to 44.1kHz */
    outl((inl(0x70002808) & ~(0x1ff)) | 33, 0x70002808);
    outl(7, 0x60006080);

    IISCONFIG = ((IISCONFIG & ~FIFO_FORMAT_MASK) | FIFO_FORMAT_LE16);
#else
    IISCONFIG = ((IISCONFIG & ~FIFO_FORMAT_MASK) | FIFO_FORMAT_LE32);
#endif

    /* RX_ATN_LVL=1 == when 12 slots full */
    /* TX_ATN_LVL=1 == when 12 slots empty */
    IISFIFO_CFG |= 0x33;

    /* Rx.CLR = 1, TX.CLR = 1 */
    IISFIFO_CFG |= 0x1100;
}
#endif