diff options
author | Pavel Hofman <pavel.hofman@ivitera.com> | 2009-09-16 16:25:37 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-09-21 09:45:07 -0400 |
commit | 42cfa276aebd28e5cc4350ff6c7d75f1cb84dd98 (patch) | |
tree | 5456711f5170f5b1fec06aef201d01a24ed8777a | |
parent | 8f34692f63d66805b51ff408f4067748d3c1c3fd (diff) |
ALSA: ak4113 support
* complete support for ak4113
* based on code for ak4114 and ak4117
Signed-off-by: Pavel Hofman <pavel.hofman@ivitera.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | include/sound/ak4113.h | 321 | ||||
-rw-r--r-- | sound/i2c/other/Makefile | 3 | ||||
-rw-r--r-- | sound/i2c/other/ak4113.c | 639 |
3 files changed, 962 insertions, 1 deletions
diff --git a/include/sound/ak4113.h b/include/sound/ak4113.h new file mode 100644 index 000000000000..8988edae1609 --- /dev/null +++ b/include/sound/ak4113.h | |||
@@ -0,0 +1,321 @@ | |||
1 | #ifndef __SOUND_AK4113_H | ||
2 | #define __SOUND_AK4113_H | ||
3 | |||
4 | /* | ||
5 | * Routines for Asahi Kasei AK4113 | ||
6 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz>, | ||
7 | * Copyright (c) by Pavel Hofman <pavel.hofman@ivitera.com>, | ||
8 | * | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | /* AK4113 registers */ | ||
27 | /* power down */ | ||
28 | #define AK4113_REG_PWRDN 0x00 | ||
29 | /* format control */ | ||
30 | #define AK4113_REG_FORMAT 0x01 | ||
31 | /* input/output control */ | ||
32 | #define AK4113_REG_IO0 0x02 | ||
33 | /* input/output control */ | ||
34 | #define AK4113_REG_IO1 0x03 | ||
35 | /* interrupt0 mask */ | ||
36 | #define AK4113_REG_INT0_MASK 0x04 | ||
37 | /* interrupt1 mask */ | ||
38 | #define AK4113_REG_INT1_MASK 0x05 | ||
39 | /* DAT mask & DTS select */ | ||
40 | #define AK4113_REG_DATDTS 0x06 | ||
41 | /* receiver status 0 */ | ||
42 | #define AK4113_REG_RCS0 0x07 | ||
43 | /* receiver status 1 */ | ||
44 | #define AK4113_REG_RCS1 0x08 | ||
45 | /* receiver status 2 */ | ||
46 | #define AK4113_REG_RCS2 0x09 | ||
47 | /* RX channel status byte 0 */ | ||
48 | #define AK4113_REG_RXCSB0 0x0a | ||
49 | /* RX channel status byte 1 */ | ||
50 | #define AK4113_REG_RXCSB1 0x0b | ||
51 | /* RX channel status byte 2 */ | ||
52 | #define AK4113_REG_RXCSB2 0x0c | ||
53 | /* RX channel status byte 3 */ | ||
54 | #define AK4113_REG_RXCSB3 0x0d | ||
55 | /* RX channel status byte 4 */ | ||
56 | #define AK4113_REG_RXCSB4 0x0e | ||
57 | /* burst preamble Pc byte 0 */ | ||
58 | #define AK4113_REG_Pc0 0x0f | ||
59 | /* burst preamble Pc byte 1 */ | ||
60 | #define AK4113_REG_Pc1 0x10 | ||
61 | /* burst preamble Pd byte 0 */ | ||
62 | #define AK4113_REG_Pd0 0x11 | ||
63 | /* burst preamble Pd byte 1 */ | ||
64 | #define AK4113_REG_Pd1 0x12 | ||
65 | /* Q-subcode address + control */ | ||
66 | #define AK4113_REG_QSUB_ADDR 0x13 | ||
67 | /* Q-subcode track */ | ||
68 | #define AK4113_REG_QSUB_TRACK 0x14 | ||
69 | /* Q-subcode index */ | ||
70 | #define AK4113_REG_QSUB_INDEX 0x15 | ||
71 | /* Q-subcode minute */ | ||
72 | #define AK4113_REG_QSUB_MINUTE 0x16 | ||
73 | /* Q-subcode second */ | ||
74 | #define AK4113_REG_QSUB_SECOND 0x17 | ||
75 | /* Q-subcode frame */ | ||
76 | #define AK4113_REG_QSUB_FRAME 0x18 | ||
77 | /* Q-subcode zero */ | ||
78 | #define AK4113_REG_QSUB_ZERO 0x19 | ||
79 | /* Q-subcode absolute minute */ | ||
80 | #define AK4113_REG_QSUB_ABSMIN 0x1a | ||
81 | /* Q-subcode absolute second */ | ||
82 | #define AK4113_REG_QSUB_ABSSEC 0x1b | ||
83 | /* Q-subcode absolute frame */ | ||
84 | #define AK4113_REG_QSUB_ABSFRM 0x1c | ||
85 | |||
86 | /* sizes */ | ||
87 | #define AK4113_REG_RXCSB_SIZE ((AK4113_REG_RXCSB4-AK4113_REG_RXCSB0)+1) | ||
88 | #define AK4113_REG_QSUB_SIZE ((AK4113_REG_QSUB_ABSFRM-AK4113_REG_QSUB_ADDR)\ | ||
89 | +1) | ||
90 | |||
91 | #define AK4113_WRITABLE_REGS (AK4113_REG_DATDTS + 1) | ||
92 | |||
93 | /* AK4113_REG_PWRDN bits */ | ||
94 | /* Channel Status Select */ | ||
95 | #define AK4113_CS12 (1<<7) | ||
96 | /* Block Start & C/U Output Mode */ | ||
97 | #define AK4113_BCU (1<<6) | ||
98 | /* Master Clock Operation Select */ | ||
99 | #define AK4113_CM1 (1<<5) | ||
100 | /* Master Clock Operation Select */ | ||
101 | #define AK4113_CM0 (1<<4) | ||
102 | /* Master Clock Frequency Select */ | ||
103 | #define AK4113_OCKS1 (1<<3) | ||
104 | /* Master Clock Frequency Select */ | ||
105 | #define AK4113_OCKS0 (1<<2) | ||
106 | /* 0 = power down, 1 = normal operation */ | ||
107 | #define AK4113_PWN (1<<1) | ||
108 | /* 0 = reset & initialize (except thisregister), 1 = normal operation */ | ||
109 | #define AK4113_RST (1<<0) | ||
110 | |||
111 | /* AK4113_REQ_FORMAT bits */ | ||
112 | /* V/TX Output select: 0 = Validity Flag Output, 1 = TX */ | ||
113 | #define AK4113_VTX (1<<7) | ||
114 | /* Audio Data Control */ | ||
115 | #define AK4113_DIF2 (1<<6) | ||
116 | /* Audio Data Control */ | ||
117 | #define AK4113_DIF1 (1<<5) | ||
118 | /* Audio Data Control */ | ||
119 | #define AK4113_DIF0 (1<<4) | ||
120 | /* Deemphasis Autodetect Enable (1 = enable) */ | ||
121 | #define AK4113_DEAU (1<<3) | ||
122 | /* 32kHz-48kHz Deemphasis Control */ | ||
123 | #define AK4113_DEM1 (1<<2) | ||
124 | /* 32kHz-48kHz Deemphasis Control */ | ||
125 | #define AK4113_DEM0 (1<<1) | ||
126 | #define AK4113_DEM_OFF (AK4113_DEM0) | ||
127 | #define AK4113_DEM_44KHZ (0) | ||
128 | #define AK4113_DEM_48KHZ (AK4113_DEM1) | ||
129 | #define AK4113_DEM_32KHZ (AK4113_DEM0|AK4113_DEM1) | ||
130 | /* STDO: 16-bit, right justified */ | ||
131 | #define AK4113_DIF_16R (0) | ||
132 | /* STDO: 18-bit, right justified */ | ||
133 | #define AK4113_DIF_18R (AK4113_DIF0) | ||
134 | /* STDO: 20-bit, right justified */ | ||
135 | #define AK4113_DIF_20R (AK4113_DIF1) | ||
136 | /* STDO: 24-bit, right justified */ | ||
137 | #define AK4113_DIF_24R (AK4113_DIF1|AK4113_DIF0) | ||
138 | /* STDO: 24-bit, left justified */ | ||
139 | #define AK4113_DIF_24L (AK4113_DIF2) | ||
140 | /* STDO: I2S */ | ||
141 | #define AK4113_DIF_24I2S (AK4113_DIF2|AK4113_DIF0) | ||
142 | /* STDO: 24-bit, left justified; LRCLK, BICK = Input */ | ||
143 | #define AK4113_DIF_I24L (AK4113_DIF2|AK4113_DIF1) | ||
144 | /* STDO: I2S; LRCLK, BICK = Input */ | ||
145 | #define AK4113_DIF_I24I2S (AK4113_DIF2|AK4113_DIF1|AK4113_DIF0) | ||
146 | |||
147 | /* AK4113_REG_IO0 */ | ||
148 | /* XTL1=0,XTL0=0 -> 11.2896Mhz; XTL1=0,XTL0=1 -> 12.288Mhz */ | ||
149 | #define AK4113_XTL1 (1<<6) | ||
150 | /* XTL1=1,XTL0=0 -> 24.576Mhz; XTL1=1,XTL0=1 -> use channel status */ | ||
151 | #define AK4113_XTL0 (1<<5) | ||
152 | /* Block Start Signal Output: 0 = U-bit, 1 = C-bit (req. BCU = 1) */ | ||
153 | #define AK4113_UCE (1<<4) | ||
154 | /* TX Output Enable (1 = enable) */ | ||
155 | #define AK4113_TXE (1<<3) | ||
156 | /* Output Through Data Selector for TX pin */ | ||
157 | #define AK4113_OPS2 (1<<2) | ||
158 | /* Output Through Data Selector for TX pin */ | ||
159 | #define AK4113_OPS1 (1<<1) | ||
160 | /* Output Through Data Selector for TX pin */ | ||
161 | #define AK4113_OPS0 (1<<0) | ||
162 | /* 11.2896 MHz ref. Xtal freq. */ | ||
163 | #define AK4113_XTL_11_2896M (0) | ||
164 | /* 12.288 MHz ref. Xtal freq. */ | ||
165 | #define AK4113_XTL_12_288M (AK4113_XTL0) | ||
166 | /* 24.576 MHz ref. Xtal freq. */ | ||
167 | #define AK4113_XTL_24_576M (AK4113_XTL1) | ||
168 | |||
169 | /* AK4113_REG_IO1 */ | ||
170 | /* Interrupt 0 pin Hold */ | ||
171 | #define AK4113_EFH1 (1<<7) | ||
172 | /* Interrupt 0 pin Hold */ | ||
173 | #define AK4113_EFH0 (1<<6) | ||
174 | #define AK4113_EFH_512LRCLK (0) | ||
175 | #define AK4113_EFH_1024LRCLK (AK4113_EFH0) | ||
176 | #define AK4113_EFH_2048LRCLK (AK4113_EFH1) | ||
177 | #define AK4113_EFH_4096LRCLK (AK4113_EFH1|AK4113_EFH0) | ||
178 | /* PLL Lock Time: 0 = 384/fs, 1 = 1/fs */ | ||
179 | #define AK4113_FAST (1<<5) | ||
180 | /* MCKO2 Output Select: 0 = CMx/OCKSx, 1 = Xtal */ | ||
181 | #define AK4113_XMCK (1<<4) | ||
182 | /* MCKO2 Output Freq. Select: 0 = x1, 1 = x0.5 (req. XMCK = 1) */ | ||
183 | #define AK4113_DIV (1<<3) | ||
184 | /* Input Recovery Data Select */ | ||
185 | #define AK4113_IPS2 (1<<2) | ||
186 | /* Input Recovery Data Select */ | ||
187 | #define AK4113_IPS1 (1<<1) | ||
188 | /* Input Recovery Data Select */ | ||
189 | #define AK4113_IPS0 (1<<0) | ||
190 | #define AK4113_IPS(x) ((x)&7) | ||
191 | |||
192 | /* AK4113_REG_INT0_MASK && AK4113_REG_INT1_MASK*/ | ||
193 | /* mask enable for QINT bit */ | ||
194 | #define AK4113_MQI (1<<7) | ||
195 | /* mask enable for AUTO bit */ | ||
196 | #define AK4113_MAUT (1<<6) | ||
197 | /* mask enable for CINT bit */ | ||
198 | #define AK4113_MCIT (1<<5) | ||
199 | /* mask enable for UNLOCK bit */ | ||
200 | #define AK4113_MULK (1<<4) | ||
201 | /* mask enable for V bit */ | ||
202 | #define AK4113_V (1<<3) | ||
203 | /* mask enable for STC bit */ | ||
204 | #define AK4113_STC (1<<2) | ||
205 | /* mask enable for AUDN bit */ | ||
206 | #define AK4113_MAN (1<<1) | ||
207 | /* mask enable for PAR bit */ | ||
208 | #define AK4113_MPR (1<<0) | ||
209 | |||
210 | /* AK4113_REG_DATDTS */ | ||
211 | /* DAT Start ID Counter */ | ||
212 | #define AK4113_DCNT (1<<4) | ||
213 | /* DTS-CD 16-bit Sync Word Detect */ | ||
214 | #define AK4113_DTS16 (1<<3) | ||
215 | /* DTS-CD 14-bit Sync Word Detect */ | ||
216 | #define AK4113_DTS14 (1<<2) | ||
217 | /* mask enable for DAT bit (if 1, no INT1 effect */ | ||
218 | #define AK4113_MDAT1 (1<<1) | ||
219 | /* mask enable for DAT bit (if 1, no INT0 effect */ | ||
220 | #define AK4113_MDAT0 (1<<0) | ||
221 | |||
222 | /* AK4113_REG_RCS0 */ | ||
223 | /* Q-subcode buffer interrupt, 0 = no change, 1 = changed */ | ||
224 | #define AK4113_QINT (1<<7) | ||
225 | /* Non-PCM or DTS stream auto detection, 0 = no detect, 1 = detect */ | ||
226 | #define AK4113_AUTO (1<<6) | ||
227 | /* channel status buffer interrupt, 0 = no change, 1 = change */ | ||
228 | #define AK4113_CINT (1<<5) | ||
229 | /* PLL lock status, 0 = lock, 1 = unlock */ | ||
230 | #define AK4113_UNLCK (1<<4) | ||
231 | /* Validity bit, 0 = valid, 1 = invalid */ | ||
232 | #define AK4113_V (1<<3) | ||
233 | /* sampling frequency or Pre-emphasis change, 0 = no detect, 1 = detect */ | ||
234 | #define AK4113_STC (1<<2) | ||
235 | /* audio bit output, 0 = audio, 1 = non-audio */ | ||
236 | #define AK4113_AUDION (1<<1) | ||
237 | /* parity error or biphase error status, 0 = no error, 1 = error */ | ||
238 | #define AK4113_PAR (1<<0) | ||
239 | |||
240 | /* AK4113_REG_RCS1 */ | ||
241 | /* sampling frequency detection */ | ||
242 | #define AK4113_FS3 (1<<7) | ||
243 | #define AK4113_FS2 (1<<6) | ||
244 | #define AK4113_FS1 (1<<5) | ||
245 | #define AK4113_FS0 (1<<4) | ||
246 | /* Pre-emphasis detect, 0 = OFF, 1 = ON */ | ||
247 | #define AK4113_PEM (1<<3) | ||
248 | /* DAT Start ID Detect, 0 = no detect, 1 = detect */ | ||
249 | #define AK4113_DAT (1<<2) | ||
250 | /* DTS-CD bit audio stream detect, 0 = no detect, 1 = detect */ | ||
251 | #define AK4113_DTSCD (1<<1) | ||
252 | /* Non-PCM bit stream detection, 0 = no detect, 1 = detect */ | ||
253 | #define AK4113_NPCM (1<<0) | ||
254 | #define AK4113_FS_8000HZ (AK4113_FS3|AK4113_FS0) | ||
255 | #define AK4113_FS_11025HZ (AK4113_FS2|AK4113_FS0) | ||
256 | #define AK4113_FS_16000HZ (AK4113_FS2|AK4113_FS1|AK4113_FS0) | ||
257 | #define AK4113_FS_22050HZ (AK4113_FS2) | ||
258 | #define AK4113_FS_24000HZ (AK4113_FS2|AK4113_FS1) | ||
259 | #define AK4113_FS_32000HZ (AK4113_FS1|AK4113_FS0) | ||
260 | #define AK4113_FS_44100HZ (0) | ||
261 | #define AK4113_FS_48000HZ (AK4113_FS1) | ||
262 | #define AK4113_FS_64000HZ (AK4113_FS3|AK4113_FS1|AK4113_FS0) | ||
263 | #define AK4113_FS_88200HZ (AK4113_FS3) | ||
264 | #define AK4113_FS_96000HZ (AK4113_FS3|AK4113_FS1) | ||
265 | #define AK4113_FS_176400HZ (AK4113_FS3|AK4113_FS2) | ||
266 | #define AK4113_FS_192000HZ (AK4113_FS3|AK4113_FS2|AK4113_FS1) | ||
267 | |||
268 | /* AK4113_REG_RCS2 */ | ||
269 | /* CRC for Q-subcode, 0 = no error, 1 = error */ | ||
270 | #define AK4113_QCRC (1<<1) | ||
271 | /* CRC for channel status, 0 = no error, 1 = error */ | ||
272 | #define AK4113_CCRC (1<<0) | ||
273 | |||
274 | /* flags for snd_ak4113_check_rate_and_errors() */ | ||
275 | #define AK4113_CHECK_NO_STAT (1<<0) /* no statistics */ | ||
276 | #define AK4113_CHECK_NO_RATE (1<<1) /* no rate check */ | ||
277 | |||
278 | #define AK4113_CONTROLS 13 | ||
279 | |||
280 | typedef void (ak4113_write_t)(void *private_data, unsigned char addr, | ||
281 | unsigned char data); | ||
282 | typedef unsigned char (ak4113_read_t)(void *private_data, unsigned char addr); | ||
283 | |||
284 | struct ak4113 { | ||
285 | struct snd_card *card; | ||
286 | ak4113_write_t *write; | ||
287 | ak4113_read_t *read; | ||
288 | void *private_data; | ||
289 | unsigned int init:1; | ||
290 | spinlock_t lock; | ||
291 | unsigned char regmap[AK4113_WRITABLE_REGS]; | ||
292 | struct snd_kcontrol *kctls[AK4113_CONTROLS]; | ||
293 | struct snd_pcm_substream *substream; | ||
294 | unsigned long parity_errors; | ||
295 | unsigned long v_bit_errors; | ||
296 | unsigned long qcrc_errors; | ||
297 | unsigned long ccrc_errors; | ||
298 | unsigned char rcs0; | ||
299 | unsigned char rcs1; | ||
300 | unsigned char rcs2; | ||
301 | struct delayed_work work; | ||
302 | unsigned int check_flags; | ||
303 | void *change_callback_private; | ||
304 | void (*change_callback)(struct ak4113 *ak4113, unsigned char c0, | ||
305 | unsigned char c1); | ||
306 | }; | ||
307 | |||
308 | int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, | ||
309 | ak4113_write_t *write, | ||
310 | const unsigned char pgm[AK4113_WRITABLE_REGS], | ||
311 | void *private_data, struct ak4113 **r_ak4113); | ||
312 | void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg, | ||
313 | unsigned char mask, unsigned char val); | ||
314 | void snd_ak4113_reinit(struct ak4113 *ak4113); | ||
315 | int snd_ak4113_build(struct ak4113 *ak4113, | ||
316 | struct snd_pcm_substream *capture_substream); | ||
317 | int snd_ak4113_external_rate(struct ak4113 *ak4113); | ||
318 | int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags); | ||
319 | |||
320 | #endif /* __SOUND_AK4113_H */ | ||
321 | |||
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile index 703d954238f4..2dad40f3f622 100644 --- a/sound/i2c/other/Makefile +++ b/sound/i2c/other/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | snd-ak4114-objs := ak4114.o | 6 | snd-ak4114-objs := ak4114.o |
7 | snd-ak4117-objs := ak4117.o | 7 | snd-ak4117-objs := ak4117.o |
8 | snd-ak4113-objs := ak4113.o | ||
8 | snd-ak4xxx-adda-objs := ak4xxx-adda.o | 9 | snd-ak4xxx-adda-objs := ak4xxx-adda.o |
9 | snd-pt2258-objs := pt2258.o | 10 | snd-pt2258-objs := pt2258.o |
10 | snd-tea575x-tuner-objs := tea575x-tuner.o | 11 | snd-tea575x-tuner-objs := tea575x-tuner.o |
@@ -12,5 +13,5 @@ snd-tea575x-tuner-objs := tea575x-tuner.o | |||
12 | # Module Dependency | 13 | # Module Dependency |
13 | obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o | 14 | obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o |
14 | obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o | 15 | obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o |
15 | obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4xxx-adda.o snd-pt2258.o | 16 | obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o |
16 | obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o | 17 | obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o |
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c new file mode 100644 index 000000000000..fff62cc8607c --- /dev/null +++ b/sound/i2c/other/ak4113.c | |||
@@ -0,0 +1,639 @@ | |||
1 | /* | ||
2 | * Routines for control of the AK4113 via I2C/4-wire serial interface | ||
3 | * IEC958 (S/PDIF) receiver by Asahi Kasei | ||
4 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> | ||
5 | * Copyright (c) by Pavel Hofman <pavel.hofman@ivitera.com> | ||
6 | * | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/slab.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <sound/core.h> | ||
27 | #include <sound/control.h> | ||
28 | #include <sound/pcm.h> | ||
29 | #include <sound/ak4113.h> | ||
30 | #include <sound/asoundef.h> | ||
31 | #include <sound/info.h> | ||
32 | |||
33 | MODULE_AUTHOR("Pavel Hofman <pavel.hofman@ivitera.com>"); | ||
34 | MODULE_DESCRIPTION("AK4113 IEC958 (S/PDIF) receiver by Asahi Kasei"); | ||
35 | MODULE_LICENSE("GPL"); | ||
36 | |||
37 | #define AK4113_ADDR 0x00 /* fixed address */ | ||
38 | |||
39 | static void ak4113_stats(struct work_struct *work); | ||
40 | static void ak4113_init_regs(struct ak4113 *chip); | ||
41 | |||
42 | |||
43 | static void reg_write(struct ak4113 *ak4113, unsigned char reg, | ||
44 | unsigned char val) | ||
45 | { | ||
46 | ak4113->write(ak4113->private_data, reg, val); | ||
47 | if (reg < sizeof(ak4113->regmap)) | ||
48 | ak4113->regmap[reg] = val; | ||
49 | } | ||
50 | |||
51 | static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg) | ||
52 | { | ||
53 | return ak4113->read(ak4113->private_data, reg); | ||
54 | } | ||
55 | |||
56 | static void snd_ak4113_free(struct ak4113 *chip) | ||
57 | { | ||
58 | chip->init = 1; /* don't schedule new work */ | ||
59 | mb(); | ||
60 | cancel_delayed_work(&chip->work); | ||
61 | flush_scheduled_work(); | ||
62 | kfree(chip); | ||
63 | } | ||
64 | |||
65 | static int snd_ak4113_dev_free(struct snd_device *device) | ||
66 | { | ||
67 | struct ak4113 *chip = device->device_data; | ||
68 | snd_ak4113_free(chip); | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, | ||
73 | ak4113_write_t *write, const unsigned char pgm[5], | ||
74 | void *private_data, struct ak4113 **r_ak4113) | ||
75 | { | ||
76 | struct ak4113 *chip; | ||
77 | int err = 0; | ||
78 | unsigned char reg; | ||
79 | static struct snd_device_ops ops = { | ||
80 | .dev_free = snd_ak4113_dev_free, | ||
81 | }; | ||
82 | |||
83 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
84 | if (chip == NULL) | ||
85 | return -ENOMEM; | ||
86 | spin_lock_init(&chip->lock); | ||
87 | chip->card = card; | ||
88 | chip->read = read; | ||
89 | chip->write = write; | ||
90 | chip->private_data = private_data; | ||
91 | INIT_DELAYED_WORK(&chip->work, ak4113_stats); | ||
92 | |||
93 | for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++) | ||
94 | chip->regmap[reg] = pgm[reg]; | ||
95 | ak4113_init_regs(chip); | ||
96 | |||
97 | chip->rcs0 = reg_read(chip, AK4113_REG_RCS0) & ~(AK4113_QINT | | ||
98 | AK4113_CINT | AK4113_STC); | ||
99 | chip->rcs1 = reg_read(chip, AK4113_REG_RCS1); | ||
100 | chip->rcs2 = reg_read(chip, AK4113_REG_RCS2); | ||
101 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); | ||
102 | if (err < 0) | ||
103 | goto __fail; | ||
104 | |||
105 | if (r_ak4113) | ||
106 | *r_ak4113 = chip; | ||
107 | return 0; | ||
108 | |||
109 | __fail: | ||
110 | snd_ak4113_free(chip); | ||
111 | return err < 0 ? err : -EIO; | ||
112 | } | ||
113 | EXPORT_SYMBOL_GPL(snd_ak4113_create); | ||
114 | |||
115 | void snd_ak4113_reg_write(struct ak4113 *chip, unsigned char reg, | ||
116 | unsigned char mask, unsigned char val) | ||
117 | { | ||
118 | if (reg >= AK4113_WRITABLE_REGS) | ||
119 | return; | ||
120 | reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val); | ||
121 | } | ||
122 | EXPORT_SYMBOL_GPL(snd_ak4113_reg_write); | ||
123 | |||
124 | static void ak4113_init_regs(struct ak4113 *chip) | ||
125 | { | ||
126 | unsigned char old = chip->regmap[AK4113_REG_PWRDN], reg; | ||
127 | |||
128 | /* bring the chip to reset state and powerdown state */ | ||
129 | reg_write(chip, AK4113_REG_PWRDN, old & ~(AK4113_RST|AK4113_PWN)); | ||
130 | udelay(200); | ||
131 | /* release reset, but leave powerdown */ | ||
132 | reg_write(chip, AK4113_REG_PWRDN, (old | AK4113_RST) & ~AK4113_PWN); | ||
133 | udelay(200); | ||
134 | for (reg = 1; reg < AK4113_WRITABLE_REGS; reg++) | ||
135 | reg_write(chip, reg, chip->regmap[reg]); | ||
136 | /* release powerdown, everything is initialized now */ | ||
137 | reg_write(chip, AK4113_REG_PWRDN, old | AK4113_RST | AK4113_PWN); | ||
138 | } | ||
139 | |||
140 | void snd_ak4113_reinit(struct ak4113 *chip) | ||
141 | { | ||
142 | chip->init = 1; | ||
143 | mb(); | ||
144 | flush_scheduled_work(); | ||
145 | ak4113_init_regs(chip); | ||
146 | /* bring up statistics / event queing */ | ||
147 | chip->init = 0; | ||
148 | if (chip->kctls[0]) | ||
149 | schedule_delayed_work(&chip->work, HZ / 10); | ||
150 | } | ||
151 | EXPORT_SYMBOL_GPL(snd_ak4113_reinit); | ||
152 | |||
153 | static unsigned int external_rate(unsigned char rcs1) | ||
154 | { | ||
155 | switch (rcs1 & (AK4113_FS0|AK4113_FS1|AK4113_FS2|AK4113_FS3)) { | ||
156 | case AK4113_FS_8000HZ: | ||
157 | return 8000; | ||
158 | case AK4113_FS_11025HZ: | ||
159 | return 11025; | ||
160 | case AK4113_FS_16000HZ: | ||
161 | return 16000; | ||
162 | case AK4113_FS_22050HZ: | ||
163 | return 22050; | ||
164 | case AK4113_FS_24000HZ: | ||
165 | return 24000; | ||
166 | case AK4113_FS_32000HZ: | ||
167 | return 32000; | ||
168 | case AK4113_FS_44100HZ: | ||
169 | return 44100; | ||
170 | case AK4113_FS_48000HZ: | ||
171 | return 48000; | ||
172 | case AK4113_FS_64000HZ: | ||
173 | return 64000; | ||
174 | case AK4113_FS_88200HZ: | ||
175 | return 88200; | ||
176 | case AK4113_FS_96000HZ: | ||
177 | return 96000; | ||
178 | case AK4113_FS_176400HZ: | ||
179 | return 176400; | ||
180 | case AK4113_FS_192000HZ: | ||
181 | return 192000; | ||
182 | default: | ||
183 | return 0; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | static int snd_ak4113_in_error_info(struct snd_kcontrol *kcontrol, | ||
188 | struct snd_ctl_elem_info *uinfo) | ||
189 | { | ||
190 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
191 | uinfo->count = 1; | ||
192 | uinfo->value.integer.min = 0; | ||
193 | uinfo->value.integer.max = LONG_MAX; | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static int snd_ak4113_in_error_get(struct snd_kcontrol *kcontrol, | ||
198 | struct snd_ctl_elem_value *ucontrol) | ||
199 | { | ||
200 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); | ||
201 | long *ptr; | ||
202 | |||
203 | spin_lock_irq(&chip->lock); | ||
204 | ptr = (long *)(((char *)chip) + kcontrol->private_value); | ||
205 | ucontrol->value.integer.value[0] = *ptr; | ||
206 | *ptr = 0; | ||
207 | spin_unlock_irq(&chip->lock); | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | #define snd_ak4113_in_bit_info snd_ctl_boolean_mono_info | ||
212 | |||
213 | static int snd_ak4113_in_bit_get(struct snd_kcontrol *kcontrol, | ||
214 | struct snd_ctl_elem_value *ucontrol) | ||
215 | { | ||
216 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); | ||
217 | unsigned char reg = kcontrol->private_value & 0xff; | ||
218 | unsigned char bit = (kcontrol->private_value >> 8) & 0xff; | ||
219 | unsigned char inv = (kcontrol->private_value >> 31) & 1; | ||
220 | |||
221 | ucontrol->value.integer.value[0] = | ||
222 | ((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv; | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int snd_ak4113_rx_info(struct snd_kcontrol *kcontrol, | ||
227 | struct snd_ctl_elem_info *uinfo) | ||
228 | { | ||
229 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
230 | uinfo->count = 1; | ||
231 | uinfo->value.integer.min = 0; | ||
232 | uinfo->value.integer.max = 5; | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int snd_ak4113_rx_get(struct snd_kcontrol *kcontrol, | ||
237 | struct snd_ctl_elem_value *ucontrol) | ||
238 | { | ||
239 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); | ||
240 | |||
241 | ucontrol->value.integer.value[0] = | ||
242 | (AK4113_IPS(chip->regmap[AK4113_REG_IO1])); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int snd_ak4113_rx_put(struct snd_kcontrol *kcontrol, | ||
247 | struct snd_ctl_elem_value *ucontrol) | ||
248 | { | ||
249 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); | ||
250 | int change; | ||
251 | u8 old_val; | ||
252 | |||
253 | spin_lock_irq(&chip->lock); | ||
254 | old_val = chip->regmap[AK4113_REG_IO1]; | ||
255 | change = ucontrol->value.integer.value[0] != AK4113_IPS(old_val); | ||
256 | if (change) | ||
257 | reg_write(chip, AK4113_REG_IO1, | ||
258 | (old_val & (~AK4113_IPS(0xff))) | | ||
259 | (AK4113_IPS(ucontrol->value.integer.value[0]))); | ||
260 | spin_unlock_irq(&chip->lock); | ||
261 | return change; | ||
262 | } | ||
263 | |||
264 | static int snd_ak4113_rate_info(struct snd_kcontrol *kcontrol, | ||
265 | struct snd_ctl_elem_info *uinfo) | ||
266 | { | ||
267 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
268 | uinfo->count = 1; | ||
269 | uinfo->value.integer.min = 0; | ||
270 | uinfo->value.integer.max = 192000; | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static int snd_ak4113_rate_get(struct snd_kcontrol *kcontrol, | ||
275 | struct snd_ctl_elem_value *ucontrol) | ||
276 | { | ||
277 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); | ||
278 | |||
279 | ucontrol->value.integer.value[0] = external_rate(reg_read(chip, | ||
280 | AK4113_REG_RCS1)); | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static int snd_ak4113_spdif_info(struct snd_kcontrol *kcontrol, | ||
285 | struct snd_ctl_elem_info *uinfo) | ||
286 | { | ||
287 | uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; | ||
288 | uinfo->count = 1; | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static int snd_ak4113_spdif_get(struct snd_kcontrol *kcontrol, | ||
293 | struct snd_ctl_elem_value *ucontrol) | ||
294 | { | ||
295 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); | ||
296 | unsigned i; | ||
297 | |||
298 | for (i = 0; i < AK4113_REG_RXCSB_SIZE; i++) | ||
299 | ucontrol->value.iec958.status[i] = reg_read(chip, | ||
300 | AK4113_REG_RXCSB0 + i); | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static int snd_ak4113_spdif_mask_info(struct snd_kcontrol *kcontrol, | ||
305 | struct snd_ctl_elem_info *uinfo) | ||
306 | { | ||
307 | uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; | ||
308 | uinfo->count = 1; | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int snd_ak4113_spdif_mask_get(struct snd_kcontrol *kcontrol, | ||
313 | struct snd_ctl_elem_value *ucontrol) | ||
314 | { | ||
315 | memset(ucontrol->value.iec958.status, 0xff, AK4113_REG_RXCSB_SIZE); | ||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static int snd_ak4113_spdif_pinfo(struct snd_kcontrol *kcontrol, | ||
320 | struct snd_ctl_elem_info *uinfo) | ||
321 | { | ||
322 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
323 | uinfo->value.integer.min = 0; | ||
324 | uinfo->value.integer.max = 0xffff; | ||
325 | uinfo->count = 4; | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static int snd_ak4113_spdif_pget(struct snd_kcontrol *kcontrol, | ||
330 | struct snd_ctl_elem_value *ucontrol) | ||
331 | { | ||
332 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); | ||
333 | unsigned short tmp; | ||
334 | |||
335 | ucontrol->value.integer.value[0] = 0xf8f2; | ||
336 | ucontrol->value.integer.value[1] = 0x4e1f; | ||
337 | tmp = reg_read(chip, AK4113_REG_Pc0) | | ||
338 | (reg_read(chip, AK4113_REG_Pc1) << 8); | ||
339 | ucontrol->value.integer.value[2] = tmp; | ||
340 | tmp = reg_read(chip, AK4113_REG_Pd0) | | ||
341 | (reg_read(chip, AK4113_REG_Pd1) << 8); | ||
342 | ucontrol->value.integer.value[3] = tmp; | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static int snd_ak4113_spdif_qinfo(struct snd_kcontrol *kcontrol, | ||
347 | struct snd_ctl_elem_info *uinfo) | ||
348 | { | ||
349 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||
350 | uinfo->count = AK4113_REG_QSUB_SIZE; | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static int snd_ak4113_spdif_qget(struct snd_kcontrol *kcontrol, | ||
355 | struct snd_ctl_elem_value *ucontrol) | ||
356 | { | ||
357 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); | ||
358 | unsigned i; | ||
359 | |||
360 | for (i = 0; i < AK4113_REG_QSUB_SIZE; i++) | ||
361 | ucontrol->value.bytes.data[i] = reg_read(chip, | ||
362 | AK4113_REG_QSUB_ADDR + i); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | /* Don't forget to change AK4113_CONTROLS define!!! */ | ||
367 | static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { | ||
368 | { | ||
369 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
370 | .name = "IEC958 Parity Errors", | ||
371 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
372 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
373 | .info = snd_ak4113_in_error_info, | ||
374 | .get = snd_ak4113_in_error_get, | ||
375 | .private_value = offsetof(struct ak4113, parity_errors), | ||
376 | }, | ||
377 | { | ||
378 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
379 | .name = "IEC958 V-Bit Errors", | ||
380 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
381 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
382 | .info = snd_ak4113_in_error_info, | ||
383 | .get = snd_ak4113_in_error_get, | ||
384 | .private_value = offsetof(struct ak4113, v_bit_errors), | ||
385 | }, | ||
386 | { | ||
387 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
388 | .name = "IEC958 C-CRC Errors", | ||
389 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
390 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
391 | .info = snd_ak4113_in_error_info, | ||
392 | .get = snd_ak4113_in_error_get, | ||
393 | .private_value = offsetof(struct ak4113, ccrc_errors), | ||
394 | }, | ||
395 | { | ||
396 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
397 | .name = "IEC958 Q-CRC Errors", | ||
398 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
399 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
400 | .info = snd_ak4113_in_error_info, | ||
401 | .get = snd_ak4113_in_error_get, | ||
402 | .private_value = offsetof(struct ak4113, qcrc_errors), | ||
403 | }, | ||
404 | { | ||
405 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
406 | .name = "IEC958 External Rate", | ||
407 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
408 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
409 | .info = snd_ak4113_rate_info, | ||
410 | .get = snd_ak4113_rate_get, | ||
411 | }, | ||
412 | { | ||
413 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
414 | .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK), | ||
415 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | ||
416 | .info = snd_ak4113_spdif_mask_info, | ||
417 | .get = snd_ak4113_spdif_mask_get, | ||
418 | }, | ||
419 | { | ||
420 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
421 | .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT), | ||
422 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
423 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
424 | .info = snd_ak4113_spdif_info, | ||
425 | .get = snd_ak4113_spdif_get, | ||
426 | }, | ||
427 | { | ||
428 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
429 | .name = "IEC958 Preample Capture Default", | ||
430 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
431 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
432 | .info = snd_ak4113_spdif_pinfo, | ||
433 | .get = snd_ak4113_spdif_pget, | ||
434 | }, | ||
435 | { | ||
436 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
437 | .name = "IEC958 Q-subcode Capture Default", | ||
438 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
439 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
440 | .info = snd_ak4113_spdif_qinfo, | ||
441 | .get = snd_ak4113_spdif_qget, | ||
442 | }, | ||
443 | { | ||
444 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
445 | .name = "IEC958 Audio", | ||
446 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
447 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
448 | .info = snd_ak4113_in_bit_info, | ||
449 | .get = snd_ak4113_in_bit_get, | ||
450 | .private_value = (1<<31) | (1<<8) | AK4113_REG_RCS0, | ||
451 | }, | ||
452 | { | ||
453 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
454 | .name = "IEC958 Non-PCM Bitstream", | ||
455 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
456 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
457 | .info = snd_ak4113_in_bit_info, | ||
458 | .get = snd_ak4113_in_bit_get, | ||
459 | .private_value = (0<<8) | AK4113_REG_RCS1, | ||
460 | }, | ||
461 | { | ||
462 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
463 | .name = "IEC958 DTS Bitstream", | ||
464 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
465 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
466 | .info = snd_ak4113_in_bit_info, | ||
467 | .get = snd_ak4113_in_bit_get, | ||
468 | .private_value = (1<<8) | AK4113_REG_RCS1, | ||
469 | }, | ||
470 | { | ||
471 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
472 | .name = "AK4113 Input Select", | ||
473 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | ||
474 | SNDRV_CTL_ELEM_ACCESS_WRITE, | ||
475 | .info = snd_ak4113_rx_info, | ||
476 | .get = snd_ak4113_rx_get, | ||
477 | .put = snd_ak4113_rx_put, | ||
478 | } | ||
479 | }; | ||
480 | |||
481 | static void snd_ak4113_proc_regs_read(struct snd_info_entry *entry, | ||
482 | struct snd_info_buffer *buffer) | ||
483 | { | ||
484 | struct ak4113 *ak4113 = entry->private_data; | ||
485 | int reg, val; | ||
486 | /* all ak4113 registers 0x00 - 0x1c */ | ||
487 | for (reg = 0; reg < 0x1d; reg++) { | ||
488 | val = reg_read(ak4113, reg); | ||
489 | snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val); | ||
490 | } | ||
491 | } | ||
492 | |||
493 | static void snd_ak4113_proc_init(struct ak4113 *ak4113) | ||
494 | { | ||
495 | struct snd_info_entry *entry; | ||
496 | if (!snd_card_proc_new(ak4113->card, "ak4113", &entry)) | ||
497 | snd_info_set_text_ops(entry, ak4113, snd_ak4113_proc_regs_read); | ||
498 | } | ||
499 | |||
500 | int snd_ak4113_build(struct ak4113 *ak4113, | ||
501 | struct snd_pcm_substream *cap_substream) | ||
502 | { | ||
503 | struct snd_kcontrol *kctl; | ||
504 | unsigned int idx; | ||
505 | int err; | ||
506 | |||
507 | if (snd_BUG_ON(!cap_substream)) | ||
508 | return -EINVAL; | ||
509 | ak4113->substream = cap_substream; | ||
510 | for (idx = 0; idx < AK4113_CONTROLS; idx++) { | ||
511 | kctl = snd_ctl_new1(&snd_ak4113_iec958_controls[idx], ak4113); | ||
512 | if (kctl == NULL) | ||
513 | return -ENOMEM; | ||
514 | kctl->id.device = cap_substream->pcm->device; | ||
515 | kctl->id.subdevice = cap_substream->number; | ||
516 | err = snd_ctl_add(ak4113->card, kctl); | ||
517 | if (err < 0) | ||
518 | return err; | ||
519 | ak4113->kctls[idx] = kctl; | ||
520 | } | ||
521 | snd_ak4113_proc_init(ak4113); | ||
522 | /* trigger workq */ | ||
523 | schedule_delayed_work(&ak4113->work, HZ / 10); | ||
524 | return 0; | ||
525 | } | ||
526 | EXPORT_SYMBOL_GPL(snd_ak4113_build); | ||
527 | |||
528 | int snd_ak4113_external_rate(struct ak4113 *ak4113) | ||
529 | { | ||
530 | unsigned char rcs1; | ||
531 | |||
532 | rcs1 = reg_read(ak4113, AK4113_REG_RCS1); | ||
533 | return external_rate(rcs1); | ||
534 | } | ||
535 | EXPORT_SYMBOL_GPL(snd_ak4113_external_rate); | ||
536 | |||
537 | int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags) | ||
538 | { | ||
539 | struct snd_pcm_runtime *runtime = | ||
540 | ak4113->substream ? ak4113->substream->runtime : NULL; | ||
541 | unsigned long _flags; | ||
542 | int res = 0; | ||
543 | unsigned char rcs0, rcs1, rcs2; | ||
544 | unsigned char c0, c1; | ||
545 | |||
546 | rcs1 = reg_read(ak4113, AK4113_REG_RCS1); | ||
547 | if (flags & AK4113_CHECK_NO_STAT) | ||
548 | goto __rate; | ||
549 | rcs0 = reg_read(ak4113, AK4113_REG_RCS0); | ||
550 | rcs2 = reg_read(ak4113, AK4113_REG_RCS2); | ||
551 | spin_lock_irqsave(&ak4113->lock, _flags); | ||
552 | if (rcs0 & AK4113_PAR) | ||
553 | ak4113->parity_errors++; | ||
554 | if (rcs0 & AK4113_V) | ||
555 | ak4113->v_bit_errors++; | ||
556 | if (rcs2 & AK4113_CCRC) | ||
557 | ak4113->ccrc_errors++; | ||
558 | if (rcs2 & AK4113_QCRC) | ||
559 | ak4113->qcrc_errors++; | ||
560 | c0 = (ak4113->rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC | | ||
561 | AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)) ^ | ||
562 | (rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC | | ||
563 | AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)); | ||
564 | c1 = (ak4113->rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM | | ||
565 | AK4113_DAT | 0xf0)) ^ | ||
566 | (rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM | | ||
567 | AK4113_DAT | 0xf0)); | ||
568 | ak4113->rcs0 = rcs0 & ~(AK4113_QINT | AK4113_CINT | AK4113_STC); | ||
569 | ak4113->rcs1 = rcs1; | ||
570 | ak4113->rcs2 = rcs2; | ||
571 | spin_unlock_irqrestore(&ak4113->lock, _flags); | ||
572 | |||
573 | if (rcs0 & AK4113_PAR) | ||
574 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
575 | &ak4113->kctls[0]->id); | ||
576 | if (rcs0 & AK4113_V) | ||
577 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
578 | &ak4113->kctls[1]->id); | ||
579 | if (rcs2 & AK4113_CCRC) | ||
580 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
581 | &ak4113->kctls[2]->id); | ||
582 | if (rcs2 & AK4113_QCRC) | ||
583 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
584 | &ak4113->kctls[3]->id); | ||
585 | |||
586 | /* rate change */ | ||
587 | if (c1 & 0xf0) | ||
588 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
589 | &ak4113->kctls[4]->id); | ||
590 | |||
591 | if ((c1 & AK4113_PEM) | (c0 & AK4113_CINT)) | ||
592 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
593 | &ak4113->kctls[6]->id); | ||
594 | if (c0 & AK4113_QINT) | ||
595 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
596 | &ak4113->kctls[8]->id); | ||
597 | |||
598 | if (c0 & AK4113_AUDION) | ||
599 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
600 | &ak4113->kctls[9]->id); | ||
601 | if (c1 & AK4113_NPCM) | ||
602 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
603 | &ak4113->kctls[10]->id); | ||
604 | if (c1 & AK4113_DTSCD) | ||
605 | snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
606 | &ak4113->kctls[11]->id); | ||
607 | |||
608 | if (ak4113->change_callback && (c0 | c1) != 0) | ||
609 | ak4113->change_callback(ak4113, c0, c1); | ||
610 | |||
611 | __rate: | ||
612 | /* compare rate */ | ||
613 | res = external_rate(rcs1); | ||
614 | if (!(flags & AK4113_CHECK_NO_RATE) && runtime && | ||
615 | (runtime->rate != res)) { | ||
616 | snd_pcm_stream_lock_irqsave(ak4113->substream, _flags); | ||
617 | if (snd_pcm_running(ak4113->substream)) { | ||
618 | /*printk(KERN_DEBUG "rate changed (%i <- %i)\n", | ||
619 | * runtime->rate, res); */ | ||
620 | snd_pcm_stop(ak4113->substream, | ||
621 | SNDRV_PCM_STATE_DRAINING); | ||
622 | wake_up(&runtime->sleep); | ||
623 | res = 1; | ||
624 | } | ||
625 | snd_pcm_stream_unlock_irqrestore(ak4113->substream, _flags); | ||
626 | } | ||
627 | return res; | ||
628 | } | ||
629 | EXPORT_SYMBOL_GPL(snd_ak4113_check_rate_and_errors); | ||
630 | |||
631 | static void ak4113_stats(struct work_struct *work) | ||
632 | { | ||
633 | struct ak4113 *chip = container_of(work, struct ak4113, work.work); | ||
634 | |||
635 | if (!chip->init) | ||
636 | snd_ak4113_check_rate_and_errors(chip, chip->check_flags); | ||
637 | |||
638 | schedule_delayed_work(&chip->work, HZ / 10); | ||
639 | } | ||