1 // SPDX-License-Identifier: GPL-2.0-or-later
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>
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>
17 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
18 MODULE_DESCRIPTION("AK4117 IEC958 (S/PDIF) receiver by Asahi Kasei");
19 MODULE_LICENSE("GPL");
21 #define AK4117_ADDR 0x00 /* fixed address */
23 static void snd_ak4117_timer(struct timer_list
*t
);
25 static void reg_write(struct ak4117
*ak4117
, unsigned char reg
, unsigned char val
)
27 ak4117
->write(ak4117
->private_data
, reg
, val
);
28 if (reg
< sizeof(ak4117
->regmap
))
29 ak4117
->regmap
[reg
] = val
;
32 static inline unsigned char reg_read(struct ak4117
*ak4117
, unsigned char reg
)
34 return ak4117
->read(ak4117
->private_data
, reg
);
38 static void reg_dump(struct ak4117
*ak4117
)
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);
48 static void snd_ak4117_free(struct ak4117
*chip
)
50 del_timer_sync(&chip
->timer
);
54 static int snd_ak4117_dev_free(struct snd_device
*device
)
56 struct ak4117
*chip
= device
->device_data
;
57 snd_ak4117_free(chip
);
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
)
67 static const struct snd_device_ops ops
= {
68 .dev_free
= snd_ak4117_dev_free
,
71 chip
= kzalloc(sizeof(*chip
), GFP_KERNEL
);
74 spin_lock_init(&chip
->lock
);
78 chip
->private_data
= private_data
;
79 timer_setup(&chip
->timer
, snd_ak4117_timer
, 0);
81 for (reg
= 0; reg
< 5; reg
++)
82 chip
->regmap
[reg
] = pgm
[reg
];
83 snd_ak4117_reinit(chip
);
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
);
89 if ((err
= snd_device_new(card
, SNDRV_DEV_CODEC
, chip
, &ops
)) < 0)
97 snd_ak4117_free(chip
);
101 void snd_ak4117_reg_write(struct ak4117
*chip
, unsigned char reg
, unsigned char mask
, unsigned char val
)
105 reg_write(chip
, reg
, (chip
->regmap
[reg
] & ~mask
) | val
);
108 void snd_ak4117_reinit(struct ak4117
*chip
)
110 unsigned char old
= chip
->regmap
[AK4117_REG_PWRDN
], reg
;
112 del_timer(&chip
->timer
);
114 /* bring the chip to reset state and powerdown state */
115 reg_write(chip
, AK4117_REG_PWRDN
, 0);
117 /* release reset, but leave powerdown */
118 reg_write(chip
, AK4117_REG_PWRDN
, (old
| AK4117_RST
) & ~AK4117_PWN
);
120 for (reg
= 1; reg
< 5; reg
++)
121 reg_write(chip
, reg
, chip
->regmap
[reg
]);
122 /* release powerdown, everything is initialized now */
123 reg_write(chip
, AK4117_REG_PWRDN
, old
| AK4117_RST
| AK4117_PWN
);
125 mod_timer(&chip
->timer
, 1 + jiffies
);
128 static unsigned int external_rate(unsigned char rcs1
)
130 switch (rcs1
& (AK4117_FS0
|AK4117_FS1
|AK4117_FS2
|AK4117_FS3
)) {
131 case AK4117_FS_32000HZ
: return 32000;
132 case AK4117_FS_44100HZ
: return 44100;
133 case AK4117_FS_48000HZ
: return 48000;
134 case AK4117_FS_88200HZ
: return 88200;
135 case AK4117_FS_96000HZ
: return 96000;
136 case AK4117_FS_176400HZ
: return 176400;
137 case AK4117_FS_192000HZ
: return 192000;
142 static int snd_ak4117_in_error_info(struct snd_kcontrol
*kcontrol
,
143 struct snd_ctl_elem_info
*uinfo
)
145 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
147 uinfo
->value
.integer
.min
= 0;
148 uinfo
->value
.integer
.max
= LONG_MAX
;
152 static int snd_ak4117_in_error_get(struct snd_kcontrol
*kcontrol
,
153 struct snd_ctl_elem_value
*ucontrol
)
155 struct ak4117
*chip
= snd_kcontrol_chip(kcontrol
);
157 spin_lock_irq(&chip
->lock
);
158 ucontrol
->value
.integer
.value
[0] =
159 chip
->errors
[kcontrol
->private_value
];
160 chip
->errors
[kcontrol
->private_value
] = 0;
161 spin_unlock_irq(&chip
->lock
);
165 #define snd_ak4117_in_bit_info snd_ctl_boolean_mono_info
167 static int snd_ak4117_in_bit_get(struct snd_kcontrol
*kcontrol
,
168 struct snd_ctl_elem_value
*ucontrol
)
170 struct ak4117
*chip
= snd_kcontrol_chip(kcontrol
);
171 unsigned char reg
= kcontrol
->private_value
& 0xff;
172 unsigned char bit
= (kcontrol
->private_value
>> 8) & 0xff;
173 unsigned char inv
= (kcontrol
->private_value
>> 31) & 1;
175 ucontrol
->value
.integer
.value
[0] = ((reg_read(chip
, reg
) & (1 << bit
)) ? 1 : 0) ^ inv
;
179 static int snd_ak4117_rx_info(struct snd_kcontrol
*kcontrol
,
180 struct snd_ctl_elem_info
*uinfo
)
182 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
184 uinfo
->value
.integer
.min
= 0;
185 uinfo
->value
.integer
.max
= 1;
189 static int snd_ak4117_rx_get(struct snd_kcontrol
*kcontrol
,
190 struct snd_ctl_elem_value
*ucontrol
)
192 struct ak4117
*chip
= snd_kcontrol_chip(kcontrol
);
194 ucontrol
->value
.integer
.value
[0] = (chip
->regmap
[AK4117_REG_IO
] & AK4117_IPS
) ? 1 : 0;
198 static int snd_ak4117_rx_put(struct snd_kcontrol
*kcontrol
,
199 struct snd_ctl_elem_value
*ucontrol
)
201 struct ak4117
*chip
= snd_kcontrol_chip(kcontrol
);
205 spin_lock_irq(&chip
->lock
);
206 old_val
= chip
->regmap
[AK4117_REG_IO
];
207 change
= !!ucontrol
->value
.integer
.value
[0] != ((old_val
& AK4117_IPS
) ? 1 : 0);
209 reg_write(chip
, AK4117_REG_IO
, (old_val
& ~AK4117_IPS
) | (ucontrol
->value
.integer
.value
[0] ? AK4117_IPS
: 0));
210 spin_unlock_irq(&chip
->lock
);
214 static int snd_ak4117_rate_info(struct snd_kcontrol
*kcontrol
,
215 struct snd_ctl_elem_info
*uinfo
)
217 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
219 uinfo
->value
.integer
.min
= 0;
220 uinfo
->value
.integer
.max
= 192000;
224 static int snd_ak4117_rate_get(struct snd_kcontrol
*kcontrol
,
225 struct snd_ctl_elem_value
*ucontrol
)
227 struct ak4117
*chip
= snd_kcontrol_chip(kcontrol
);
229 ucontrol
->value
.integer
.value
[0] = external_rate(reg_read(chip
, AK4117_REG_RCS1
));
233 static int snd_ak4117_spdif_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
235 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
240 static int snd_ak4117_spdif_get(struct snd_kcontrol
*kcontrol
,
241 struct snd_ctl_elem_value
*ucontrol
)
243 struct ak4117
*chip
= snd_kcontrol_chip(kcontrol
);
246 for (i
= 0; i
< AK4117_REG_RXCSB_SIZE
; i
++)
247 ucontrol
->value
.iec958
.status
[i
] = reg_read(chip
, AK4117_REG_RXCSB0
+ i
);
251 static int snd_ak4117_spdif_mask_info(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
253 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
258 static int snd_ak4117_spdif_mask_get(struct snd_kcontrol
*kcontrol
,
259 struct snd_ctl_elem_value
*ucontrol
)
261 memset(ucontrol
->value
.iec958
.status
, 0xff, AK4117_REG_RXCSB_SIZE
);
265 static int snd_ak4117_spdif_pinfo(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
267 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
268 uinfo
->value
.integer
.min
= 0;
269 uinfo
->value
.integer
.max
= 0xffff;
274 static int snd_ak4117_spdif_pget(struct snd_kcontrol
*kcontrol
,
275 struct snd_ctl_elem_value
*ucontrol
)
277 struct ak4117
*chip
= snd_kcontrol_chip(kcontrol
);
280 ucontrol
->value
.integer
.value
[0] = 0xf8f2;
281 ucontrol
->value
.integer
.value
[1] = 0x4e1f;
282 tmp
= reg_read(chip
, AK4117_REG_Pc0
) | (reg_read(chip
, AK4117_REG_Pc1
) << 8);
283 ucontrol
->value
.integer
.value
[2] = tmp
;
284 tmp
= reg_read(chip
, AK4117_REG_Pd0
) | (reg_read(chip
, AK4117_REG_Pd1
) << 8);
285 ucontrol
->value
.integer
.value
[3] = tmp
;
289 static int snd_ak4117_spdif_qinfo(struct snd_kcontrol
*kcontrol
, struct snd_ctl_elem_info
*uinfo
)
291 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BYTES
;
292 uinfo
->count
= AK4117_REG_QSUB_SIZE
;
296 static int snd_ak4117_spdif_qget(struct snd_kcontrol
*kcontrol
,
297 struct snd_ctl_elem_value
*ucontrol
)
299 struct ak4117
*chip
= snd_kcontrol_chip(kcontrol
);
302 for (i
= 0; i
< AK4117_REG_QSUB_SIZE
; i
++)
303 ucontrol
->value
.bytes
.data
[i
] = reg_read(chip
, AK4117_REG_QSUB_ADDR
+ i
);
307 /* Don't forget to change AK4117_CONTROLS define!!! */
308 static const struct snd_kcontrol_new snd_ak4117_iec958_controls
[] = {
310 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
311 .name
= "IEC958 Parity Errors",
312 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
313 .info
= snd_ak4117_in_error_info
,
314 .get
= snd_ak4117_in_error_get
,
315 .private_value
= AK4117_PARITY_ERRORS
,
318 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
319 .name
= "IEC958 V-Bit Errors",
320 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
321 .info
= snd_ak4117_in_error_info
,
322 .get
= snd_ak4117_in_error_get
,
323 .private_value
= AK4117_V_BIT_ERRORS
,
326 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
327 .name
= "IEC958 C-CRC Errors",
328 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
329 .info
= snd_ak4117_in_error_info
,
330 .get
= snd_ak4117_in_error_get
,
331 .private_value
= AK4117_CCRC_ERRORS
,
334 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
335 .name
= "IEC958 Q-CRC Errors",
336 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
337 .info
= snd_ak4117_in_error_info
,
338 .get
= snd_ak4117_in_error_get
,
339 .private_value
= AK4117_QCRC_ERRORS
,
342 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
343 .name
= "IEC958 External Rate",
344 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
345 .info
= snd_ak4117_rate_info
,
346 .get
= snd_ak4117_rate_get
,
349 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
350 .name
= SNDRV_CTL_NAME_IEC958("",CAPTURE
,MASK
),
351 .access
= SNDRV_CTL_ELEM_ACCESS_READ
,
352 .info
= snd_ak4117_spdif_mask_info
,
353 .get
= snd_ak4117_spdif_mask_get
,
356 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
357 .name
= SNDRV_CTL_NAME_IEC958("",CAPTURE
,DEFAULT
),
358 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
359 .info
= snd_ak4117_spdif_info
,
360 .get
= snd_ak4117_spdif_get
,
363 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
364 .name
= "IEC958 Preamble Capture Default",
365 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
366 .info
= snd_ak4117_spdif_pinfo
,
367 .get
= snd_ak4117_spdif_pget
,
370 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
371 .name
= "IEC958 Q-subcode Capture Default",
372 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
373 .info
= snd_ak4117_spdif_qinfo
,
374 .get
= snd_ak4117_spdif_qget
,
377 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
378 .name
= "IEC958 Audio",
379 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
380 .info
= snd_ak4117_in_bit_info
,
381 .get
= snd_ak4117_in_bit_get
,
382 .private_value
= (1<<31) | (3<<8) | AK4117_REG_RCS0
,
385 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
386 .name
= "IEC958 Non-PCM Bitstream",
387 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
388 .info
= snd_ak4117_in_bit_info
,
389 .get
= snd_ak4117_in_bit_get
,
390 .private_value
= (5<<8) | AK4117_REG_RCS1
,
393 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
394 .name
= "IEC958 DTS Bitstream",
395 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
396 .info
= snd_ak4117_in_bit_info
,
397 .get
= snd_ak4117_in_bit_get
,
398 .private_value
= (6<<8) | AK4117_REG_RCS1
,
401 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
402 .name
= "AK4117 Input Select",
403 .access
= SNDRV_CTL_ELEM_ACCESS_READ
| SNDRV_CTL_ELEM_ACCESS_WRITE
,
404 .info
= snd_ak4117_rx_info
,
405 .get
= snd_ak4117_rx_get
,
406 .put
= snd_ak4117_rx_put
,
410 int snd_ak4117_build(struct ak4117
*ak4117
, struct snd_pcm_substream
*cap_substream
)
412 struct snd_kcontrol
*kctl
;
416 if (snd_BUG_ON(!cap_substream
))
418 ak4117
->substream
= cap_substream
;
419 for (idx
= 0; idx
< AK4117_CONTROLS
; idx
++) {
420 kctl
= snd_ctl_new1(&snd_ak4117_iec958_controls
[idx
], ak4117
);
423 kctl
->id
.device
= cap_substream
->pcm
->device
;
424 kctl
->id
.subdevice
= cap_substream
->number
;
425 err
= snd_ctl_add(ak4117
->card
, kctl
);
428 ak4117
->kctls
[idx
] = kctl
;
433 int snd_ak4117_external_rate(struct ak4117
*ak4117
)
437 rcs1
= reg_read(ak4117
, AK4117_REG_RCS1
);
438 return external_rate(rcs1
);
441 int snd_ak4117_check_rate_and_errors(struct ak4117
*ak4117
, unsigned int flags
)
443 struct snd_pcm_runtime
*runtime
= ak4117
->substream
? ak4117
->substream
->runtime
: NULL
;
444 unsigned long _flags
;
446 unsigned char rcs0
, rcs1
, rcs2
;
447 unsigned char c0
, c1
;
449 rcs1
= reg_read(ak4117
, AK4117_REG_RCS1
);
450 if (flags
& AK4117_CHECK_NO_STAT
)
452 rcs0
= reg_read(ak4117
, AK4117_REG_RCS0
);
453 rcs2
= reg_read(ak4117
, AK4117_REG_RCS2
);
454 // printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
455 spin_lock_irqsave(&ak4117
->lock
, _flags
);
456 if (rcs0
& AK4117_PAR
)
457 ak4117
->errors
[AK4117_PARITY_ERRORS
]++;
459 ak4117
->errors
[AK4117_V_BIT_ERRORS
]++;
460 if (rcs2
& AK4117_CCRC
)
461 ak4117
->errors
[AK4117_CCRC_ERRORS
]++;
462 if (rcs2
& AK4117_QCRC
)
463 ak4117
->errors
[AK4117_QCRC_ERRORS
]++;
464 c0
= (ak4117
->rcs0
& (AK4117_QINT
| AK4117_CINT
| AK4117_STC
| AK4117_AUDION
| AK4117_AUTO
| AK4117_UNLCK
)) ^
465 (rcs0
& (AK4117_QINT
| AK4117_CINT
| AK4117_STC
| AK4117_AUDION
| AK4117_AUTO
| AK4117_UNLCK
));
466 c1
= (ak4117
->rcs1
& (AK4117_DTSCD
| AK4117_NPCM
| AK4117_PEM
| 0x0f)) ^
467 (rcs1
& (AK4117_DTSCD
| AK4117_NPCM
| AK4117_PEM
| 0x0f));
468 ak4117
->rcs0
= rcs0
& ~(AK4117_QINT
| AK4117_CINT
| AK4117_STC
);
471 spin_unlock_irqrestore(&ak4117
->lock
, _flags
);
473 if (rcs0
& AK4117_PAR
)
474 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[0]->id
);
476 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[1]->id
);
477 if (rcs2
& AK4117_CCRC
)
478 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[2]->id
);
479 if (rcs2
& AK4117_QCRC
)
480 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[3]->id
);
484 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[4]->id
);
486 if ((c1
& AK4117_PEM
) | (c0
& AK4117_CINT
))
487 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[6]->id
);
488 if (c0
& AK4117_QINT
)
489 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[8]->id
);
491 if (c0
& AK4117_AUDION
)
492 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[9]->id
);
493 if (c1
& AK4117_NPCM
)
494 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[10]->id
);
495 if (c1
& AK4117_DTSCD
)
496 snd_ctl_notify(ak4117
->card
, SNDRV_CTL_EVENT_MASK_VALUE
, &ak4117
->kctls
[11]->id
);
498 if (ak4117
->change_callback
&& (c0
| c1
) != 0)
499 ak4117
->change_callback(ak4117
, c0
, c1
);
503 res
= external_rate(rcs1
);
504 if (!(flags
& AK4117_CHECK_NO_RATE
) && runtime
&& runtime
->rate
!= res
) {
505 snd_pcm_stream_lock_irqsave(ak4117
->substream
, _flags
);
506 if (snd_pcm_running(ak4117
->substream
)) {
507 // printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
508 snd_pcm_stop(ak4117
->substream
, SNDRV_PCM_STATE_DRAINING
);
509 wake_up(&runtime
->sleep
);
512 snd_pcm_stream_unlock_irqrestore(ak4117
->substream
, _flags
);
517 static void snd_ak4117_timer(struct timer_list
*t
)
519 struct ak4117
*chip
= from_timer(chip
, t
, timer
);
523 snd_ak4117_check_rate_and_errors(chip
, 0);
524 mod_timer(&chip
->timer
, 1 + jiffies
);
527 EXPORT_SYMBOL(snd_ak4117_create
);
528 EXPORT_SYMBOL(snd_ak4117_reg_write
);
529 EXPORT_SYMBOL(snd_ak4117_reinit
);
530 EXPORT_SYMBOL(snd_ak4117_build
);
531 EXPORT_SYMBOL(snd_ak4117_external_rate
);
532 EXPORT_SYMBOL(snd_ak4117_check_rate_and_errors
);