162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci#ifndef __SOUND_AK4114_H 362306a36Sopenharmony_ci#define __SOUND_AK4114_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * Routines for Asahi Kasei AK4114 762306a36Sopenharmony_ci * Copyright (c) by Jaroslav Kysela <perex@perex.cz>, 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/* AK4114 registers */ 1162306a36Sopenharmony_ci#define AK4114_REG_PWRDN 0x00 /* power down */ 1262306a36Sopenharmony_ci#define AK4114_REG_FORMAT 0x01 /* format control */ 1362306a36Sopenharmony_ci#define AK4114_REG_IO0 0x02 /* input/output control */ 1462306a36Sopenharmony_ci#define AK4114_REG_IO1 0x03 /* input/output control */ 1562306a36Sopenharmony_ci#define AK4114_REG_INT0_MASK 0x04 /* interrupt0 mask */ 1662306a36Sopenharmony_ci#define AK4114_REG_INT1_MASK 0x05 /* interrupt1 mask */ 1762306a36Sopenharmony_ci#define AK4114_REG_RCS0 0x06 /* receiver status 0 */ 1862306a36Sopenharmony_ci#define AK4114_REG_RCS1 0x07 /* receiver status 1 */ 1962306a36Sopenharmony_ci#define AK4114_REG_RXCSB0 0x08 /* RX channel status byte 0 */ 2062306a36Sopenharmony_ci#define AK4114_REG_RXCSB1 0x09 /* RX channel status byte 1 */ 2162306a36Sopenharmony_ci#define AK4114_REG_RXCSB2 0x0a /* RX channel status byte 2 */ 2262306a36Sopenharmony_ci#define AK4114_REG_RXCSB3 0x0b /* RX channel status byte 3 */ 2362306a36Sopenharmony_ci#define AK4114_REG_RXCSB4 0x0c /* RX channel status byte 4 */ 2462306a36Sopenharmony_ci#define AK4114_REG_TXCSB0 0x0d /* TX channel status byte 0 */ 2562306a36Sopenharmony_ci#define AK4114_REG_TXCSB1 0x0e /* TX channel status byte 1 */ 2662306a36Sopenharmony_ci#define AK4114_REG_TXCSB2 0x0f /* TX channel status byte 2 */ 2762306a36Sopenharmony_ci#define AK4114_REG_TXCSB3 0x10 /* TX channel status byte 3 */ 2862306a36Sopenharmony_ci#define AK4114_REG_TXCSB4 0x11 /* TX channel status byte 4 */ 2962306a36Sopenharmony_ci#define AK4114_REG_Pc0 0x12 /* burst preamble Pc byte 0 */ 3062306a36Sopenharmony_ci#define AK4114_REG_Pc1 0x13 /* burst preamble Pc byte 1 */ 3162306a36Sopenharmony_ci#define AK4114_REG_Pd0 0x14 /* burst preamble Pd byte 0 */ 3262306a36Sopenharmony_ci#define AK4114_REG_Pd1 0x15 /* burst preamble Pd byte 1 */ 3362306a36Sopenharmony_ci#define AK4114_REG_QSUB_ADDR 0x16 /* Q-subcode address + control */ 3462306a36Sopenharmony_ci#define AK4114_REG_QSUB_TRACK 0x17 /* Q-subcode track */ 3562306a36Sopenharmony_ci#define AK4114_REG_QSUB_INDEX 0x18 /* Q-subcode index */ 3662306a36Sopenharmony_ci#define AK4114_REG_QSUB_MINUTE 0x19 /* Q-subcode minute */ 3762306a36Sopenharmony_ci#define AK4114_REG_QSUB_SECOND 0x1a /* Q-subcode second */ 3862306a36Sopenharmony_ci#define AK4114_REG_QSUB_FRAME 0x1b /* Q-subcode frame */ 3962306a36Sopenharmony_ci#define AK4114_REG_QSUB_ZERO 0x1c /* Q-subcode zero */ 4062306a36Sopenharmony_ci#define AK4114_REG_QSUB_ABSMIN 0x1d /* Q-subcode absolute minute */ 4162306a36Sopenharmony_ci#define AK4114_REG_QSUB_ABSSEC 0x1e /* Q-subcode absolute second */ 4262306a36Sopenharmony_ci#define AK4114_REG_QSUB_ABSFRM 0x1f /* Q-subcode absolute frame */ 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* sizes */ 4562306a36Sopenharmony_ci#define AK4114_REG_RXCSB_SIZE ((AK4114_REG_RXCSB4-AK4114_REG_RXCSB0)+1) 4662306a36Sopenharmony_ci#define AK4114_REG_TXCSB_SIZE ((AK4114_REG_TXCSB4-AK4114_REG_TXCSB0)+1) 4762306a36Sopenharmony_ci#define AK4114_REG_QSUB_SIZE ((AK4114_REG_QSUB_ABSFRM-AK4114_REG_QSUB_ADDR)+1) 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/* AK4117_REG_PWRDN bits */ 5062306a36Sopenharmony_ci#define AK4114_CS12 (1<<7) /* Channel Status Select */ 5162306a36Sopenharmony_ci#define AK4114_BCU (1<<6) /* Block Start & C/U Output Mode */ 5262306a36Sopenharmony_ci#define AK4114_CM1 (1<<5) /* Master Clock Operation Select */ 5362306a36Sopenharmony_ci#define AK4114_CM0 (1<<4) /* Master Clock Operation Select */ 5462306a36Sopenharmony_ci#define AK4114_OCKS1 (1<<3) /* Master Clock Frequency Select */ 5562306a36Sopenharmony_ci#define AK4114_OCKS0 (1<<2) /* Master Clock Frequency Select */ 5662306a36Sopenharmony_ci#define AK4114_PWN (1<<1) /* 0 = power down, 1 = normal operation */ 5762306a36Sopenharmony_ci#define AK4114_RST (1<<0) /* 0 = reset & initialize (except this register), 1 = normal operation */ 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* AK4114_REQ_FORMAT bits */ 6062306a36Sopenharmony_ci#define AK4114_MONO (1<<7) /* Double Sampling Frequency Mode: 0 = stereo, 1 = mono */ 6162306a36Sopenharmony_ci#define AK4114_DIF2 (1<<6) /* Audio Data Control */ 6262306a36Sopenharmony_ci#define AK4114_DIF1 (1<<5) /* Audio Data Control */ 6362306a36Sopenharmony_ci#define AK4114_DIF0 (1<<4) /* Audio Data Control */ 6462306a36Sopenharmony_ci#define AK4114_DIF_16R (0) /* STDO: 16-bit, right justified */ 6562306a36Sopenharmony_ci#define AK4114_DIF_18R (AK4114_DIF0) /* STDO: 18-bit, right justified */ 6662306a36Sopenharmony_ci#define AK4114_DIF_20R (AK4114_DIF1) /* STDO: 20-bit, right justified */ 6762306a36Sopenharmony_ci#define AK4114_DIF_24R (AK4114_DIF1|AK4114_DIF0) /* STDO: 24-bit, right justified */ 6862306a36Sopenharmony_ci#define AK4114_DIF_24L (AK4114_DIF2) /* STDO: 24-bit, left justified */ 6962306a36Sopenharmony_ci#define AK4114_DIF_24I2S (AK4114_DIF2|AK4114_DIF0) /* STDO: I2S */ 7062306a36Sopenharmony_ci#define AK4114_DIF_I24L (AK4114_DIF2|AK4114_DIF1) /* STDO: 24-bit, left justified; LRCLK, BICK = Input */ 7162306a36Sopenharmony_ci#define AK4114_DIF_I24I2S (AK4114_DIF2|AK4114_DIF1|AK4114_DIF0) /* STDO: I2S; LRCLK, BICK = Input */ 7262306a36Sopenharmony_ci#define AK4114_DEAU (1<<3) /* Deemphasis Autodetect Enable (1 = enable) */ 7362306a36Sopenharmony_ci#define AK4114_DEM1 (1<<2) /* 32kHz-48kHz Deemphasis Control */ 7462306a36Sopenharmony_ci#define AK4114_DEM0 (1<<1) /* 32kHz-48kHz Deemphasis Control */ 7562306a36Sopenharmony_ci#define AK4114_DEM_44KHZ (0) 7662306a36Sopenharmony_ci#define AK4114_DEM_48KHZ (AK4114_DEM1) 7762306a36Sopenharmony_ci#define AK4114_DEM_32KHZ (AK4114_DEM0|AK4114_DEM1) 7862306a36Sopenharmony_ci#define AK4114_DEM_96KHZ (AK4114_DEM1) /* DFS must be set */ 7962306a36Sopenharmony_ci#define AK4114_DFS (1<<0) /* 96kHz Deemphasis Control */ 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci/* AK4114_REG_IO0 */ 8262306a36Sopenharmony_ci#define AK4114_TX1E (1<<7) /* TX1 Output Enable (1 = enable) */ 8362306a36Sopenharmony_ci#define AK4114_OPS12 (1<<6) /* Output Data Selector for TX1 pin */ 8462306a36Sopenharmony_ci#define AK4114_OPS11 (1<<5) /* Output Data Selector for TX1 pin */ 8562306a36Sopenharmony_ci#define AK4114_OPS10 (1<<4) /* Output Data Selector for TX1 pin */ 8662306a36Sopenharmony_ci#define AK4114_TX0E (1<<3) /* TX0 Output Enable (1 = enable) */ 8762306a36Sopenharmony_ci#define AK4114_OPS02 (1<<2) /* Output Data Selector for TX0 pin */ 8862306a36Sopenharmony_ci#define AK4114_OPS01 (1<<1) /* Output Data Selector for TX0 pin */ 8962306a36Sopenharmony_ci#define AK4114_OPS00 (1<<0) /* Output Data Selector for TX0 pin */ 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci/* AK4114_REG_IO1 */ 9262306a36Sopenharmony_ci#define AK4114_EFH1 (1<<7) /* Interrupt 0 pin Hold */ 9362306a36Sopenharmony_ci#define AK4114_EFH0 (1<<6) /* Interrupt 0 pin Hold */ 9462306a36Sopenharmony_ci#define AK4114_EFH_512 (0) 9562306a36Sopenharmony_ci#define AK4114_EFH_1024 (AK4114_EFH0) 9662306a36Sopenharmony_ci#define AK4114_EFH_2048 (AK4114_EFH1) 9762306a36Sopenharmony_ci#define AK4114_EFH_4096 (AK4114_EFH1|AK4114_EFH0) 9862306a36Sopenharmony_ci#define AK4114_UDIT (1<<5) /* U-bit Control for DIT (0 = fixed '0', 1 = recovered) */ 9962306a36Sopenharmony_ci#define AK4114_TLR (1<<4) /* Double Sampling Frequency Select for DIT (0 = L channel, 1 = R channel) */ 10062306a36Sopenharmony_ci#define AK4114_DIT (1<<3) /* TX1 out: 0 = Through Data (RX data), 1 = Transmit Data (DAUX data) */ 10162306a36Sopenharmony_ci#define AK4114_IPS2 (1<<2) /* Input Recovery Data Select */ 10262306a36Sopenharmony_ci#define AK4114_IPS1 (1<<1) /* Input Recovery Data Select */ 10362306a36Sopenharmony_ci#define AK4114_IPS0 (1<<0) /* Input Recovery Data Select */ 10462306a36Sopenharmony_ci#define AK4114_IPS(x) ((x)&7) 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/* AK4114_REG_INT0_MASK && AK4114_REG_INT1_MASK*/ 10762306a36Sopenharmony_ci#define AK4117_MQI (1<<7) /* mask enable for QINT bit */ 10862306a36Sopenharmony_ci#define AK4117_MAT (1<<6) /* mask enable for AUTO bit */ 10962306a36Sopenharmony_ci#define AK4117_MCI (1<<5) /* mask enable for CINT bit */ 11062306a36Sopenharmony_ci#define AK4117_MUL (1<<4) /* mask enable for UNLOCK bit */ 11162306a36Sopenharmony_ci#define AK4117_MDTS (1<<3) /* mask enable for DTSCD bit */ 11262306a36Sopenharmony_ci#define AK4117_MPE (1<<2) /* mask enable for PEM bit */ 11362306a36Sopenharmony_ci#define AK4117_MAN (1<<1) /* mask enable for AUDN bit */ 11462306a36Sopenharmony_ci#define AK4117_MPR (1<<0) /* mask enable for PAR bit */ 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci/* AK4114_REG_RCS0 */ 11762306a36Sopenharmony_ci#define AK4114_QINT (1<<7) /* Q-subcode buffer interrupt, 0 = no change, 1 = changed */ 11862306a36Sopenharmony_ci#define AK4114_AUTO (1<<6) /* Non-PCM or DTS stream auto detection, 0 = no detect, 1 = detect */ 11962306a36Sopenharmony_ci#define AK4114_CINT (1<<5) /* channel status buffer interrupt, 0 = no change, 1 = change */ 12062306a36Sopenharmony_ci#define AK4114_UNLCK (1<<4) /* PLL lock status, 0 = lock, 1 = unlock */ 12162306a36Sopenharmony_ci#define AK4114_DTSCD (1<<3) /* DTS-CD Detect, 0 = No detect, 1 = Detect */ 12262306a36Sopenharmony_ci#define AK4114_PEM (1<<2) /* Pre-emphasis Detect, 0 = OFF, 1 = ON */ 12362306a36Sopenharmony_ci#define AK4114_AUDION (1<<1) /* audio bit output, 0 = audio, 1 = non-audio */ 12462306a36Sopenharmony_ci#define AK4114_PAR (1<<0) /* parity error or biphase error status, 0 = no error, 1 = error */ 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci/* AK4114_REG_RCS1 */ 12762306a36Sopenharmony_ci#define AK4114_FS3 (1<<7) /* sampling frequency detection */ 12862306a36Sopenharmony_ci#define AK4114_FS2 (1<<6) 12962306a36Sopenharmony_ci#define AK4114_FS1 (1<<5) 13062306a36Sopenharmony_ci#define AK4114_FS0 (1<<4) 13162306a36Sopenharmony_ci#define AK4114_FS_44100HZ (0) 13262306a36Sopenharmony_ci#define AK4114_FS_48000HZ (AK4114_FS1) 13362306a36Sopenharmony_ci#define AK4114_FS_32000HZ (AK4114_FS1|AK4114_FS0) 13462306a36Sopenharmony_ci#define AK4114_FS_88200HZ (AK4114_FS3) 13562306a36Sopenharmony_ci#define AK4114_FS_96000HZ (AK4114_FS3|AK4114_FS1) 13662306a36Sopenharmony_ci#define AK4114_FS_176400HZ (AK4114_FS3|AK4114_FS2) 13762306a36Sopenharmony_ci#define AK4114_FS_192000HZ (AK4114_FS3|AK4114_FS2|AK4114_FS1) 13862306a36Sopenharmony_ci#define AK4114_V (1<<3) /* Validity of Channel Status, 0 = Valid, 1 = Invalid */ 13962306a36Sopenharmony_ci#define AK4114_QCRC (1<<1) /* CRC for Q-subcode, 0 = no error, 1 = error */ 14062306a36Sopenharmony_ci#define AK4114_CCRC (1<<0) /* CRC for channel status, 0 = no error, 1 = error */ 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/* flags for snd_ak4114_check_rate_and_errors() */ 14362306a36Sopenharmony_ci#define AK4114_CHECK_NO_STAT (1<<0) /* no statistics */ 14462306a36Sopenharmony_ci#define AK4114_CHECK_NO_RATE (1<<1) /* no rate check */ 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci#define AK4114_CONTROLS 15 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_citypedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data); 14962306a36Sopenharmony_citypedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cienum { 15262306a36Sopenharmony_ci AK4114_PARITY_ERRORS, 15362306a36Sopenharmony_ci AK4114_V_BIT_ERRORS, 15462306a36Sopenharmony_ci AK4114_QCRC_ERRORS, 15562306a36Sopenharmony_ci AK4114_CCRC_ERRORS, 15662306a36Sopenharmony_ci AK4114_NUM_ERRORS 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cistruct ak4114 { 16062306a36Sopenharmony_ci struct snd_card *card; 16162306a36Sopenharmony_ci ak4114_write_t * write; 16262306a36Sopenharmony_ci ak4114_read_t * read; 16362306a36Sopenharmony_ci void * private_data; 16462306a36Sopenharmony_ci atomic_t wq_processing; 16562306a36Sopenharmony_ci struct mutex reinit_mutex; 16662306a36Sopenharmony_ci spinlock_t lock; 16762306a36Sopenharmony_ci unsigned char regmap[6]; 16862306a36Sopenharmony_ci unsigned char txcsb[5]; 16962306a36Sopenharmony_ci struct snd_kcontrol *kctls[AK4114_CONTROLS]; 17062306a36Sopenharmony_ci struct snd_pcm_substream *playback_substream; 17162306a36Sopenharmony_ci struct snd_pcm_substream *capture_substream; 17262306a36Sopenharmony_ci unsigned long errors[AK4114_NUM_ERRORS]; 17362306a36Sopenharmony_ci unsigned char rcs0; 17462306a36Sopenharmony_ci unsigned char rcs1; 17562306a36Sopenharmony_ci struct delayed_work work; 17662306a36Sopenharmony_ci unsigned int check_flags; 17762306a36Sopenharmony_ci void *change_callback_private; 17862306a36Sopenharmony_ci void (*change_callback)(struct ak4114 *ak4114, unsigned char c0, unsigned char c1); 17962306a36Sopenharmony_ci}; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ciint snd_ak4114_create(struct snd_card *card, 18262306a36Sopenharmony_ci ak4114_read_t *read, ak4114_write_t *write, 18362306a36Sopenharmony_ci const unsigned char pgm[6], const unsigned char txcsb[5], 18462306a36Sopenharmony_ci void *private_data, struct ak4114 **r_ak4114); 18562306a36Sopenharmony_civoid snd_ak4114_reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char mask, unsigned char val); 18662306a36Sopenharmony_civoid snd_ak4114_reinit(struct ak4114 *ak4114); 18762306a36Sopenharmony_ciint snd_ak4114_build(struct ak4114 *ak4114, 18862306a36Sopenharmony_ci struct snd_pcm_substream *playback_substream, 18962306a36Sopenharmony_ci struct snd_pcm_substream *capture_substream); 19062306a36Sopenharmony_ciint snd_ak4114_external_rate(struct ak4114 *ak4114); 19162306a36Sopenharmony_ciint snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci#ifdef CONFIG_PM 19462306a36Sopenharmony_civoid snd_ak4114_suspend(struct ak4114 *chip); 19562306a36Sopenharmony_civoid snd_ak4114_resume(struct ak4114 *chip); 19662306a36Sopenharmony_ci#else 19762306a36Sopenharmony_cistatic inline void snd_ak4114_suspend(struct ak4114 *chip) {} 19862306a36Sopenharmony_cistatic inline void snd_ak4114_resume(struct ak4114 *chip) {} 19962306a36Sopenharmony_ci#endif 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci#endif /* __SOUND_AK4114_H */ 20262306a36Sopenharmony_ci 203