2 * Driver for Sound Core PDAudioCF soundcard
4 * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/delay.h>
22 #include <linux/slab.h>
23 #include <sound/core.h>
24 #include <sound/info.h>
25 #include "pdaudiocf.h"
26 #include <sound/initval.h>
31 static unsigned char pdacf_ak4117_read(void *private_data
, unsigned char reg
)
33 struct snd_pdacf
*chip
= private_data
;
34 unsigned long timeout
;
38 spin_lock_irqsave(&chip
->ak4117_lock
, flags
);
40 while (pdacf_reg_read(chip
, PDAUDIOCF_REG_SCR
) & PDAUDIOCF_AK_SBP
) {
43 spin_unlock_irqrestore(&chip
->ak4117_lock
, flags
);
44 snd_printk(KERN_ERR
"AK4117 ready timeout (read)\n");
48 pdacf_reg_write(chip
, PDAUDIOCF_REG_AK_IFR
, (u16
)reg
<< 8);
50 while (pdacf_reg_read(chip
, PDAUDIOCF_REG_SCR
) & PDAUDIOCF_AK_SBP
) {
53 spin_unlock_irqrestore(&chip
->ak4117_lock
, flags
);
54 snd_printk(KERN_ERR
"AK4117 read timeout (read2)\n");
58 res
= (unsigned char)pdacf_reg_read(chip
, PDAUDIOCF_REG_AK_IFR
);
59 spin_unlock_irqrestore(&chip
->ak4117_lock
, flags
);
63 static void pdacf_ak4117_write(void *private_data
, unsigned char reg
, unsigned char val
)
65 struct snd_pdacf
*chip
= private_data
;
66 unsigned long timeout
;
69 spin_lock_irqsave(&chip
->ak4117_lock
, flags
);
71 while (inw(chip
->port
+ PDAUDIOCF_REG_SCR
) & PDAUDIOCF_AK_SBP
) {
74 spin_unlock_irqrestore(&chip
->ak4117_lock
, flags
);
75 snd_printk(KERN_ERR
"AK4117 ready timeout (write)\n");
79 outw((u16
)reg
<< 8 | val
| (1<<13), chip
->port
+ PDAUDIOCF_REG_AK_IFR
);
80 spin_unlock_irqrestore(&chip
->ak4117_lock
, flags
);
84 static int pdacf_reset(struct snd_pdacf
*chip
, int powerdown
)
88 val
= pdacf_reg_read(chip
, PDAUDIOCF_REG_SCR
);
90 val
&= ~PDAUDIOCF_RECORD
; /* for sure */
91 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, val
);
94 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, val
);
96 val
&= ~PDAUDIOCF_RST
;
97 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, val
);
100 val
&= ~PDAUDIOCF_PDN
;
101 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, val
);
107 void pdacf_reinit(struct snd_pdacf
*chip
, int resume
)
109 pdacf_reset(chip
, 0);
111 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, chip
->suspend_reg_scr
);
112 snd_ak4117_reinit(chip
->ak4117
);
113 pdacf_reg_write(chip
, PDAUDIOCF_REG_TCR
, chip
->regmap
[PDAUDIOCF_REG_TCR
>>1]);
114 pdacf_reg_write(chip
, PDAUDIOCF_REG_IER
, chip
->regmap
[PDAUDIOCF_REG_IER
>>1]);
117 static void pdacf_proc_read(struct snd_info_entry
* entry
,
118 struct snd_info_buffer
*buffer
)
120 struct snd_pdacf
*chip
= entry
->private_data
;
123 snd_iprintf(buffer
, "PDAudioCF\n\n");
124 tmp
= pdacf_reg_read(chip
, PDAUDIOCF_REG_SCR
);
125 snd_iprintf(buffer
, "FPGA revision : 0x%x\n", PDAUDIOCF_FPGAREV(tmp
));
129 static void pdacf_proc_init(struct snd_pdacf
*chip
)
131 struct snd_info_entry
*entry
;
133 if (! snd_card_proc_new(chip
->card
, "pdaudiocf", &entry
))
134 snd_info_set_text_ops(entry
, chip
, pdacf_proc_read
);
137 struct snd_pdacf
*snd_pdacf_create(struct snd_card
*card
)
139 struct snd_pdacf
*chip
;
141 chip
= kzalloc(sizeof(*chip
), GFP_KERNEL
);
145 spin_lock_init(&chip
->reg_lock
);
146 spin_lock_init(&chip
->ak4117_lock
);
147 tasklet_init(&chip
->tq
, pdacf_tasklet
, (unsigned long)chip
);
148 card
->private_data
= chip
;
150 pdacf_proc_init(chip
);
154 static void snd_pdacf_ak4117_change(struct ak4117
*ak4117
, unsigned char c0
, unsigned char c1
)
156 struct snd_pdacf
*chip
= ak4117
->change_callback_private
;
160 if (!(c0
& AK4117_UNLCK
))
162 spin_lock_irqsave(&chip
->reg_lock
, flags
);
163 val
= chip
->regmap
[PDAUDIOCF_REG_SCR
>>1];
164 if (ak4117
->rcs0
& AK4117_UNLCK
)
165 val
|= PDAUDIOCF_BLUE_LED_OFF
;
167 val
&= ~PDAUDIOCF_BLUE_LED_OFF
;
168 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, val
);
169 spin_unlock_irqrestore(&chip
->reg_lock
, flags
);
172 int snd_pdacf_ak4117_create(struct snd_pdacf
*chip
)
176 /* design note: if we unmask PLL unlock, parity, valid, audio or auto bit interrupts */
177 /* from AK4117 then INT1 pin from AK4117 will be high all time, because PCMCIA interrupts are */
178 /* egde based and FPGA does logical OR for all interrupt sources, we cannot use these */
179 /* high-rate sources */
180 static unsigned char pgm
[5] = {
181 AK4117_XTL_24_576M
| AK4117_EXCT
, /* AK4117_REG_PWRDN */
182 AK4117_CM_PLL_XTAL
| AK4117_PKCS_128fs
| AK4117_XCKS_128fs
, /* AK4117_REQ_CLOCK */
183 AK4117_EFH_1024LRCLK
| AK4117_DIF_24R
| AK4117_IPS
, /* AK4117_REG_IO */
184 0xff, /* AK4117_REG_INT0_MASK */
185 AK4117_MAUTO
| AK4117_MAUD
| AK4117_MULK
| AK4117_MPAR
| AK4117_MV
, /* AK4117_REG_INT1_MASK */
188 err
= pdacf_reset(chip
, 0);
191 err
= snd_ak4117_create(chip
->card
, pdacf_ak4117_read
, pdacf_ak4117_write
, pgm
, chip
, &chip
->ak4117
);
195 val
= pdacf_reg_read(chip
, PDAUDIOCF_REG_TCR
);
196 val
&= ~(PDAUDIOCF_ELIMAKMBIT
|PDAUDIOCF_TESTDATASEL
);
197 pdacf_reg_write(chip
, PDAUDIOCF_REG_TCR
, val
);
199 /* setup the FPGA to match AK4117 setup */
200 val
= pdacf_reg_read(chip
, PDAUDIOCF_REG_SCR
);
201 val
&= ~(PDAUDIOCF_CLKDIV0
| PDAUDIOCF_CLKDIV1
); /* use 24.576Mhz clock */
202 val
&= ~(PDAUDIOCF_RED_LED_OFF
|PDAUDIOCF_BLUE_LED_OFF
);
203 val
|= PDAUDIOCF_DATAFMT0
| PDAUDIOCF_DATAFMT1
; /* 24-bit data */
204 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, val
);
206 /* setup LEDs and IRQ */
207 val
= pdacf_reg_read(chip
, PDAUDIOCF_REG_IER
);
208 val
&= ~(PDAUDIOCF_IRQLVLEN0
| PDAUDIOCF_IRQLVLEN1
);
209 val
&= ~(PDAUDIOCF_BLUEDUTY0
| PDAUDIOCF_REDDUTY0
| PDAUDIOCF_REDDUTY1
);
210 val
|= PDAUDIOCF_BLUEDUTY1
| PDAUDIOCF_HALFRATE
;
211 val
|= PDAUDIOCF_IRQOVREN
| PDAUDIOCF_IRQAKMEN
;
212 pdacf_reg_write(chip
, PDAUDIOCF_REG_IER
, val
);
214 chip
->ak4117
->change_callback_private
= chip
;
215 chip
->ak4117
->change_callback
= snd_pdacf_ak4117_change
;
217 /* update LED status */
218 snd_pdacf_ak4117_change(chip
->ak4117
, AK4117_UNLCK
, 0);
223 void snd_pdacf_powerdown(struct snd_pdacf
*chip
)
227 val
= pdacf_reg_read(chip
, PDAUDIOCF_REG_SCR
);
228 chip
->suspend_reg_scr
= val
;
229 val
|= PDAUDIOCF_RED_LED_OFF
| PDAUDIOCF_BLUE_LED_OFF
;
230 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, val
);
231 /* disable interrupts, but use direct write to preserve old register value in chip->regmap */
232 val
= inw(chip
->port
+ PDAUDIOCF_REG_IER
);
233 val
&= ~(PDAUDIOCF_IRQOVREN
|PDAUDIOCF_IRQAKMEN
|PDAUDIOCF_IRQLVLEN0
|PDAUDIOCF_IRQLVLEN1
);
234 outw(val
, chip
->port
+ PDAUDIOCF_REG_IER
);
235 pdacf_reset(chip
, 1);
240 int snd_pdacf_suspend(struct snd_pdacf
*chip
, pm_message_t state
)
244 snd_power_change_state(chip
->card
, SNDRV_CTL_POWER_D3hot
);
245 snd_pcm_suspend_all(chip
->pcm
);
246 /* disable interrupts, but use direct write to preserve old register value in chip->regmap */
247 val
= inw(chip
->port
+ PDAUDIOCF_REG_IER
);
248 val
&= ~(PDAUDIOCF_IRQOVREN
|PDAUDIOCF_IRQAKMEN
|PDAUDIOCF_IRQLVLEN0
|PDAUDIOCF_IRQLVLEN1
);
249 outw(val
, chip
->port
+ PDAUDIOCF_REG_IER
);
250 chip
->chip_status
|= PDAUDIOCF_STAT_IS_SUSPENDED
; /* ignore interrupts from now */
251 snd_pdacf_powerdown(chip
);
255 static inline int check_signal(struct snd_pdacf
*chip
)
257 return (chip
->ak4117
->rcs0
& AK4117_UNLCK
) == 0;
260 int snd_pdacf_resume(struct snd_pdacf
*chip
)
264 pdacf_reinit(chip
, 1);
265 /* wait for AK4117's PLL */
266 while (timeout
-- > 0 &&
267 (snd_ak4117_external_rate(chip
->ak4117
) <= 0 || !check_signal(chip
)))
269 chip
->chip_status
&= ~PDAUDIOCF_STAT_IS_SUSPENDED
;
270 snd_power_change_state(chip
->card
, SNDRV_CTL_POWER_D0
);