/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef __SOUND_AK4113_H
#define __SOUND_AK4113_H





#define AK4113_REG_PWRDN	0x00

#define AK4113_REG_FORMAT	0x01

#define AK4113_REG_IO0		0x02

#define AK4113_REG_IO1		0x03

#define AK4113_REG_INT0_MASK	0x04

#define AK4113_REG_INT1_MASK	0x05

#define AK4113_REG_DATDTS	0x06

#define AK4113_REG_RCS0		0x07

#define AK4113_REG_RCS1		0x08

#define AK4113_REG_RCS2		0x09

#define AK4113_REG_RXCSB0	0x0a

#define AK4113_REG_RXCSB1	0x0b

#define AK4113_REG_RXCSB2	0x0c

#define AK4113_REG_RXCSB3	0x0d

#define AK4113_REG_RXCSB4	0x0e

#define AK4113_REG_Pc0		0x0f

#define AK4113_REG_Pc1		0x10

#define AK4113_REG_Pd0		0x11

#define AK4113_REG_Pd1		0x12

#define AK4113_REG_QSUB_ADDR	0x13

#define AK4113_REG_QSUB_TRACK	0x14

#define AK4113_REG_QSUB_INDEX	0x15

#define AK4113_REG_QSUB_MINUTE	0x16

#define AK4113_REG_QSUB_SECOND	0x17

#define AK4113_REG_QSUB_FRAME	0x18

#define AK4113_REG_QSUB_ZERO	0x19

#define AK4113_REG_QSUB_ABSMIN	0x1a

#define AK4113_REG_QSUB_ABSSEC	0x1b

#define AK4113_REG_QSUB_ABSFRM	0x1c


#define AK4113_REG_RXCSB_SIZE	((AK4113_REG_RXCSB4-AK4113_REG_RXCSB0)+1)
#define AK4113_REG_QSUB_SIZE	((AK4113_REG_QSUB_ABSFRM-AK4113_REG_QSUB_ADDR)\
		+1)

#define AK4113_WRITABLE_REGS	(AK4113_REG_DATDTS + 1)



#define AK4113_CS12		(1<<7)

#define AK4113_BCU		(1<<6)

#define AK4113_CM1		(1<<5)

#define AK4113_CM0		(1<<4)

#define AK4113_OCKS1		(1<<3)

#define AK4113_OCKS0		(1<<2)

#define AK4113_PWN		(1<<1)

#define AK4113_RST		(1<<0)



#define AK4113_VTX		(1<<7)

#define AK4113_DIF2		(1<<6)

#define AK4113_DIF1		(1<<5)

#define AK4113_DIF0		(1<<4)

#define AK4113_DEAU		(1<<3)

#define AK4113_DEM1		(1<<2)

#define AK4113_DEM0		(1<<1)
#define AK4113_DEM_OFF		(AK4113_DEM0)
#define AK4113_DEM_44KHZ	(0)
#define AK4113_DEM_48KHZ	(AK4113_DEM1)
#define AK4113_DEM_32KHZ	(AK4113_DEM0|AK4113_DEM1)

#define AK4113_DIF_16R		(0)

#define AK4113_DIF_18R		(AK4113_DIF0)

#define AK4113_DIF_20R		(AK4113_DIF1)

#define AK4113_DIF_24R		(AK4113_DIF1|AK4113_DIF0)

#define AK4113_DIF_24L		(AK4113_DIF2)

#define AK4113_DIF_24I2S	(AK4113_DIF2|AK4113_DIF0)

#define AK4113_DIF_I24L		(AK4113_DIF2|AK4113_DIF1)

#define AK4113_DIF_I24I2S	(AK4113_DIF2|AK4113_DIF1|AK4113_DIF0)



#define AK4113_XTL1		(1<<6)

#define AK4113_XTL0		(1<<5)

#define AK4113_UCE		(1<<4)

#define AK4113_TXE		(1<<3)

#define AK4113_OPS2		(1<<2)

#define AK4113_OPS1		(1<<1)

#define AK4113_OPS0		(1<<0)

#define AK4113_XTL_11_2896M	(0)

#define AK4113_XTL_12_288M	(AK4113_XTL0)

#define AK4113_XTL_24_576M	(AK4113_XTL1)



#define AK4113_EFH1		(1<<7)

#define AK4113_EFH0		(1<<6)
#define AK4113_EFH_512LRCLK	(0)
#define AK4113_EFH_1024LRCLK	(AK4113_EFH0)
#define AK4113_EFH_2048LRCLK	(AK4113_EFH1)
#define AK4113_EFH_4096LRCLK	(AK4113_EFH1|AK4113_EFH0)

#define AK4113_FAST		(1<<5)

#define AK4113_XMCK		(1<<4)

#define AK4113_DIV		(1<<3)

#define AK4113_IPS2		(1<<2)

#define AK4113_IPS1		(1<<1)

#define AK4113_IPS0		(1<<0)
#define AK4113_IPS(x)		((x)&7)



#define AK4113_MQI		(1<<7)

#define AK4113_MAUT		(1<<6)

#define AK4113_MCIT		(1<<5)

#define AK4113_MULK		(1<<4)

#define AK4113_V		(1<<3)

#define AK4113_STC		(1<<2)

#define AK4113_MAN		(1<<1)

#define AK4113_MPR		(1<<0)



#define AK4113_DCNT		(1<<4)

#define AK4113_DTS16		(1<<3)

#define AK4113_DTS14		(1<<2)

#define AK4113_MDAT1		(1<<1)

#define AK4113_MDAT0		(1<<0)



#define AK4113_QINT		(1<<7)

#define AK4113_AUTO		(1<<6)

#define AK4113_CINT		(1<<5)

#define AK4113_UNLCK		(1<<4)

#define AK4113_V		(1<<3)

#define AK4113_STC		(1<<2)

#define AK4113_AUDION		(1<<1)

#define AK4113_PAR		(1<<0)



#define AK4113_FS3		(1<<7)
#define AK4113_FS2		(1<<6)
#define AK4113_FS1		(1<<5)
#define AK4113_FS0		(1<<4)

#define AK4113_PEM		(1<<3)

#define AK4113_DAT		(1<<2)

#define AK4113_DTSCD		(1<<1)

#define AK4113_NPCM		(1<<0)
#define AK4113_FS_8000HZ	(AK4113_FS3|AK4113_FS0)
#define AK4113_FS_11025HZ	(AK4113_FS2|AK4113_FS0)
#define AK4113_FS_16000HZ	(AK4113_FS2|AK4113_FS1|AK4113_FS0)
#define AK4113_FS_22050HZ	(AK4113_FS2)
#define AK4113_FS_24000HZ	(AK4113_FS2|AK4113_FS1)
#define AK4113_FS_32000HZ	(AK4113_FS1|AK4113_FS0)
#define AK4113_FS_44100HZ	(0)
#define AK4113_FS_48000HZ	(AK4113_FS1)
#define AK4113_FS_64000HZ	(AK4113_FS3|AK4113_FS1|AK4113_FS0)
#define AK4113_FS_88200HZ	(AK4113_FS3)
#define AK4113_FS_96000HZ	(AK4113_FS3|AK4113_FS1)
#define AK4113_FS_176400HZ	(AK4113_FS3|AK4113_FS2)
#define AK4113_FS_192000HZ	(AK4113_FS3|AK4113_FS2|AK4113_FS1)



#define AK4113_QCRC		(1<<1)

#define AK4113_CCRC		(1<<0)


#define AK4113_CHECK_NO_STAT	(1<<0)	
#define AK4113_CHECK_NO_RATE	(1<<1)	

#define AK4113_CONTROLS		13

typedef void (ak4113_write_t)(void *private_data, unsigned char addr,
		unsigned char data);
typedef unsigned char (ak4113_read_t)(void *private_data, unsigned char addr);

enum {
	AK4113_PARITY_ERRORS,
	AK4113_V_BIT_ERRORS,
	AK4113_QCRC_ERRORS,
	AK4113_CCRC_ERRORS,
	AK4113_NUM_ERRORS
};

struct ak4113 {
	struct snd_card *card;
	ak4113_write_t *write;
	ak4113_read_t *read;
	void *private_data;
	atomic_t wq_processing;
	struct mutex reinit_mutex;
	spinlock_t lock;
	unsigned char regmap[AK4113_WRITABLE_REGS];
	struct snd_kcontrol *kctls[AK4113_CONTROLS];
	struct snd_pcm_substream *substream;
	unsigned long errors[AK4113_NUM_ERRORS];
	unsigned char rcs0;
	unsigned char rcs1;
	unsigned char rcs2;
	struct delayed_work work;
	unsigned int check_flags;
	void *change_callback_private;
	void (*change_callback)(struct ak4113 *ak4113, unsigned char c0,
			unsigned char c1);
};

int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
		ak4113_write_t *write,
		const unsigned char *pgm,
		void *private_data, struct ak4113 **r_ak4113);
void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg,
		unsigned char mask, unsigned char val);
void snd_ak4113_reinit(struct ak4113 *ak4113);
int snd_ak4113_build(struct ak4113 *ak4113,
		struct snd_pcm_substream *capture_substream);
int snd_ak4113_external_rate(struct ak4113 *ak4113);
int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags);

#ifdef CONFIG_PM
void snd_ak4113_suspend(struct ak4113 *chip);
void snd_ak4113_resume(struct ak4113 *chip);
#else
static inline void snd_ak4113_suspend(struct ak4113 *chip) {}
static inline void snd_ak4113_resume(struct ak4113 *chip) {}
#endif

#endif 

