1 /* 2 * Routines for control of the AK4114 via I2C and 4-wire serial interface 3 * IEC958 (S/PDIF) receiver by Asahi Kasei 4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 5 * 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 */ 22 23 #include <linux/slab.h> 24 #include <linux/delay.h> 25 #include <linux/module.h> 26 #include <sound/core.h> 27 #include <sound/control.h> 28 #include <sound/pcm.h> 29 #include <sound/ak4114.h> 30 #include <sound/asoundef.h> 31 #include <sound/info.h> 32 33 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 34 MODULE_DESCRIPTION("AK4114 IEC958 (S/PDIF) receiver by Asahi Kasei"); 35 MODULE_LICENSE("GPL"); 36 37 #define AK4114_ADDR 0x00 /* fixed address */ 38 39 static void ak4114_stats(struct work_struct *work); 40 static void ak4114_init_regs(struct ak4114 *chip); 41 42 static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val) 43 { 44 ak4114->write(ak4114->private_data, reg, val); 45 if (reg <= AK4114_REG_INT1_MASK) 46 ak4114->regmap[reg] = val; 47 else if (reg >= AK4114_REG_TXCSB0 && reg <= AK4114_REG_TXCSB4) 48 ak4114->txcsb[reg-AK4114_REG_TXCSB0] = val; 49 } 50 51 static inline unsigned char reg_read(struct ak4114 *ak4114, unsigned char reg) 52 { 53 return ak4114->read(ak4114->private_data, reg); 54 } 55 56 #if 0 57 static void reg_dump(struct ak4114 *ak4114) 58 { 59 int i; 60 61 printk(KERN_DEBUG "AK4114 REG DUMP:\n"); 62 for (i = 0; i < 0x20; i++) 63 printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0); 64 } 65 #endif 66 67 static void snd_ak4114_free(struct ak4114 *chip) 68 { 69 chip->init = 1; /* don't schedule new work */ 70 mb(); 71 cancel_delayed_work_sync(&chip->work); 72 kfree(chip); 73 } 74 75 static int snd_ak4114_dev_free(struct snd_device *device) 76 { 77 struct ak4114 *chip = device->device_data; 78 snd_ak4114_free(chip); 79 return 0; 80 } 81 82 int snd_ak4114_create(struct snd_card *card, 83 ak4114_read_t *read, ak4114_write_t *write, 84 const unsigned char pgm[7], const unsigned char txcsb[5], 85 void *private_data, struct ak4114 **r_ak4114) 86 { 87 struct ak4114 *chip; 88 int err = 0; 89 unsigned char reg; 90 static struct snd_device_ops ops = { 91 .dev_free = snd_ak4114_dev_free, 92 }; 93 94 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 95 if (chip == NULL) 96 return -ENOMEM; 97 spin_lock_init(&chip->lock); 98 chip->card = card; 99 chip->read = read; 100 chip->write = write; 101 chip->private_data = private_data; 102 INIT_DELAYED_WORK(&chip->work, ak4114_stats); 103 104 for (reg = 0; reg < 7; reg++) 105 chip->regmap[reg] = pgm[reg]; 106 for (reg = 0; reg < 5; reg++) 107 chip->txcsb[reg] = txcsb[reg]; 108 109 ak4114_init_regs(chip); 110 111 chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT); 112 chip->rcs1 = reg_read(chip, AK4114_REG_RCS1); 113 114 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) 115 goto __fail; 116 117 if (r_ak4114) 118 *r_ak4114 = chip; 119 return 0; 120 121 __fail: 122 snd_ak4114_free(chip); 123 return err < 0 ? err : -EIO; 124 } 125 126 void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char mask, unsigned char val) 127 { 128 if (reg <= AK4114_REG_INT1_MASK) 129 reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val); 130 else if (reg >= AK4114_REG_TXCSB0 && reg <= AK4114_REG_TXCSB4) 131 reg_write(chip, reg, 132 (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val); 133 } 134 135 static void ak4114_init_regs(struct ak4114 *chip) 136 { 137 unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg; 138 139 /* bring the chip to reset state and powerdown state */ 140 reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN)); 141 udelay(200); 142 /* release reset, but leave powerdown */ 143 reg_write(chip, AK4114_REG_PWRDN, (old | AK4114_RST) & ~AK4114_PWN); 144 udelay(200); 145 for (reg = 1; reg < 7; reg++) 146 reg_write(chip, reg, chip->regmap[reg]); 147 for (reg = 0; reg < 5; reg++) 148 reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]); 149 /* release powerdown, everything is initialized now */ 150 reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN); 151 } 152 153 void snd_ak4114_reinit(struct ak4114 *chip) 154 { 155 chip->init = 1; 156 mb(); 157 flush_delayed_work_sync(&chip->work); 158 ak4114_init_regs(chip); 159 /* bring up statistics / event queing */ 160 chip->init = 0; 161 if (chip->kctls[0]) 162 schedule_delayed_work(&chip->work, HZ / 10); 163 } 164 165 static unsigned int external_rate(unsigned char rcs1) 166 { 167 switch (rcs1 & (AK4114_FS0|AK4114_FS1|AK4114_FS2|AK4114_FS3)) { 168 case AK4114_FS_32000HZ: return 32000; 169 case AK4114_FS_44100HZ: return 44100; 170 case AK4114_FS_48000HZ: return 48000; 171 case AK4114_FS_88200HZ: return 88200; 172 case AK4114_FS_96000HZ: return 96000; 173 case AK4114_FS_176400HZ: return 176400; 174 case AK4114_FS_192000HZ: return 192000; 175 default: return 0; 176 } 177 } 178 179 static int snd_ak4114_in_error_info(struct snd_kcontrol *kcontrol, 180 struct snd_ctl_elem_info *uinfo) 181 { 182 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 183 uinfo->count = 1; 184 uinfo->value.integer.min = 0; 185 uinfo->value.integer.max = LONG_MAX; 186 return 0; 187 } 188 189 static int snd_ak4114_in_error_get(struct snd_kcontrol *kcontrol, 190 struct snd_ctl_elem_value *ucontrol) 191 { 192 struct ak4114 *chip = snd_kcontrol_chip(kcontrol); 193 long *ptr; 194 195 spin_lock_irq(&chip->lock); 196 ptr = (long *)(((char *)chip) + kcontrol->private_value); 197 ucontrol->value.integer.value[0] = *ptr; 198 *ptr = 0; 199 spin_unlock_irq(&chip->lock); 200 return 0; 201 } 202 203 #define snd_ak4114_in_bit_info snd_ctl_boolean_mono_info 204 205 static int snd_ak4114_in_bit_get(struct snd_kcontrol *kcontrol, 206 struct snd_ctl_elem_value *ucontrol) 207 { 208 struct ak4114 *chip = snd_kcontrol_chip(kcontrol); 209 unsigned char reg = kcontrol->private_value & 0xff; 210 unsigned char bit = (kcontrol->private_value >> 8) & 0xff; 211 unsigned char inv = (kcontrol->private_value >> 31) & 1; 212 213 ucontrol->value.integer.value[0] = ((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv; 214 return 0; 215 } 216 217 static int snd_ak4114_rate_info(struct snd_kcontrol *kcontrol, 218 struct snd_ctl_elem_info *uinfo) 219 { 220 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 221 uinfo->count = 1; 222 uinfo->value.integer.min = 0; 223 uinfo->value.integer.max = 192000; 224 return 0; 225 } 226 227 static int snd_ak4114_rate_get(struct snd_kcontrol *kcontrol, 228 struct snd_ctl_elem_value *ucontrol) 229 { 230 struct ak4114 *chip = snd_kcontrol_chip(kcontrol); 231 232 ucontrol->value.integer.value[0] = external_rate(reg_read(chip, AK4114_REG_RCS1)); 233 return 0; 234 } 235 236 static int snd_ak4114_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 237 { 238 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 239 uinfo->count = 1; 240 return 0; 241 } 242 243 static int snd_ak4114_spdif_get(struct snd_kcontrol *kcontrol, 244 struct snd_ctl_elem_value *ucontrol) 245 { 246 struct ak4114 *chip = snd_kcontrol_chip(kcontrol); 247 unsigned i; 248 249 for (i = 0; i < AK4114_REG_RXCSB_SIZE; i++) 250 ucontrol->value.iec958.status[i] = reg_read(chip, AK4114_REG_RXCSB0 + i); 251 return 0; 252 } 253 254 static int snd_ak4114_spdif_playback_get(struct snd_kcontrol *kcontrol, 255 struct snd_ctl_elem_value *ucontrol) 256 { 257 struct ak4114 *chip = snd_kcontrol_chip(kcontrol); 258 unsigned i; 259 260 for (i = 0; i < AK4114_REG_TXCSB_SIZE; i++) 261 ucontrol->value.iec958.status[i] = chip->txcsb[i]; 262 return 0; 263 } 264 265 static int snd_ak4114_spdif_playback_put(struct snd_kcontrol *kcontrol, 266 struct snd_ctl_elem_value *ucontrol) 267 { 268 struct ak4114 *chip = snd_kcontrol_chip(kcontrol); 269 unsigned i; 270 271 for (i = 0; i < AK4114_REG_TXCSB_SIZE; i++) 272 reg_write(chip, AK4114_REG_TXCSB0 + i, ucontrol->value.iec958.status[i]); 273 return 0; 274 } 275 276 static int snd_ak4114_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 277 { 278 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 279 uinfo->count = 1; 280 return 0; 281 } 282 283 static int snd_ak4114_spdif_mask_get(struct snd_kcontrol *kcontrol, 284 struct snd_ctl_elem_value *ucontrol) 285 { 286 memset(ucontrol->value.iec958.status, 0xff, AK4114_REG_RXCSB_SIZE); 287 return 0; 288 } 289 290 static int snd_ak4114_spdif_pinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 291 { 292 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 293 uinfo->value.integer.min = 0; 294 uinfo->value.integer.max = 0xffff; 295 uinfo->count = 4; 296 return 0; 297 } 298 299 static int snd_ak4114_spdif_pget(struct snd_kcontrol *kcontrol, 300 struct snd_ctl_elem_value *ucontrol) 301 { 302 struct ak4114 *chip = snd_kcontrol_chip(kcontrol); 303 unsigned short tmp; 304 305 ucontrol->value.integer.value[0] = 0xf8f2; 306 ucontrol->value.integer.value[1] = 0x4e1f; 307 tmp = reg_read(chip, AK4114_REG_Pc0) | (reg_read(chip, AK4114_REG_Pc1) << 8); 308 ucontrol->value.integer.value[2] = tmp; 309 tmp = reg_read(chip, AK4114_REG_Pd0) | (reg_read(chip, AK4114_REG_Pd1) << 8); 310 ucontrol->value.integer.value[3] = tmp; 311 return 0; 312 } 313 314 static int snd_ak4114_spdif_qinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 315 { 316 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 317 uinfo->count = AK4114_REG_QSUB_SIZE; 318 return 0; 319 } 320 321 static int snd_ak4114_spdif_qget(struct snd_kcontrol *kcontrol, 322 struct snd_ctl_elem_value *ucontrol) 323 { 324 struct ak4114 *chip = snd_kcontrol_chip(kcontrol); 325 unsigned i; 326 327 for (i = 0; i < AK4114_REG_QSUB_SIZE; i++) 328 ucontrol->value.bytes.data[i] = reg_read(chip, AK4114_REG_QSUB_ADDR + i); 329 return 0; 330 } 331 332 /* Don't forget to change AK4114_CONTROLS define!!! */ 333 static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { 334 { 335 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 336 .name = "IEC958 Parity Errors", 337 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 338 .info = snd_ak4114_in_error_info, 339 .get = snd_ak4114_in_error_get, 340 .private_value = offsetof(struct ak4114, parity_errors), 341 }, 342 { 343 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 344 .name = "IEC958 V-Bit Errors", 345 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 346 .info = snd_ak4114_in_error_info, 347 .get = snd_ak4114_in_error_get, 348 .private_value = offsetof(struct ak4114, v_bit_errors), 349 }, 350 { 351 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 352 .name = "IEC958 C-CRC Errors", 353 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 354 .info = snd_ak4114_in_error_info, 355 .get = snd_ak4114_in_error_get, 356 .private_value = offsetof(struct ak4114, ccrc_errors), 357 }, 358 { 359 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 360 .name = "IEC958 Q-CRC Errors", 361 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 362 .info = snd_ak4114_in_error_info, 363 .get = snd_ak4114_in_error_get, 364 .private_value = offsetof(struct ak4114, qcrc_errors), 365 }, 366 { 367 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 368 .name = "IEC958 External Rate", 369 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 370 .info = snd_ak4114_rate_info, 371 .get = snd_ak4114_rate_get, 372 }, 373 { 374 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 375 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 376 .access = SNDRV_CTL_ELEM_ACCESS_READ, 377 .info = snd_ak4114_spdif_mask_info, 378 .get = snd_ak4114_spdif_mask_get, 379 }, 380 { 381 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 382 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 383 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 384 .info = snd_ak4114_spdif_info, 385 .get = snd_ak4114_spdif_playback_get, 386 .put = snd_ak4114_spdif_playback_put, 387 }, 388 { 389 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 390 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK), 391 .access = SNDRV_CTL_ELEM_ACCESS_READ, 392 .info = snd_ak4114_spdif_mask_info, 393 .get = snd_ak4114_spdif_mask_get, 394 }, 395 { 396 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 397 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 398 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 399 .info = snd_ak4114_spdif_info, 400 .get = snd_ak4114_spdif_get, 401 }, 402 { 403 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 404 .name = "IEC958 Preample Capture Default", 405 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 406 .info = snd_ak4114_spdif_pinfo, 407 .get = snd_ak4114_spdif_pget, 408 }, 409 { 410 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 411 .name = "IEC958 Q-subcode Capture Default", 412 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 413 .info = snd_ak4114_spdif_qinfo, 414 .get = snd_ak4114_spdif_qget, 415 }, 416 { 417 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 418 .name = "IEC958 Audio", 419 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 420 .info = snd_ak4114_in_bit_info, 421 .get = snd_ak4114_in_bit_get, 422 .private_value = (1<<31) | (1<<8) | AK4114_REG_RCS0, 423 }, 424 { 425 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 426 .name = "IEC958 Non-PCM Bitstream", 427 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 428 .info = snd_ak4114_in_bit_info, 429 .get = snd_ak4114_in_bit_get, 430 .private_value = (6<<8) | AK4114_REG_RCS0, 431 }, 432 { 433 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 434 .name = "IEC958 DTS Bitstream", 435 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 436 .info = snd_ak4114_in_bit_info, 437 .get = snd_ak4114_in_bit_get, 438 .private_value = (3<<8) | AK4114_REG_RCS0, 439 }, 440 { 441 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 442 .name = "IEC958 PPL Lock Status", 443 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 444 .info = snd_ak4114_in_bit_info, 445 .get = snd_ak4114_in_bit_get, 446 .private_value = (1<<31) | (4<<8) | AK4114_REG_RCS0, 447 } 448 }; 449 450 451 static void snd_ak4114_proc_regs_read(struct snd_info_entry *entry, 452 struct snd_info_buffer *buffer) 453 { 454 struct ak4114 *ak4114 = entry->private_data; 455 int reg, val; 456 /* all ak4114 registers 0x00 - 0x1f */ 457 for (reg = 0; reg < 0x20; reg++) { 458 val = reg_read(ak4114, reg); 459 snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val); 460 } 461 } 462 463 static void snd_ak4114_proc_init(struct ak4114 *ak4114) 464 { 465 struct snd_info_entry *entry; 466 if (!snd_card_proc_new(ak4114->card, "ak4114", &entry)) 467 snd_info_set_text_ops(entry, ak4114, snd_ak4114_proc_regs_read); 468 } 469 470 int snd_ak4114_build(struct ak4114 *ak4114, 471 struct snd_pcm_substream *ply_substream, 472 struct snd_pcm_substream *cap_substream) 473 { 474 struct snd_kcontrol *kctl; 475 unsigned int idx; 476 int err; 477 478 if (snd_BUG_ON(!cap_substream)) 479 return -EINVAL; 480 ak4114->playback_substream = ply_substream; 481 ak4114->capture_substream = cap_substream; 482 for (idx = 0; idx < AK4114_CONTROLS; idx++) { 483 kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114); 484 if (kctl == NULL) 485 return -ENOMEM; 486 if (strstr(kctl->id.name, "Playback")) { 487 if (ply_substream == NULL) { 488 snd_ctl_free_one(kctl); 489 ak4114->kctls[idx] = NULL; 490 continue; 491 } 492 kctl->id.device = ply_substream->pcm->device; 493 kctl->id.subdevice = ply_substream->number; 494 } else { 495 kctl->id.device = cap_substream->pcm->device; 496 kctl->id.subdevice = cap_substream->number; 497 } 498 err = snd_ctl_add(ak4114->card, kctl); 499 if (err < 0) 500 return err; 501 ak4114->kctls[idx] = kctl; 502 } 503 snd_ak4114_proc_init(ak4114); 504 /* trigger workq */ 505 schedule_delayed_work(&ak4114->work, HZ / 10); 506 return 0; 507 } 508 509 /* notify kcontrols if any parameters are changed */ 510 static void ak4114_notify(struct ak4114 *ak4114, 511 unsigned char rcs0, unsigned char rcs1, 512 unsigned char c0, unsigned char c1) 513 { 514 if (!ak4114->kctls[0]) 515 return; 516 517 if (rcs0 & AK4114_PAR) 518 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 519 &ak4114->kctls[0]->id); 520 if (rcs0 & AK4114_V) 521 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 522 &ak4114->kctls[1]->id); 523 if (rcs1 & AK4114_CCRC) 524 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 525 &ak4114->kctls[2]->id); 526 if (rcs1 & AK4114_QCRC) 527 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 528 &ak4114->kctls[3]->id); 529 530 /* rate change */ 531 if (c1 & 0xf0) 532 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 533 &ak4114->kctls[4]->id); 534 535 if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT)) 536 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 537 &ak4114->kctls[9]->id); 538 if (c0 & AK4114_QINT) 539 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 540 &ak4114->kctls[10]->id); 541 542 if (c0 & AK4114_AUDION) 543 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 544 &ak4114->kctls[11]->id); 545 if (c0 & AK4114_AUTO) 546 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 547 &ak4114->kctls[12]->id); 548 if (c0 & AK4114_DTSCD) 549 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 550 &ak4114->kctls[13]->id); 551 if (c0 & AK4114_UNLCK) 552 snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, 553 &ak4114->kctls[14]->id); 554 } 555 556 int snd_ak4114_external_rate(struct ak4114 *ak4114) 557 { 558 unsigned char rcs1; 559 560 rcs1 = reg_read(ak4114, AK4114_REG_RCS1); 561 return external_rate(rcs1); 562 } 563 564 int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags) 565 { 566 struct snd_pcm_runtime *runtime = ak4114->capture_substream ? ak4114->capture_substream->runtime : NULL; 567 unsigned long _flags; 568 int res = 0; 569 unsigned char rcs0, rcs1; 570 unsigned char c0, c1; 571 572 rcs1 = reg_read(ak4114, AK4114_REG_RCS1); 573 if (flags & AK4114_CHECK_NO_STAT) 574 goto __rate; 575 rcs0 = reg_read(ak4114, AK4114_REG_RCS0); 576 spin_lock_irqsave(&ak4114->lock, _flags); 577 if (rcs0 & AK4114_PAR) 578 ak4114->parity_errors++; 579 if (rcs1 & AK4114_V) 580 ak4114->v_bit_errors++; 581 if (rcs1 & AK4114_CCRC) 582 ak4114->ccrc_errors++; 583 if (rcs1 & AK4114_QCRC) 584 ak4114->qcrc_errors++; 585 c0 = (ak4114->rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)) ^ 586 (rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)); 587 c1 = (ak4114->rcs1 & 0xf0) ^ (rcs1 & 0xf0); 588 ak4114->rcs0 = rcs0 & ~(AK4114_QINT | AK4114_CINT); 589 ak4114->rcs1 = rcs1; 590 spin_unlock_irqrestore(&ak4114->lock, _flags); 591 592 ak4114_notify(ak4114, rcs0, rcs1, c0, c1); 593 if (ak4114->change_callback && (c0 | c1) != 0) 594 ak4114->change_callback(ak4114, c0, c1); 595 596 __rate: 597 /* compare rate */ 598 res = external_rate(rcs1); 599 if (!(flags & AK4114_CHECK_NO_RATE) && runtime && runtime->rate != res) { 600 snd_pcm_stream_lock_irqsave(ak4114->capture_substream, _flags); 601 if (snd_pcm_running(ak4114->capture_substream)) { 602 // printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res); 603 snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING); 604 res = 1; 605 } 606 snd_pcm_stream_unlock_irqrestore(ak4114->capture_substream, _flags); 607 } 608 return res; 609 } 610 611 static void ak4114_stats(struct work_struct *work) 612 { 613 struct ak4114 *chip = container_of(work, struct ak4114, work.work); 614 615 if (!chip->init) 616 snd_ak4114_check_rate_and_errors(chip, chip->check_flags); 617 618 schedule_delayed_work(&chip->work, HZ / 10); 619 } 620 621 EXPORT_SYMBOL(snd_ak4114_create); 622 EXPORT_SYMBOL(snd_ak4114_reg_write); 623 EXPORT_SYMBOL(snd_ak4114_reinit); 624 EXPORT_SYMBOL(snd_ak4114_build); 625 EXPORT_SYMBOL(snd_ak4114_external_rate); 626 EXPORT_SYMBOL(snd_ak4114_check_rate_and_errors); 627