diff options
Diffstat (limited to 'sound/aoa/soundbus/i2sbus/interface.h')
-rw-r--r-- | sound/aoa/soundbus/i2sbus/interface.h | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/sound/aoa/soundbus/i2sbus/interface.h b/sound/aoa/soundbus/i2sbus/interface.h new file mode 100644 index 000000000000..c6b5f5452d20 --- /dev/null +++ b/sound/aoa/soundbus/i2sbus/interface.h | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * i2sbus driver -- interface register definitions | ||
3 | * | ||
4 | * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * | ||
6 | * GPL v2, can be found in COPYING. | ||
7 | */ | ||
8 | #ifndef __I2SBUS_INTERFACE_H | ||
9 | #define __I2SBUS_INTERFACE_H | ||
10 | |||
11 | /* i2s bus control registers, at least what we know about them */ | ||
12 | |||
13 | #define __PAD(m,n) u8 __pad##m[n] | ||
14 | #define _PAD(line, n) __PAD(line, n) | ||
15 | #define PAD(n) _PAD(__LINE__, (n)) | ||
16 | struct i2s_interface_regs { | ||
17 | __le32 intr_ctl; /* 0x00 */ | ||
18 | PAD(12); | ||
19 | __le32 serial_format; /* 0x10 */ | ||
20 | PAD(12); | ||
21 | __le32 codec_msg_out; /* 0x20 */ | ||
22 | PAD(12); | ||
23 | __le32 codec_msg_in; /* 0x30 */ | ||
24 | PAD(12); | ||
25 | __le32 frame_count; /* 0x40 */ | ||
26 | PAD(12); | ||
27 | __le32 frame_match; /* 0x50 */ | ||
28 | PAD(12); | ||
29 | __le32 data_word_sizes; /* 0x60 */ | ||
30 | PAD(12); | ||
31 | __le32 peak_level_sel; /* 0x70 */ | ||
32 | PAD(12); | ||
33 | __le32 peak_level_in0; /* 0x80 */ | ||
34 | PAD(12); | ||
35 | __le32 peak_level_in1; /* 0x90 */ | ||
36 | PAD(12); | ||
37 | /* total size: 0x100 bytes */ | ||
38 | } __attribute__((__packed__)); | ||
39 | |||
40 | /* interrupt register is just a bitfield with | ||
41 | * interrupt enable and pending bits */ | ||
42 | #define I2S_REG_INTR_CTL 0x00 | ||
43 | # define I2S_INT_FRAME_COUNT (1<<31) | ||
44 | # define I2S_PENDING_FRAME_COUNT (1<<30) | ||
45 | # define I2S_INT_MESSAGE_FLAG (1<<29) | ||
46 | # define I2S_PENDING_MESSAGE_FLAG (1<<28) | ||
47 | # define I2S_INT_NEW_PEAK (1<<27) | ||
48 | # define I2S_PENDING_NEW_PEAK (1<<26) | ||
49 | # define I2S_INT_CLOCKS_STOPPED (1<<25) | ||
50 | # define I2S_PENDING_CLOCKS_STOPPED (1<<24) | ||
51 | # define I2S_INT_EXTERNAL_SYNC_ERROR (1<<23) | ||
52 | # define I2S_PENDING_EXTERNAL_SYNC_ERROR (1<<22) | ||
53 | # define I2S_INT_EXTERNAL_SYNC_OK (1<<21) | ||
54 | # define I2S_PENDING_EXTERNAL_SYNC_OK (1<<20) | ||
55 | # define I2S_INT_NEW_SAMPLE_RATE (1<<19) | ||
56 | # define I2S_PENDING_NEW_SAMPLE_RATE (1<<18) | ||
57 | # define I2S_INT_STATUS_FLAG (1<<17) | ||
58 | # define I2S_PENDING_STATUS_FLAG (1<<16) | ||
59 | |||
60 | /* serial format register is more interesting :) | ||
61 | * It contains: | ||
62 | * - clock source | ||
63 | * - MClk divisor | ||
64 | * - SClk divisor | ||
65 | * - SClk master flag | ||
66 | * - serial format (sony, i2s 64x, i2s 32x, dav, silabs) | ||
67 | * - external sample frequency interrupt (don't understand) | ||
68 | * - external sample frequency | ||
69 | */ | ||
70 | #define I2S_REG_SERIAL_FORMAT 0x10 | ||
71 | /* clock source. You get either 18.432, 45.1584 or 49.1520 MHz */ | ||
72 | # define I2S_SF_CLOCK_SOURCE_SHIFT 30 | ||
73 | # define I2S_SF_CLOCK_SOURCE_MASK (3<<I2S_SF_CLOCK_SOURCE_SHIFT) | ||
74 | # define I2S_SF_CLOCK_SOURCE_18MHz (0<<I2S_SF_CLOCK_SOURCE_SHIFT) | ||
75 | # define I2S_SF_CLOCK_SOURCE_45MHz (1<<I2S_SF_CLOCK_SOURCE_SHIFT) | ||
76 | # define I2S_SF_CLOCK_SOURCE_49MHz (2<<I2S_SF_CLOCK_SOURCE_SHIFT) | ||
77 | /* also, let's define the exact clock speeds here, in Hz */ | ||
78 | #define I2S_CLOCK_SPEED_18MHz 18432000 | ||
79 | #define I2S_CLOCK_SPEED_45MHz 45158400 | ||
80 | #define I2S_CLOCK_SPEED_49MHz 49152000 | ||
81 | /* MClk is the clock that drives the codec, usually called its 'system clock'. | ||
82 | * It is derived by taking only every 'divisor' tick of the clock. | ||
83 | */ | ||
84 | # define I2S_SF_MCLKDIV_SHIFT 24 | ||
85 | # define I2S_SF_MCLKDIV_MASK (0x1F<<I2S_SF_MCLKDIV_SHIFT) | ||
86 | # define I2S_SF_MCLKDIV_1 (0x14<<I2S_SF_MCLKDIV_SHIFT) | ||
87 | # define I2S_SF_MCLKDIV_3 (0x13<<I2S_SF_MCLKDIV_SHIFT) | ||
88 | # define I2S_SF_MCLKDIV_5 (0x12<<I2S_SF_MCLKDIV_SHIFT) | ||
89 | # define I2S_SF_MCLKDIV_14 (0x0E<<I2S_SF_MCLKDIV_SHIFT) | ||
90 | # define I2S_SF_MCLKDIV_OTHER(div) (((div/2-1)<<I2S_SF_MCLKDIV_SHIFT)&I2S_SF_MCLKDIV_MASK) | ||
91 | static inline int i2s_sf_mclkdiv(int div, int *out) | ||
92 | { | ||
93 | int d; | ||
94 | |||
95 | switch(div) { | ||
96 | case 1: *out |= I2S_SF_MCLKDIV_1; return 0; | ||
97 | case 3: *out |= I2S_SF_MCLKDIV_3; return 0; | ||
98 | case 5: *out |= I2S_SF_MCLKDIV_5; return 0; | ||
99 | case 14: *out |= I2S_SF_MCLKDIV_14; return 0; | ||
100 | default: | ||
101 | if (div%2) return -1; | ||
102 | d = div/2-1; | ||
103 | if (d == 0x14 || d == 0x13 || d == 0x12 || d == 0x0E) | ||
104 | return -1; | ||
105 | *out |= I2S_SF_MCLKDIV_OTHER(div); | ||
106 | return 0; | ||
107 | } | ||
108 | } | ||
109 | /* SClk is the clock that drives the i2s wire bus. Note that it is | ||
110 | * derived from the MClk above by taking only every 'divisor' tick | ||
111 | * of MClk. | ||
112 | */ | ||
113 | # define I2S_SF_SCLKDIV_SHIFT 20 | ||
114 | # define I2S_SF_SCLKDIV_MASK (0xF<<I2S_SF_SCLKDIV_SHIFT) | ||
115 | # define I2S_SF_SCLKDIV_1 (8<<I2S_SF_SCLKDIV_SHIFT) | ||
116 | # define I2S_SF_SCLKDIV_3 (9<<I2S_SF_SCLKDIV_SHIFT) | ||
117 | # define I2S_SF_SCLKDIV_OTHER(div) (((div/2-1)<<I2S_SF_SCLKDIV_SHIFT)&I2S_SF_SCLKDIV_MASK) | ||
118 | static inline int i2s_sf_sclkdiv(int div, int *out) | ||
119 | { | ||
120 | int d; | ||
121 | |||
122 | switch(div) { | ||
123 | case 1: *out |= I2S_SF_SCLKDIV_1; return 0; | ||
124 | case 3: *out |= I2S_SF_SCLKDIV_3; return 0; | ||
125 | default: | ||
126 | if (div%2) return -1; | ||
127 | d = div/2-1; | ||
128 | if (d == 8 || d == 9) return -1; | ||
129 | *out |= I2S_SF_SCLKDIV_OTHER(div); | ||
130 | return 0; | ||
131 | } | ||
132 | } | ||
133 | # define I2S_SF_SCLK_MASTER (1<<19) | ||
134 | /* serial format is the way the data is put to the i2s wire bus */ | ||
135 | # define I2S_SF_SERIAL_FORMAT_SHIFT 16 | ||
136 | # define I2S_SF_SERIAL_FORMAT_MASK (7<<I2S_SF_SERIAL_FORMAT_SHIFT) | ||
137 | # define I2S_SF_SERIAL_FORMAT_SONY (0<<I2S_SF_SERIAL_FORMAT_SHIFT) | ||
138 | # define I2S_SF_SERIAL_FORMAT_I2S_64X (1<<I2S_SF_SERIAL_FORMAT_SHIFT) | ||
139 | # define I2S_SF_SERIAL_FORMAT_I2S_32X (2<<I2S_SF_SERIAL_FORMAT_SHIFT) | ||
140 | # define I2S_SF_SERIAL_FORMAT_I2S_DAV (4<<I2S_SF_SERIAL_FORMAT_SHIFT) | ||
141 | # define I2S_SF_SERIAL_FORMAT_I2S_SILABS (5<<I2S_SF_SERIAL_FORMAT_SHIFT) | ||
142 | /* unknown */ | ||
143 | # define I2S_SF_EXT_SAMPLE_FREQ_INT_SHIFT 12 | ||
144 | # define I2S_SF_EXT_SAMPLE_FREQ_INT_MASK (0xF<<I2S_SF_SAMPLE_FREQ_INT_SHIFT) | ||
145 | /* probably gives external frequency? */ | ||
146 | # define I2S_SF_EXT_SAMPLE_FREQ_MASK 0xFFF | ||
147 | |||
148 | /* used to send codec messages, but how isn't clear */ | ||
149 | #define I2S_REG_CODEC_MSG_OUT 0x20 | ||
150 | |||
151 | /* used to receive codec messages, but how isn't clear */ | ||
152 | #define I2S_REG_CODEC_MSG_IN 0x30 | ||
153 | |||
154 | /* frame count reg isn't clear to me yet, but probably useful */ | ||
155 | #define I2S_REG_FRAME_COUNT 0x40 | ||
156 | |||
157 | /* program to some value, and get interrupt if frame count reaches it */ | ||
158 | #define I2S_REG_FRAME_MATCH 0x50 | ||
159 | |||
160 | /* this register describes how the bus transfers data */ | ||
161 | #define I2S_REG_DATA_WORD_SIZES 0x60 | ||
162 | /* number of interleaved input channels */ | ||
163 | # define I2S_DWS_NUM_CHANNELS_IN_SHIFT 24 | ||
164 | # define I2S_DWS_NUM_CHANNELS_IN_MASK (0x1F<<I2S_DWS_NUM_CHANNELS_IN_SHIFT) | ||
165 | /* word size of input data */ | ||
166 | # define I2S_DWS_DATA_IN_SIZE_SHIFT 16 | ||
167 | # define I2S_DWS_DATA_IN_16BIT (0<<I2S_DWS_DATA_IN_SIZE_SHIFT) | ||
168 | # define I2S_DWS_DATA_IN_24BIT (3<<I2S_DWS_DATA_IN_SIZE_SHIFT) | ||
169 | /* number of interleaved output channels */ | ||
170 | # define I2S_DWS_NUM_CHANNELS_OUT_SHIFT 8 | ||
171 | # define I2S_DWS_NUM_CHANNELS_OUT_MASK (0x1F<<I2S_DWS_NUM_CHANNELS_OUT_SHIFT) | ||
172 | /* word size of output data */ | ||
173 | # define I2S_DWS_DATA_OUT_SIZE_SHIFT 0 | ||
174 | # define I2S_DWS_DATA_OUT_16BIT (0<<I2S_DWS_DATA_OUT_SIZE_SHIFT) | ||
175 | # define I2S_DWS_DATA_OUT_24BIT (3<<I2S_DWS_DATA_OUT_SIZE_SHIFT) | ||
176 | |||
177 | |||
178 | /* unknown */ | ||
179 | #define I2S_REG_PEAK_LEVEL_SEL 0x70 | ||
180 | |||
181 | /* unknown */ | ||
182 | #define I2S_REG_PEAK_LEVEL_IN0 0x80 | ||
183 | |||
184 | /* unknown */ | ||
185 | #define I2S_REG_PEAK_LEVEL_IN1 0x90 | ||
186 | |||
187 | #endif /* __I2SBUS_INTERFACE_H */ | ||