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