1 /* 2 * Driver for Sound Core PDAudioCF soundcard 3 * 4 * Copyright (c) 2003 by Jaroslav Kysela <perex@suse.cz> 5 * 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. 10 * 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. 15 * 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 19 */ 20 21 #include <sound/driver.h> 22 #include <linux/delay.h> 23 #include <sound/core.h> 24 #include <sound/info.h> 25 #include "pdaudiocf.h" 26 #include <sound/initval.h> 27 28 /* 29 * 30 */ 31 static unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg) 32 { 33 struct snd_pdacf *chip = private_data; 34 unsigned long timeout; 35 unsigned long flags; 36 unsigned char res; 37 38 spin_lock_irqsave(&chip->ak4117_lock, flags); 39 timeout = 1000; 40 while (pdacf_reg_read(chip, PDAUDIOCF_REG_SCR) & PDAUDIOCF_AK_SBP) { 41 udelay(5); 42 if (--timeout == 0) { 43 spin_unlock_irqrestore(&chip->ak4117_lock, flags); 44 snd_printk(KERN_ERR "AK4117 ready timeout (read)\n"); 45 return 0; 46 } 47 } 48 pdacf_reg_write(chip, PDAUDIOCF_REG_AK_IFR, (u16)reg << 8); 49 timeout = 1000; 50 while (pdacf_reg_read(chip, PDAUDIOCF_REG_SCR) & PDAUDIOCF_AK_SBP) { 51 udelay(5); 52 if (--timeout == 0) { 53 spin_unlock_irqrestore(&chip->ak4117_lock, flags); 54 snd_printk(KERN_ERR "AK4117 read timeout (read2)\n"); 55 return 0; 56 } 57 } 58 res = (unsigned char)pdacf_reg_read(chip, PDAUDIOCF_REG_AK_IFR); 59 spin_unlock_irqrestore(&chip->ak4117_lock, flags); 60 return res; 61 } 62 63 static void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned char val) 64 { 65 struct snd_pdacf *chip = private_data; 66 unsigned long timeout; 67 unsigned long flags; 68 69 spin_lock_irqsave(&chip->ak4117_lock, flags); 70 timeout = 1000; 71 while (inw(chip->port + PDAUDIOCF_REG_SCR) & PDAUDIOCF_AK_SBP) { 72 udelay(5); 73 if (--timeout == 0) { 74 spin_unlock_irqrestore(&chip->ak4117_lock, flags); 75 snd_printk(KERN_ERR "AK4117 ready timeout (write)\n"); 76 return; 77 } 78 } 79 outw((u16)reg << 8 | val | (1<<13), chip->port + PDAUDIOCF_REG_AK_IFR); 80 spin_unlock_irqrestore(&chip->ak4117_lock, flags); 81 } 82 83 #if 0 84 void pdacf_dump(struct snd_pdacf *chip) 85 { 86 printk("PDAUDIOCF DUMP (0x%lx):\n", chip->port); 87 printk("WPD : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_WDP)); 88 printk("RDP : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_RDP)); 89 printk("TCR : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_TCR)); 90 printk("SCR : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_SCR)); 91 printk("ISR : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_ISR)); 92 printk("IER : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_IER)); 93 printk("AK_IFR : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_AK_IFR)); 94 } 95 #endif 96 97 static int pdacf_reset(struct snd_pdacf *chip, int powerdown) 98 { 99 u16 val; 100 101 val = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR); 102 val |= PDAUDIOCF_PDN; 103 val &= ~PDAUDIOCF_RECORD; /* for sure */ 104 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val); 105 udelay(5); 106 val |= PDAUDIOCF_RST; 107 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val); 108 udelay(200); 109 val &= ~PDAUDIOCF_RST; 110 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val); 111 udelay(5); 112 if (!powerdown) { 113 val &= ~PDAUDIOCF_PDN; 114 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val); 115 udelay(200); 116 } 117 return 0; 118 } 119 120 void pdacf_reinit(struct snd_pdacf *chip, int resume) 121 { 122 pdacf_reset(chip, 0); 123 if (resume) 124 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, chip->suspend_reg_scr); 125 snd_ak4117_reinit(chip->ak4117); 126 pdacf_reg_write(chip, PDAUDIOCF_REG_TCR, chip->regmap[PDAUDIOCF_REG_TCR>>1]); 127 pdacf_reg_write(chip, PDAUDIOCF_REG_IER, chip->regmap[PDAUDIOCF_REG_IER>>1]); 128 } 129 130 static void pdacf_proc_read(struct snd_info_entry * entry, 131 struct snd_info_buffer *buffer) 132 { 133 struct snd_pdacf *chip = entry->private_data; 134 u16 tmp; 135 136 snd_iprintf(buffer, "PDAudioCF\n\n"); 137 tmp = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR); 138 snd_iprintf(buffer, "FPGA revision : 0x%x\n", PDAUDIOCF_FPGAREV(tmp)); 139 140 } 141 142 static void pdacf_proc_init(struct snd_pdacf *chip) 143 { 144 struct snd_info_entry *entry; 145 146 if (! snd_card_proc_new(chip->card, "pdaudiocf", &entry)) 147 snd_info_set_text_ops(entry, chip, 1024, pdacf_proc_read); 148 } 149 150 struct snd_pdacf *snd_pdacf_create(struct snd_card *card) 151 { 152 struct snd_pdacf *chip; 153 154 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 155 if (chip == NULL) 156 return NULL; 157 chip->card = card; 158 spin_lock_init(&chip->reg_lock); 159 spin_lock_init(&chip->ak4117_lock); 160 tasklet_init(&chip->tq, pdacf_tasklet, (unsigned long)chip); 161 card->private_data = chip; 162 163 pdacf_proc_init(chip); 164 return chip; 165 } 166 167 static void snd_pdacf_ak4117_change(struct ak4117 *ak4117, unsigned char c0, unsigned char c1) 168 { 169 struct snd_pdacf *chip = ak4117->change_callback_private; 170 unsigned long flags; 171 u16 val; 172 173 if (!(c0 & AK4117_UNLCK)) 174 return; 175 spin_lock_irqsave(&chip->reg_lock, flags); 176 val = chip->regmap[PDAUDIOCF_REG_SCR>>1]; 177 if (ak4117->rcs0 & AK4117_UNLCK) 178 val |= PDAUDIOCF_BLUE_LED_OFF; 179 else 180 val &= ~PDAUDIOCF_BLUE_LED_OFF; 181 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val); 182 spin_unlock_irqrestore(&chip->reg_lock, flags); 183 } 184 185 int snd_pdacf_ak4117_create(struct snd_pdacf *chip) 186 { 187 int err; 188 u16 val; 189 /* design note: if we unmask PLL unlock, parity, valid, audio or auto bit interrupts */ 190 /* from AK4117 then INT1 pin from AK4117 will be high all time, because PCMCIA interrupts are */ 191 /* egde based and FPGA does logical OR for all interrupt sources, we cannot use these */ 192 /* high-rate sources */ 193 static unsigned char pgm[5] = { 194 AK4117_XTL_24_576M | AK4117_EXCT, /* AK4117_REG_PWRDN */ 195 AK4117_CM_PLL_XTAL | AK4117_PKCS_128fs | AK4117_XCKS_128fs, /* AK4117_REQ_CLOCK */ 196 AK4117_EFH_1024LRCLK | AK4117_DIF_24R | AK4117_IPS, /* AK4117_REG_IO */ 197 0xff, /* AK4117_REG_INT0_MASK */ 198 AK4117_MAUTO | AK4117_MAUD | AK4117_MULK | AK4117_MPAR | AK4117_MV, /* AK4117_REG_INT1_MASK */ 199 }; 200 201 err = pdacf_reset(chip, 0); 202 if (err < 0) 203 return err; 204 err = snd_ak4117_create(chip->card, pdacf_ak4117_read, pdacf_ak4117_write, pgm, chip, &chip->ak4117); 205 if (err < 0) 206 return err; 207 208 val = pdacf_reg_read(chip, PDAUDIOCF_REG_TCR); 209 #if 1 /* normal operation */ 210 val &= ~(PDAUDIOCF_ELIMAKMBIT|PDAUDIOCF_TESTDATASEL); 211 #else /* debug */ 212 val |= PDAUDIOCF_ELIMAKMBIT; 213 val &= ~PDAUDIOCF_TESTDATASEL; 214 #endif 215 pdacf_reg_write(chip, PDAUDIOCF_REG_TCR, val); 216 217 /* setup the FPGA to match AK4117 setup */ 218 val = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR); 219 val &= ~(PDAUDIOCF_CLKDIV0 | PDAUDIOCF_CLKDIV1); /* use 24.576Mhz clock */ 220 val &= ~(PDAUDIOCF_RED_LED_OFF|PDAUDIOCF_BLUE_LED_OFF); 221 val |= PDAUDIOCF_DATAFMT0 | PDAUDIOCF_DATAFMT1; /* 24-bit data */ 222 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val); 223 224 /* setup LEDs and IRQ */ 225 val = pdacf_reg_read(chip, PDAUDIOCF_REG_IER); 226 val &= ~(PDAUDIOCF_IRQLVLEN0 | PDAUDIOCF_IRQLVLEN1); 227 val &= ~(PDAUDIOCF_BLUEDUTY0 | PDAUDIOCF_REDDUTY0 | PDAUDIOCF_REDDUTY1); 228 val |= PDAUDIOCF_BLUEDUTY1 | PDAUDIOCF_HALFRATE; 229 val |= PDAUDIOCF_IRQOVREN | PDAUDIOCF_IRQAKMEN; 230 pdacf_reg_write(chip, PDAUDIOCF_REG_IER, val); 231 232 chip->ak4117->change_callback_private = chip; 233 chip->ak4117->change_callback = snd_pdacf_ak4117_change; 234 235 /* update LED status */ 236 snd_pdacf_ak4117_change(chip->ak4117, AK4117_UNLCK, 0); 237 238 return 0; 239 } 240 241 void snd_pdacf_powerdown(struct snd_pdacf *chip) 242 { 243 u16 val; 244 245 val = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR); 246 chip->suspend_reg_scr = val; 247 val |= PDAUDIOCF_RED_LED_OFF | PDAUDIOCF_BLUE_LED_OFF; 248 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, val); 249 /* disable interrupts, but use direct write to preserve old register value in chip->regmap */ 250 val = inw(chip->port + PDAUDIOCF_REG_IER); 251 val &= ~(PDAUDIOCF_IRQOVREN|PDAUDIOCF_IRQAKMEN|PDAUDIOCF_IRQLVLEN0|PDAUDIOCF_IRQLVLEN1); 252 outw(val, chip->port + PDAUDIOCF_REG_IER); 253 pdacf_reset(chip, 1); 254 } 255 256 #ifdef CONFIG_PM 257 258 int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state) 259 { 260 u16 val; 261 262 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); 263 snd_pcm_suspend_all(chip->pcm); 264 /* disable interrupts, but use direct write to preserve old register value in chip->regmap */ 265 val = inw(chip->port + PDAUDIOCF_REG_IER); 266 val &= ~(PDAUDIOCF_IRQOVREN|PDAUDIOCF_IRQAKMEN|PDAUDIOCF_IRQLVLEN0|PDAUDIOCF_IRQLVLEN1); 267 outw(val, chip->port + PDAUDIOCF_REG_IER); 268 chip->chip_status |= PDAUDIOCF_STAT_IS_SUSPENDED; /* ignore interrupts from now */ 269 snd_pdacf_powerdown(chip); 270 return 0; 271 } 272 273 static inline int check_signal(struct snd_pdacf *chip) 274 { 275 return (chip->ak4117->rcs0 & AK4117_UNLCK) == 0; 276 } 277 278 int snd_pdacf_resume(struct snd_pdacf *chip) 279 { 280 int timeout = 40; 281 282 pdacf_reinit(chip, 1); 283 /* wait for AK4117's PLL */ 284 while (timeout-- > 0 && 285 (snd_ak4117_external_rate(chip->ak4117) <= 0 || !check_signal(chip))) 286 mdelay(1); 287 chip->chip_status &= ~PDAUDIOCF_STAT_IS_SUSPENDED; 288 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0); 289 return 0; 290 } 291 #endif 292