1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Routines for control of the AK4117 via 4-wire serial interface 4 * IEC958 (S/PDIF) receiver by Asahi Kasei 5 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 6 */ 7 8 #include <linux/slab.h> 9 #include <linux/delay.h> 10 #include <linux/module.h> 11 #include <sound/core.h> 12 #include <sound/control.h> 13 #include <sound/pcm.h> 14 #include <sound/ak4117.h> 15 #include <sound/asoundef.h> 16 17 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 18 MODULE_DESCRIPTION("AK4117 IEC958 (S/PDIF) receiver by Asahi Kasei"); 19 MODULE_LICENSE("GPL"); 20 21 #define AK4117_ADDR 0x00 /* fixed address */ 22 23 static void snd_ak4117_timer(struct timer_list *t); 24 25 static void reg_write(struct ak4117 *ak4117, unsigned char reg, unsigned char val) 26 { 27 ak4117->write(ak4117->private_data, reg, val); 28 if (reg < sizeof(ak4117->regmap)) 29 ak4117->regmap[reg] = val; 30 } 31 32 static inline unsigned char reg_read(struct ak4117 *ak4117, unsigned char reg) 33 { 34 return ak4117->read(ak4117->private_data, reg); 35 } 36 37 #if 0 38 static void reg_dump(struct ak4117 *ak4117) 39 { 40 int i; 41 42 printk(KERN_DEBUG "AK4117 REG DUMP:\n"); 43 for (i = 0; i < 0x1b; i++) 44 printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0); 45 } 46 #endif 47 48 static void snd_ak4117_free(struct ak4117 *chip) 49 { 50 timer_shutdown_sync(&chip->timer); 51 kfree(chip); 52 } 53 54 static int snd_ak4117_dev_free(struct snd_device *device) 55 { 56 struct ak4117 *chip = device->device_data; 57 snd_ak4117_free(chip); 58 return 0; 59 } 60 61 int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t *write, 62 const unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117) 63 { 64 struct ak4117 *chip; 65 int err = 0; 66 unsigned char reg; 67 static const struct snd_device_ops ops = { 68 .dev_free = snd_ak4117_dev_free, 69 }; 70 71 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 72 if (chip == NULL) 73 return -ENOMEM; 74 spin_lock_init(&chip->lock); 75 chip->card = card; 76 chip->read = read; 77 chip->write = write; 78 chip->private_data = private_data; 79 timer_setup(&chip->timer, snd_ak4117_timer, 0); 80 81 for (reg = 0; reg < 5; reg++) 82 chip->regmap[reg] = pgm[reg]; 83 snd_ak4117_reinit(chip); 84 85 chip->rcs0 = reg_read(chip, AK4117_REG_RCS0) & ~(AK4117_QINT | AK4117_CINT | AK4117_STC); 86 chip->rcs1 = reg_read(chip, AK4117_REG_RCS1); 87 chip->rcs2 = reg_read(chip, AK4117_REG_RCS2); 88 89 err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops); 90 if (err < 0) 91 goto __fail; 92 93 if (r_ak4117) 94 *r_ak4117 = chip; 95 return 0; 96 97 __fail: 98 snd_ak4117_free(chip); 99 return err; 100 } 101 102 void snd_ak4117_reg_write(struct ak4117 *chip, unsigned char reg, unsigned char mask, unsigned char val) 103 { 104 if (reg >= 5) 105 return; 106 reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val); 107 } 108 109 void snd_ak4117_reinit(struct ak4117 *chip) 110 { 111 unsigned char old = chip->regmap[AK4117_REG_PWRDN], reg; 112 113 del_timer(&chip->timer); 114 chip->init = 1; 115 /* bring the chip to reset state and powerdown state */ 116 reg_write(chip, AK4117_REG_PWRDN, 0); 117 udelay(200); 118 /* release reset, but leave powerdown */ 119 reg_write(chip, AK4117_REG_PWRDN, (old | AK4117_RST) & ~AK4117_PWN); 120 udelay(200); 121 for (reg = 1; reg < 5; reg++) 122 reg_write(chip, reg, chip->regmap[reg]); 123 /* release powerdown, everything is initialized now */ 124 reg_write(chip, AK4117_REG_PWRDN, old | AK4117_RST | AK4117_PWN); 125 chip->init = 0; 126 mod_timer(&chip->timer, 1 + jiffies); 127 } 128 129 static unsigned int external_rate(unsigned char rcs1) 130 { 131 switch (rcs1 & (AK4117_FS0|AK4117_FS1|AK4117_FS2|AK4117_FS3)) { 132 case AK4117_FS_32000HZ: return 32000; 133 case AK4117_FS_44100HZ: return 44100; 134 case AK4117_FS_48000HZ: return 48000; 135 case AK4117_FS_88200HZ: return 88200; 136 case AK4117_FS_96000HZ: return 96000; 137 case AK4117_FS_176400HZ: return 176400; 138 case AK4117_FS_192000HZ: return 192000; 139 default: return 0; 140 } 141 } 142 143 static int snd_ak4117_in_error_info(struct snd_kcontrol *kcontrol, 144 struct snd_ctl_elem_info *uinfo) 145 { 146 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 147 uinfo->count = 1; 148 uinfo->value.integer.min = 0; 149 uinfo->value.integer.max = LONG_MAX; 150 return 0; 151 } 152 153 static int snd_ak4117_in_error_get(struct snd_kcontrol *kcontrol, 154 struct snd_ctl_elem_value *ucontrol) 155 { 156 struct ak4117 *chip = snd_kcontrol_chip(kcontrol); 157 158 spin_lock_irq(&chip->lock); 159 ucontrol->value.integer.value[0] = 160 chip->errors[kcontrol->private_value]; 161 chip->errors[kcontrol->private_value] = 0; 162 spin_unlock_irq(&chip->lock); 163 return 0; 164 } 165 166 #define snd_ak4117_in_bit_info snd_ctl_boolean_mono_info 167 168 static int snd_ak4117_in_bit_get(struct snd_kcontrol *kcontrol, 169 struct snd_ctl_elem_value *ucontrol) 170 { 171 struct ak4117 *chip = snd_kcontrol_chip(kcontrol); 172 unsigned char reg = kcontrol->private_value & 0xff; 173 unsigned char bit = (kcontrol->private_value >> 8) & 0xff; 174 unsigned char inv = (kcontrol->private_value >> 31) & 1; 175 176 ucontrol->value.integer.value[0] = ((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv; 177 return 0; 178 } 179 180 static int snd_ak4117_rx_info(struct snd_kcontrol *kcontrol, 181 struct snd_ctl_elem_info *uinfo) 182 { 183 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 184 uinfo->count = 1; 185 uinfo->value.integer.min = 0; 186 uinfo->value.integer.max = 1; 187 return 0; 188 } 189 190 static int snd_ak4117_rx_get(struct snd_kcontrol *kcontrol, 191 struct snd_ctl_elem_value *ucontrol) 192 { 193 struct ak4117 *chip = snd_kcontrol_chip(kcontrol); 194 195 ucontrol->value.integer.value[0] = (chip->regmap[AK4117_REG_IO] & AK4117_IPS) ? 1 : 0; 196 return 0; 197 } 198 199 static int snd_ak4117_rx_put(struct snd_kcontrol *kcontrol, 200 struct snd_ctl_elem_value *ucontrol) 201 { 202 struct ak4117 *chip = snd_kcontrol_chip(kcontrol); 203 int change; 204 u8 old_val; 205 206 spin_lock_irq(&chip->lock); 207 old_val = chip->regmap[AK4117_REG_IO]; 208 change = !!ucontrol->value.integer.value[0] != ((old_val & AK4117_IPS) ? 1 : 0); 209 if (change) 210 reg_write(chip, AK4117_REG_IO, (old_val & ~AK4117_IPS) | (ucontrol->value.integer.value[0] ? AK4117_IPS : 0)); 211 spin_unlock_irq(&chip->lock); 212 return change; 213 } 214 215 static int snd_ak4117_rate_info(struct snd_kcontrol *kcontrol, 216 struct snd_ctl_elem_info *uinfo) 217 { 218 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 219 uinfo->count = 1; 220 uinfo->value.integer.min = 0; 221 uinfo->value.integer.max = 192000; 222 return 0; 223 } 224 225 static int snd_ak4117_rate_get(struct snd_kcontrol *kcontrol, 226 struct snd_ctl_elem_value *ucontrol) 227 { 228 struct ak4117 *chip = snd_kcontrol_chip(kcontrol); 229 230 ucontrol->value.integer.value[0] = external_rate(reg_read(chip, AK4117_REG_RCS1)); 231 return 0; 232 } 233 234 static int snd_ak4117_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 235 { 236 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 237 uinfo->count = 1; 238 return 0; 239 } 240 241 static int snd_ak4117_spdif_get(struct snd_kcontrol *kcontrol, 242 struct snd_ctl_elem_value *ucontrol) 243 { 244 struct ak4117 *chip = snd_kcontrol_chip(kcontrol); 245 unsigned i; 246 247 for (i = 0; i < AK4117_REG_RXCSB_SIZE; i++) 248 ucontrol->value.iec958.status[i] = reg_read(chip, AK4117_REG_RXCSB0 + i); 249 return 0; 250 } 251 252 static int snd_ak4117_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 253 { 254 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 255 uinfo->count = 1; 256 return 0; 257 } 258 259 static int snd_ak4117_spdif_mask_get(struct snd_kcontrol *kcontrol, 260 struct snd_ctl_elem_value *ucontrol) 261 { 262 memset(ucontrol->value.iec958.status, 0xff, AK4117_REG_RXCSB_SIZE); 263 return 0; 264 } 265 266 static int snd_ak4117_spdif_pinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 267 { 268 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 269 uinfo->value.integer.min = 0; 270 uinfo->value.integer.max = 0xffff; 271 uinfo->count = 4; 272 return 0; 273 } 274 275 static int snd_ak4117_spdif_pget(struct snd_kcontrol *kcontrol, 276 struct snd_ctl_elem_value *ucontrol) 277 { 278 struct ak4117 *chip = snd_kcontrol_chip(kcontrol); 279 unsigned short tmp; 280 281 ucontrol->value.integer.value[0] = 0xf8f2; 282 ucontrol->value.integer.value[1] = 0x4e1f; 283 tmp = reg_read(chip, AK4117_REG_Pc0) | (reg_read(chip, AK4117_REG_Pc1) << 8); 284 ucontrol->value.integer.value[2] = tmp; 285 tmp = reg_read(chip, AK4117_REG_Pd0) | (reg_read(chip, AK4117_REG_Pd1) << 8); 286 ucontrol->value.integer.value[3] = tmp; 287 return 0; 288 } 289 290 static int snd_ak4117_spdif_qinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 291 { 292 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 293 uinfo->count = AK4117_REG_QSUB_SIZE; 294 return 0; 295 } 296 297 static int snd_ak4117_spdif_qget(struct snd_kcontrol *kcontrol, 298 struct snd_ctl_elem_value *ucontrol) 299 { 300 struct ak4117 *chip = snd_kcontrol_chip(kcontrol); 301 unsigned i; 302 303 for (i = 0; i < AK4117_REG_QSUB_SIZE; i++) 304 ucontrol->value.bytes.data[i] = reg_read(chip, AK4117_REG_QSUB_ADDR + i); 305 return 0; 306 } 307 308 /* Don't forget to change AK4117_CONTROLS define!!! */ 309 static const struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { 310 { 311 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 312 .name = "IEC958 Parity Errors", 313 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 314 .info = snd_ak4117_in_error_info, 315 .get = snd_ak4117_in_error_get, 316 .private_value = AK4117_PARITY_ERRORS, 317 }, 318 { 319 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 320 .name = "IEC958 V-Bit Errors", 321 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 322 .info = snd_ak4117_in_error_info, 323 .get = snd_ak4117_in_error_get, 324 .private_value = AK4117_V_BIT_ERRORS, 325 }, 326 { 327 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 328 .name = "IEC958 C-CRC Errors", 329 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 330 .info = snd_ak4117_in_error_info, 331 .get = snd_ak4117_in_error_get, 332 .private_value = AK4117_CCRC_ERRORS, 333 }, 334 { 335 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 336 .name = "IEC958 Q-CRC Errors", 337 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 338 .info = snd_ak4117_in_error_info, 339 .get = snd_ak4117_in_error_get, 340 .private_value = AK4117_QCRC_ERRORS, 341 }, 342 { 343 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 344 .name = "IEC958 External Rate", 345 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 346 .info = snd_ak4117_rate_info, 347 .get = snd_ak4117_rate_get, 348 }, 349 { 350 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 351 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK), 352 .access = SNDRV_CTL_ELEM_ACCESS_READ, 353 .info = snd_ak4117_spdif_mask_info, 354 .get = snd_ak4117_spdif_mask_get, 355 }, 356 { 357 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 358 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 359 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 360 .info = snd_ak4117_spdif_info, 361 .get = snd_ak4117_spdif_get, 362 }, 363 { 364 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 365 .name = "IEC958 Preamble Capture Default", 366 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 367 .info = snd_ak4117_spdif_pinfo, 368 .get = snd_ak4117_spdif_pget, 369 }, 370 { 371 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 372 .name = "IEC958 Q-subcode Capture Default", 373 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 374 .info = snd_ak4117_spdif_qinfo, 375 .get = snd_ak4117_spdif_qget, 376 }, 377 { 378 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 379 .name = "IEC958 Audio", 380 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 381 .info = snd_ak4117_in_bit_info, 382 .get = snd_ak4117_in_bit_get, 383 .private_value = (1<<31) | (3<<8) | AK4117_REG_RCS0, 384 }, 385 { 386 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 387 .name = "IEC958 Non-PCM Bitstream", 388 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 389 .info = snd_ak4117_in_bit_info, 390 .get = snd_ak4117_in_bit_get, 391 .private_value = (5<<8) | AK4117_REG_RCS1, 392 }, 393 { 394 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 395 .name = "IEC958 DTS Bitstream", 396 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 397 .info = snd_ak4117_in_bit_info, 398 .get = snd_ak4117_in_bit_get, 399 .private_value = (6<<8) | AK4117_REG_RCS1, 400 }, 401 { 402 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 403 .name = "AK4117 Input Select", 404 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, 405 .info = snd_ak4117_rx_info, 406 .get = snd_ak4117_rx_get, 407 .put = snd_ak4117_rx_put, 408 } 409 }; 410 411 int snd_ak4117_build(struct ak4117 *ak4117, struct snd_pcm_substream *cap_substream) 412 { 413 struct snd_kcontrol *kctl; 414 unsigned int idx; 415 int err; 416 417 if (snd_BUG_ON(!cap_substream)) 418 return -EINVAL; 419 ak4117->substream = cap_substream; 420 for (idx = 0; idx < AK4117_CONTROLS; idx++) { 421 kctl = snd_ctl_new1(&snd_ak4117_iec958_controls[idx], ak4117); 422 if (kctl == NULL) 423 return -ENOMEM; 424 kctl->id.device = cap_substream->pcm->device; 425 kctl->id.subdevice = cap_substream->number; 426 err = snd_ctl_add(ak4117->card, kctl); 427 if (err < 0) 428 return err; 429 ak4117->kctls[idx] = kctl; 430 } 431 return 0; 432 } 433 434 int snd_ak4117_external_rate(struct ak4117 *ak4117) 435 { 436 unsigned char rcs1; 437 438 rcs1 = reg_read(ak4117, AK4117_REG_RCS1); 439 return external_rate(rcs1); 440 } 441 442 int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags) 443 { 444 struct snd_pcm_runtime *runtime = ak4117->substream ? ak4117->substream->runtime : NULL; 445 unsigned long _flags; 446 int res = 0; 447 unsigned char rcs0, rcs1, rcs2; 448 unsigned char c0, c1; 449 450 rcs1 = reg_read(ak4117, AK4117_REG_RCS1); 451 if (flags & AK4117_CHECK_NO_STAT) 452 goto __rate; 453 rcs0 = reg_read(ak4117, AK4117_REG_RCS0); 454 rcs2 = reg_read(ak4117, AK4117_REG_RCS2); 455 // printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2); 456 spin_lock_irqsave(&ak4117->lock, _flags); 457 if (rcs0 & AK4117_PAR) 458 ak4117->errors[AK4117_PARITY_ERRORS]++; 459 if (rcs0 & AK4117_V) 460 ak4117->errors[AK4117_V_BIT_ERRORS]++; 461 if (rcs2 & AK4117_CCRC) 462 ak4117->errors[AK4117_CCRC_ERRORS]++; 463 if (rcs2 & AK4117_QCRC) 464 ak4117->errors[AK4117_QCRC_ERRORS]++; 465 c0 = (ak4117->rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)) ^ 466 (rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)); 467 c1 = (ak4117->rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)) ^ 468 (rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)); 469 ak4117->rcs0 = rcs0 & ~(AK4117_QINT | AK4117_CINT | AK4117_STC); 470 ak4117->rcs1 = rcs1; 471 ak4117->rcs2 = rcs2; 472 spin_unlock_irqrestore(&ak4117->lock, _flags); 473 474 if (rcs0 & AK4117_PAR) 475 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[0]->id); 476 if (rcs0 & AK4117_V) 477 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[1]->id); 478 if (rcs2 & AK4117_CCRC) 479 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[2]->id); 480 if (rcs2 & AK4117_QCRC) 481 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[3]->id); 482 483 /* rate change */ 484 if (c1 & 0x0f) 485 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[4]->id); 486 487 if ((c1 & AK4117_PEM) | (c0 & AK4117_CINT)) 488 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[6]->id); 489 if (c0 & AK4117_QINT) 490 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[8]->id); 491 492 if (c0 & AK4117_AUDION) 493 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[9]->id); 494 if (c1 & AK4117_NPCM) 495 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[10]->id); 496 if (c1 & AK4117_DTSCD) 497 snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[11]->id); 498 499 if (ak4117->change_callback && (c0 | c1) != 0) 500 ak4117->change_callback(ak4117, c0, c1); 501 502 __rate: 503 /* compare rate */ 504 res = external_rate(rcs1); 505 if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) { 506 snd_pcm_stream_lock_irqsave(ak4117->substream, _flags); 507 if (snd_pcm_running(ak4117->substream)) { 508 // printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res); 509 snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING); 510 wake_up(&runtime->sleep); 511 res = 1; 512 } 513 snd_pcm_stream_unlock_irqrestore(ak4117->substream, _flags); 514 } 515 return res; 516 } 517 518 static void snd_ak4117_timer(struct timer_list *t) 519 { 520 struct ak4117 *chip = from_timer(chip, t, timer); 521 522 if (chip->init) 523 return; 524 snd_ak4117_check_rate_and_errors(chip, 0); 525 mod_timer(&chip->timer, 1 + jiffies); 526 } 527 528 EXPORT_SYMBOL(snd_ak4117_create); 529 EXPORT_SYMBOL(snd_ak4117_reg_write); 530 EXPORT_SYMBOL(snd_ak4117_reinit); 531 EXPORT_SYMBOL(snd_ak4117_build); 532 EXPORT_SYMBOL(snd_ak4117_external_rate); 533 EXPORT_SYMBOL(snd_ak4117_check_rate_and_errors); 534
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.