cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ak4xxx-adda.c (25665B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *   ALSA driver for AK4524 / AK4528 / AK4529 / AK4355 / AK4358 / AK4381
      4 *   AD and DA converters
      5 *
      6 *	Copyright (c) 2000-2004 Jaroslav Kysela <perex@perex.cz>,
      7 *				Takashi Iwai <tiwai@suse.de>
      8 */
      9
     10#include <linux/io.h>
     11#include <linux/delay.h>
     12#include <linux/interrupt.h>
     13#include <linux/init.h>
     14#include <linux/module.h>
     15#include <sound/core.h>
     16#include <sound/control.h>
     17#include <sound/tlv.h>
     18#include <sound/ak4xxx-adda.h>
     19#include <sound/info.h>
     20
     21MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
     22MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx  AD/DA converters");
     23MODULE_LICENSE("GPL");
     24
     25/* write the given register and save the data to the cache */
     26void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg,
     27		       unsigned char val)
     28{
     29	ak->ops.lock(ak, chip);
     30	ak->ops.write(ak, chip, reg, val);
     31
     32	/* save the data */
     33	snd_akm4xxx_set(ak, chip, reg, val);
     34	ak->ops.unlock(ak, chip);
     35}
     36
     37EXPORT_SYMBOL(snd_akm4xxx_write);
     38
     39/* reset procedure for AK4524 and AK4528 */
     40static void ak4524_reset(struct snd_akm4xxx *ak, int state)
     41{
     42	unsigned int chip;
     43	unsigned char reg;
     44
     45	for (chip = 0; chip < ak->num_dacs/2; chip++) {
     46		snd_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03);
     47		if (state)
     48			continue;
     49		/* DAC volumes */
     50		for (reg = 0x04; reg < ak->total_regs; reg++)
     51			snd_akm4xxx_write(ak, chip, reg,
     52					  snd_akm4xxx_get(ak, chip, reg));
     53	}
     54}
     55
     56/* reset procedure for AK4355 and AK4358 */
     57static void ak435X_reset(struct snd_akm4xxx *ak, int state)
     58{
     59	unsigned char reg;
     60
     61	if (state) {
     62		snd_akm4xxx_write(ak, 0, 0x01, 0x02); /* reset and soft-mute */
     63		return;
     64	}
     65	for (reg = 0x00; reg < ak->total_regs; reg++)
     66		if (reg != 0x01)
     67			snd_akm4xxx_write(ak, 0, reg,
     68					  snd_akm4xxx_get(ak, 0, reg));
     69	snd_akm4xxx_write(ak, 0, 0x01, 0x01); /* un-reset, unmute */
     70}
     71
     72/* reset procedure for AK4381 */
     73static void ak4381_reset(struct snd_akm4xxx *ak, int state)
     74{
     75	unsigned int chip;
     76	unsigned char reg;
     77	for (chip = 0; chip < ak->num_dacs/2; chip++) {
     78		snd_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f);
     79		if (state)
     80			continue;
     81		for (reg = 0x01; reg < ak->total_regs; reg++)
     82			snd_akm4xxx_write(ak, chip, reg,
     83					  snd_akm4xxx_get(ak, chip, reg));
     84	}
     85}
     86
     87/*
     88 * reset the AKM codecs
     89 * @state: 1 = reset codec, 0 = restore the registers
     90 *
     91 * assert the reset operation and restores the register values to the chips.
     92 */
     93void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state)
     94{
     95	switch (ak->type) {
     96	case SND_AK4524:
     97	case SND_AK4528:
     98	case SND_AK4620:
     99		ak4524_reset(ak, state);
    100		break;
    101	case SND_AK4529:
    102		/* FIXME: needed for ak4529? */
    103		break;
    104	case SND_AK4355:
    105		ak435X_reset(ak, state);
    106		break;
    107	case SND_AK4358:
    108		ak435X_reset(ak, state);
    109		break;
    110	case SND_AK4381:
    111		ak4381_reset(ak, state);
    112		break;
    113	default:
    114		break;
    115	}
    116}
    117
    118EXPORT_SYMBOL(snd_akm4xxx_reset);
    119
    120
    121/*
    122 * Volume conversion table for non-linear volumes
    123 * from -63.5dB (mute) to 0dB step 0.5dB
    124 *
    125 * Used for AK4524/AK4620 input/ouput attenuation, AK4528, and
    126 * AK5365 input attenuation
    127 */
    128static const unsigned char vol_cvt_datt[128] = {
    129	0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04,
    130	0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06,
    131	0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x0a,
    132	0x0a, 0x0b, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f,
    133	0x10, 0x10, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14,
    134	0x15, 0x16, 0x17, 0x17, 0x18, 0x19, 0x1a, 0x1c,
    135	0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x23,
    136	0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2d,
    137	0x2e, 0x30, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
    138	0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3e, 0x3f, 0x40,
    139	0x41, 0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x4a,
    140	0x4b, 0x4d, 0x4e, 0x50, 0x51, 0x52, 0x53, 0x54,
    141	0x55, 0x56, 0x58, 0x59, 0x5b, 0x5c, 0x5e, 0x5f,
    142	0x60, 0x61, 0x62, 0x64, 0x65, 0x66, 0x67, 0x69,
    143	0x6a, 0x6c, 0x6d, 0x6f, 0x70, 0x71, 0x72, 0x73,
    144	0x75, 0x76, 0x77, 0x79, 0x7a, 0x7c, 0x7d, 0x7f,
    145};
    146
    147/*
    148 * dB tables
    149 */
    150static const DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1);
    151static const DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1);
    152static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1);
    153static const DECLARE_TLV_DB_LINEAR(db_scale_linear, TLV_DB_GAIN_MUTE, 0);
    154
    155/*
    156 * initialize all the ak4xxx chips
    157 */
    158void snd_akm4xxx_init(struct snd_akm4xxx *ak)
    159{
    160	static const unsigned char inits_ak4524[] = {
    161		0x00, 0x07, /* 0: all power up */
    162		0x01, 0x00, /* 1: ADC/DAC reset */
    163		0x02, 0x60, /* 2: 24bit I2S */
    164		0x03, 0x19, /* 3: deemphasis off */
    165		0x01, 0x03, /* 1: ADC/DAC enable */
    166		0x04, 0x00, /* 4: ADC left muted */
    167		0x05, 0x00, /* 5: ADC right muted */
    168		0x06, 0x00, /* 6: DAC left muted */
    169		0x07, 0x00, /* 7: DAC right muted */
    170		0xff, 0xff
    171	};
    172	static const unsigned char inits_ak4528[] = {
    173		0x00, 0x07, /* 0: all power up */
    174		0x01, 0x00, /* 1: ADC/DAC reset */
    175		0x02, 0x60, /* 2: 24bit I2S */
    176		0x03, 0x0d, /* 3: deemphasis off, turn LR highpass filters on */
    177		0x01, 0x03, /* 1: ADC/DAC enable */
    178		0x04, 0x00, /* 4: ADC left muted */
    179		0x05, 0x00, /* 5: ADC right muted */
    180		0xff, 0xff
    181	};
    182	static const unsigned char inits_ak4529[] = {
    183		0x09, 0x01, /* 9: ATS=0, RSTN=1 */
    184		0x0a, 0x3f, /* A: all power up, no zero/overflow detection */
    185		0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */
    186		0x01, 0x00, /* 1: ACKS=0, ADC, loop off */
    187		0x02, 0xff, /* 2: LOUT1 muted */
    188		0x03, 0xff, /* 3: ROUT1 muted */
    189		0x04, 0xff, /* 4: LOUT2 muted */
    190		0x05, 0xff, /* 5: ROUT2 muted */
    191		0x06, 0xff, /* 6: LOUT3 muted */
    192		0x07, 0xff, /* 7: ROUT3 muted */
    193		0x0b, 0xff, /* B: LOUT4 muted */
    194		0x0c, 0xff, /* C: ROUT4 muted */
    195		0x08, 0x55, /* 8: deemphasis all off */
    196		0xff, 0xff
    197	};
    198	static const unsigned char inits_ak4355[] = {
    199		0x01, 0x02, /* 1: reset and soft-mute */
    200		0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
    201			     * disable DZF, sharp roll-off, RSTN#=0 */
    202		0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */
    203		// 0x02, 0x2e, /* quad speed */
    204		0x03, 0x01, /* 3: de-emphasis off */
    205		0x04, 0x00, /* 4: LOUT1 volume muted */
    206		0x05, 0x00, /* 5: ROUT1 volume muted */
    207		0x06, 0x00, /* 6: LOUT2 volume muted */
    208		0x07, 0x00, /* 7: ROUT2 volume muted */
    209		0x08, 0x00, /* 8: LOUT3 volume muted */
    210		0x09, 0x00, /* 9: ROUT3 volume muted */
    211		0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
    212		0x01, 0x01, /* 1: un-reset, unmute */
    213		0xff, 0xff
    214	};
    215	static const unsigned char inits_ak4358[] = {
    216		0x01, 0x02, /* 1: reset and soft-mute */
    217		0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
    218			     * disable DZF, sharp roll-off, RSTN#=0 */
    219		0x02, 0x4e, /* 2: DA's power up, normal speed, RSTN#=0 */
    220		/* 0x02, 0x6e,*/ /* quad speed */
    221		0x03, 0x01, /* 3: de-emphasis off */
    222		0x04, 0x00, /* 4: LOUT1 volume muted */
    223		0x05, 0x00, /* 5: ROUT1 volume muted */
    224		0x06, 0x00, /* 6: LOUT2 volume muted */
    225		0x07, 0x00, /* 7: ROUT2 volume muted */
    226		0x08, 0x00, /* 8: LOUT3 volume muted */
    227		0x09, 0x00, /* 9: ROUT3 volume muted */
    228		0x0b, 0x00, /* b: LOUT4 volume muted */
    229		0x0c, 0x00, /* c: ROUT4 volume muted */
    230		0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
    231		0x01, 0x01, /* 1: un-reset, unmute */
    232		0xff, 0xff
    233	};
    234	static const unsigned char inits_ak4381[] = {
    235		0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */
    236		0x01, 0x02, /* 1: de-emphasis off, normal speed,
    237			     * sharp roll-off, DZF off */
    238		// 0x01, 0x12, /* quad speed */
    239		0x02, 0x00, /* 2: DZF disabled */
    240		0x03, 0x00, /* 3: LATT 0 */
    241		0x04, 0x00, /* 4: RATT 0 */
    242		0x00, 0x0f, /* 0: power-up, un-reset */
    243		0xff, 0xff
    244	};
    245	static const unsigned char inits_ak4620[] = {
    246		0x00, 0x07, /* 0: normal */
    247		0x01, 0x00, /* 0: reset */
    248		0x01, 0x02, /* 1: RSTAD */
    249		0x01, 0x03, /* 1: RSTDA */
    250		0x01, 0x0f, /* 1: normal */
    251		0x02, 0x60, /* 2: 24bit I2S */
    252		0x03, 0x01, /* 3: deemphasis off */
    253		0x04, 0x00, /* 4: LIN muted */
    254		0x05, 0x00, /* 5: RIN muted */
    255		0x06, 0x00, /* 6: LOUT muted */
    256		0x07, 0x00, /* 7: ROUT muted */
    257		0xff, 0xff
    258	};
    259
    260	int chip;
    261	const unsigned char *ptr, *inits;
    262	unsigned char reg, data;
    263
    264	memset(ak->images, 0, sizeof(ak->images));
    265	memset(ak->volumes, 0, sizeof(ak->volumes));
    266
    267	switch (ak->type) {
    268	case SND_AK4524:
    269		inits = inits_ak4524;
    270		ak->num_chips = ak->num_dacs / 2;
    271		ak->name = "ak4524";
    272		ak->total_regs = 0x08;
    273		break;
    274	case SND_AK4528:
    275		inits = inits_ak4528;
    276		ak->num_chips = ak->num_dacs / 2;
    277		ak->name = "ak4528";
    278		ak->total_regs = 0x06;
    279		break;
    280	case SND_AK4529:
    281		inits = inits_ak4529;
    282		ak->num_chips = 1;
    283		ak->name = "ak4529";
    284		ak->total_regs = 0x0d;
    285		break;
    286	case SND_AK4355:
    287		inits = inits_ak4355;
    288		ak->num_chips = 1;
    289		ak->name = "ak4355";
    290		ak->total_regs = 0x0b;
    291		break;
    292	case SND_AK4358:
    293		inits = inits_ak4358;
    294		ak->num_chips = 1;
    295		ak->name = "ak4358";
    296		ak->total_regs = 0x10;
    297		break;
    298	case SND_AK4381:
    299		inits = inits_ak4381;
    300		ak->num_chips = ak->num_dacs / 2;
    301		ak->name = "ak4381";
    302		ak->total_regs = 0x05;
    303		break;
    304	case SND_AK5365:
    305		/* FIXME: any init sequence? */
    306		ak->num_chips = 1;
    307		ak->name = "ak5365";
    308		ak->total_regs = 0x08;
    309		return;
    310	case SND_AK4620:
    311		inits = inits_ak4620;
    312		ak->num_chips = ak->num_dacs / 2;
    313		ak->name = "ak4620";
    314		ak->total_regs = 0x08;
    315		break;
    316	default:
    317		snd_BUG();
    318		return;
    319	}
    320
    321	for (chip = 0; chip < ak->num_chips; chip++) {
    322		ptr = inits;
    323		while (*ptr != 0xff) {
    324			reg = *ptr++;
    325			data = *ptr++;
    326			snd_akm4xxx_write(ak, chip, reg, data);
    327			udelay(10);
    328		}
    329	}
    330}
    331
    332EXPORT_SYMBOL(snd_akm4xxx_init);
    333
    334/*
    335 * Mixer callbacks
    336 */
    337#define AK_IPGA 			(1<<20)	/* including IPGA */
    338#define AK_VOL_CVT 			(1<<21)	/* need dB conversion */
    339#define AK_NEEDSMSB 			(1<<22)	/* need MSB update bit */
    340#define AK_INVERT 			(1<<23)	/* data is inverted */
    341#define AK_GET_CHIP(val)		(((val) >> 8) & 0xff)
    342#define AK_GET_ADDR(val)		((val) & 0xff)
    343#define AK_GET_SHIFT(val)		(((val) >> 16) & 0x0f)
    344#define AK_GET_VOL_CVT(val)		(((val) >> 21) & 1)
    345#define AK_GET_IPGA(val)		(((val) >> 20) & 1)
    346#define AK_GET_NEEDSMSB(val)		(((val) >> 22) & 1)
    347#define AK_GET_INVERT(val)		(((val) >> 23) & 1)
    348#define AK_GET_MASK(val)		(((val) >> 24) & 0xff)
    349#define AK_COMPOSE(chip,addr,shift,mask) \
    350	(((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24))
    351
    352static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol,
    353				   struct snd_ctl_elem_info *uinfo)
    354{
    355	unsigned int mask = AK_GET_MASK(kcontrol->private_value);
    356
    357	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    358	uinfo->count = 1;
    359	uinfo->value.integer.min = 0;
    360	uinfo->value.integer.max = mask;
    361	return 0;
    362}
    363
    364static int snd_akm4xxx_volume_get(struct snd_kcontrol *kcontrol,
    365				  struct snd_ctl_elem_value *ucontrol)
    366{
    367	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    368	int chip = AK_GET_CHIP(kcontrol->private_value);
    369	int addr = AK_GET_ADDR(kcontrol->private_value);
    370
    371	ucontrol->value.integer.value[0] = snd_akm4xxx_get_vol(ak, chip, addr);
    372	return 0;
    373}
    374
    375static int put_ak_reg(struct snd_kcontrol *kcontrol, int addr,
    376		      unsigned char nval)
    377{
    378	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    379	unsigned int mask = AK_GET_MASK(kcontrol->private_value);
    380	int chip = AK_GET_CHIP(kcontrol->private_value);
    381
    382	if (snd_akm4xxx_get_vol(ak, chip, addr) == nval)
    383		return 0;
    384
    385	snd_akm4xxx_set_vol(ak, chip, addr, nval);
    386	if (AK_GET_VOL_CVT(kcontrol->private_value) && nval < 128)
    387		nval = vol_cvt_datt[nval];
    388	if (AK_GET_IPGA(kcontrol->private_value) && nval >= 128)
    389		nval++; /* need to correct + 1 since both 127 and 128 are 0dB */
    390	if (AK_GET_INVERT(kcontrol->private_value))
    391		nval = mask - nval;
    392	if (AK_GET_NEEDSMSB(kcontrol->private_value))
    393		nval |= 0x80;
    394	/* printk(KERN_DEBUG "DEBUG - AK writing reg: chip %x addr %x,
    395	   nval %x\n", chip, addr, nval); */
    396	snd_akm4xxx_write(ak, chip, addr, nval);
    397	return 1;
    398}
    399
    400static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol,
    401				  struct snd_ctl_elem_value *ucontrol)
    402{
    403	unsigned int mask = AK_GET_MASK(kcontrol->private_value);
    404	unsigned int val = ucontrol->value.integer.value[0];
    405	if (val > mask)
    406		return -EINVAL;
    407	return put_ak_reg(kcontrol, AK_GET_ADDR(kcontrol->private_value), val);
    408}
    409
    410static int snd_akm4xxx_stereo_volume_info(struct snd_kcontrol *kcontrol,
    411					  struct snd_ctl_elem_info *uinfo)
    412{
    413	unsigned int mask = AK_GET_MASK(kcontrol->private_value);
    414
    415	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    416	uinfo->count = 2;
    417	uinfo->value.integer.min = 0;
    418	uinfo->value.integer.max = mask;
    419	return 0;
    420}
    421
    422static int snd_akm4xxx_stereo_volume_get(struct snd_kcontrol *kcontrol,
    423					 struct snd_ctl_elem_value *ucontrol)
    424{
    425	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    426	int chip = AK_GET_CHIP(kcontrol->private_value);
    427	int addr = AK_GET_ADDR(kcontrol->private_value);
    428
    429	ucontrol->value.integer.value[0] = snd_akm4xxx_get_vol(ak, chip, addr);
    430	ucontrol->value.integer.value[1] = snd_akm4xxx_get_vol(ak, chip, addr+1);
    431	return 0;
    432}
    433
    434static int snd_akm4xxx_stereo_volume_put(struct snd_kcontrol *kcontrol,
    435					 struct snd_ctl_elem_value *ucontrol)
    436{
    437	int addr = AK_GET_ADDR(kcontrol->private_value);
    438	unsigned int mask = AK_GET_MASK(kcontrol->private_value);
    439	unsigned int val[2];
    440	int change;
    441
    442	val[0] = ucontrol->value.integer.value[0];
    443	val[1] = ucontrol->value.integer.value[1];
    444	if (val[0] > mask || val[1] > mask)
    445		return -EINVAL;
    446	change = put_ak_reg(kcontrol, addr, val[0]);
    447	change |= put_ak_reg(kcontrol, addr + 1, val[1]);
    448	return change;
    449}
    450
    451static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol,
    452				       struct snd_ctl_elem_info *uinfo)
    453{
    454	static const char * const texts[4] = {
    455		"44.1kHz", "Off", "48kHz", "32kHz",
    456	};
    457	return snd_ctl_enum_info(uinfo, 1, 4, texts);
    458}
    459
    460static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol,
    461				      struct snd_ctl_elem_value *ucontrol)
    462{
    463	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    464	int chip = AK_GET_CHIP(kcontrol->private_value);
    465	int addr = AK_GET_ADDR(kcontrol->private_value);
    466	int shift = AK_GET_SHIFT(kcontrol->private_value);
    467	ucontrol->value.enumerated.item[0] =
    468		(snd_akm4xxx_get(ak, chip, addr) >> shift) & 3;
    469	return 0;
    470}
    471
    472static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol,
    473				      struct snd_ctl_elem_value *ucontrol)
    474{
    475	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    476	int chip = AK_GET_CHIP(kcontrol->private_value);
    477	int addr = AK_GET_ADDR(kcontrol->private_value);
    478	int shift = AK_GET_SHIFT(kcontrol->private_value);
    479	unsigned char nval = ucontrol->value.enumerated.item[0] & 3;
    480	int change;
    481	
    482	nval = (nval << shift) |
    483		(snd_akm4xxx_get(ak, chip, addr) & ~(3 << shift));
    484	change = snd_akm4xxx_get(ak, chip, addr) != nval;
    485	if (change)
    486		snd_akm4xxx_write(ak, chip, addr, nval);
    487	return change;
    488}
    489
    490#define ak4xxx_switch_info	snd_ctl_boolean_mono_info
    491
    492static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol,
    493			     struct snd_ctl_elem_value *ucontrol)
    494{
    495	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    496	int chip = AK_GET_CHIP(kcontrol->private_value);
    497	int addr = AK_GET_ADDR(kcontrol->private_value);
    498	int shift = AK_GET_SHIFT(kcontrol->private_value);
    499	int invert = AK_GET_INVERT(kcontrol->private_value);
    500	/* we observe the (1<<shift) bit only */
    501	unsigned char val = snd_akm4xxx_get(ak, chip, addr) & (1<<shift);
    502	if (invert)
    503		val = ! val;
    504	ucontrol->value.integer.value[0] = (val & (1<<shift)) != 0;
    505	return 0;
    506}
    507
    508static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol,
    509			     struct snd_ctl_elem_value *ucontrol)
    510{
    511	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    512	int chip = AK_GET_CHIP(kcontrol->private_value);
    513	int addr = AK_GET_ADDR(kcontrol->private_value);
    514	int shift = AK_GET_SHIFT(kcontrol->private_value);
    515	int invert = AK_GET_INVERT(kcontrol->private_value);
    516	long flag = ucontrol->value.integer.value[0];
    517	unsigned char val, oval;
    518	int change;
    519
    520	if (invert)
    521		flag = ! flag;
    522	oval = snd_akm4xxx_get(ak, chip, addr);
    523	if (flag)
    524		val = oval | (1<<shift);
    525	else
    526		val = oval & ~(1<<shift);
    527	change = (oval != val);
    528	if (change)
    529		snd_akm4xxx_write(ak, chip, addr, val);
    530	return change;
    531}
    532
    533#define AK5365_NUM_INPUTS 5
    534
    535static int ak4xxx_capture_num_inputs(struct snd_akm4xxx *ak, int mixer_ch)
    536{
    537	int num_names;
    538	const char **input_names;
    539
    540	input_names = ak->adc_info[mixer_ch].input_names;
    541	num_names = 0;
    542	while (num_names < AK5365_NUM_INPUTS && input_names[num_names])
    543		++num_names;
    544	return num_names;
    545}
    546
    547static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol,
    548				      struct snd_ctl_elem_info *uinfo)
    549{
    550	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    551	int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
    552	unsigned int num_names;
    553
    554	num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
    555	if (!num_names)
    556		return -EINVAL;
    557	return snd_ctl_enum_info(uinfo, 1, num_names,
    558				 ak->adc_info[mixer_ch].input_names);
    559}
    560
    561static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol,
    562				     struct snd_ctl_elem_value *ucontrol)
    563{
    564	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    565	int chip = AK_GET_CHIP(kcontrol->private_value);
    566	int addr = AK_GET_ADDR(kcontrol->private_value);
    567	int mask = AK_GET_MASK(kcontrol->private_value);
    568	unsigned char val;
    569
    570	val = snd_akm4xxx_get(ak, chip, addr) & mask;
    571	ucontrol->value.enumerated.item[0] = val;
    572	return 0;
    573}
    574
    575static int ak4xxx_capture_source_put(struct snd_kcontrol *kcontrol,
    576				     struct snd_ctl_elem_value *ucontrol)
    577{
    578	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
    579	int mixer_ch = AK_GET_SHIFT(kcontrol->private_value);
    580	int chip = AK_GET_CHIP(kcontrol->private_value);
    581	int addr = AK_GET_ADDR(kcontrol->private_value);
    582	int mask = AK_GET_MASK(kcontrol->private_value);
    583	unsigned char oval, val;
    584	int num_names = ak4xxx_capture_num_inputs(ak, mixer_ch);
    585
    586	if (ucontrol->value.enumerated.item[0] >= num_names)
    587		return -EINVAL;
    588
    589	oval = snd_akm4xxx_get(ak, chip, addr);
    590	val = oval & ~mask;
    591	val |= ucontrol->value.enumerated.item[0] & mask;
    592	if (val != oval) {
    593		snd_akm4xxx_write(ak, chip, addr, val);
    594		return 1;
    595	}
    596	return 0;
    597}
    598
    599/*
    600 * build AK4xxx controls
    601 */
    602
    603static int build_dac_controls(struct snd_akm4xxx *ak)
    604{
    605	int idx, err, mixer_ch, num_stereo;
    606	struct snd_kcontrol_new knew;
    607
    608	mixer_ch = 0;
    609	for (idx = 0; idx < ak->num_dacs; ) {
    610		/* mute control for Revolution 7.1 - AK4381 */
    611		if (ak->type == SND_AK4381 
    612				&&  ak->dac_info[mixer_ch].switch_name) {
    613			memset(&knew, 0, sizeof(knew));
    614			knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
    615			knew.count = 1;
    616			knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
    617			knew.name = ak->dac_info[mixer_ch].switch_name;
    618			knew.info = ak4xxx_switch_info;
    619			knew.get = ak4xxx_switch_get;
    620			knew.put = ak4xxx_switch_put;
    621			knew.access = 0;
    622			/* register 1, bit 0 (SMUTE): 0 = normal operation,
    623			   1 = mute */
    624			knew.private_value =
    625				AK_COMPOSE(idx/2, 1, 0, 0) | AK_INVERT;
    626			err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
    627			if (err < 0)
    628				return err;
    629		}
    630		memset(&knew, 0, sizeof(knew));
    631		if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) {
    632			knew.name = "DAC Volume";
    633			knew.index = mixer_ch + ak->idx_offset * 2;
    634			num_stereo = 1;
    635		} else {
    636			knew.name = ak->dac_info[mixer_ch].name;
    637			num_stereo = ak->dac_info[mixer_ch].num_channels;
    638		}
    639		knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
    640		knew.count = 1;
    641		knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
    642			SNDRV_CTL_ELEM_ACCESS_TLV_READ;
    643		if (num_stereo == 2) {
    644			knew.info = snd_akm4xxx_stereo_volume_info;
    645			knew.get = snd_akm4xxx_stereo_volume_get;
    646			knew.put = snd_akm4xxx_stereo_volume_put;
    647		} else {
    648			knew.info = snd_akm4xxx_volume_info;
    649			knew.get = snd_akm4xxx_volume_get;
    650			knew.put = snd_akm4xxx_volume_put;
    651		}
    652		switch (ak->type) {
    653		case SND_AK4524:
    654			/* register 6 & 7 */
    655			knew.private_value =
    656				AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127) |
    657				AK_VOL_CVT;
    658			knew.tlv.p = db_scale_vol_datt;
    659			break;
    660		case SND_AK4528:
    661			/* register 4 & 5 */
    662			knew.private_value =
    663				AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127) |
    664				AK_VOL_CVT;
    665			knew.tlv.p = db_scale_vol_datt;
    666			break;
    667		case SND_AK4529: {
    668			/* registers 2-7 and b,c */
    669			int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb;
    670			knew.private_value =
    671				AK_COMPOSE(0, val, 0, 255) | AK_INVERT;
    672			knew.tlv.p = db_scale_8bit;
    673			break;
    674		}
    675		case SND_AK4355:
    676			/* register 4-9, chip #0 only */
    677			knew.private_value = AK_COMPOSE(0, idx + 4, 0, 255);
    678			knew.tlv.p = db_scale_8bit;
    679			break;
    680		case SND_AK4358: {
    681			/* register 4-9 and 11-12, chip #0 only */
    682			int  addr = idx < 6 ? idx + 4 : idx + 5;
    683			knew.private_value =
    684				AK_COMPOSE(0, addr, 0, 127) | AK_NEEDSMSB;
    685			knew.tlv.p = db_scale_7bit;
    686			break;
    687		}
    688		case SND_AK4381:
    689			/* register 3 & 4 */
    690			knew.private_value =
    691				AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255);
    692			knew.tlv.p = db_scale_linear;
    693			break;
    694		case SND_AK4620:
    695			/* register 6 & 7 */
    696			knew.private_value =
    697				AK_COMPOSE(idx/2, (idx%2) + 6, 0, 255);
    698			knew.tlv.p = db_scale_linear;
    699			break;
    700		default:
    701			return -EINVAL;
    702		}
    703
    704		err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
    705		if (err < 0)
    706			return err;
    707
    708		idx += num_stereo;
    709		mixer_ch++;
    710	}
    711	return 0;
    712}
    713
    714static int build_adc_controls(struct snd_akm4xxx *ak)
    715{
    716	int idx, err, mixer_ch, num_stereo, max_steps;
    717	struct snd_kcontrol_new knew;
    718
    719	mixer_ch = 0;
    720	if (ak->type == SND_AK4528)
    721		return 0;	/* no controls */
    722	for (idx = 0; idx < ak->num_adcs;) {
    723		memset(&knew, 0, sizeof(knew));
    724		if (! ak->adc_info || ! ak->adc_info[mixer_ch].name) {
    725			knew.name = "ADC Volume";
    726			knew.index = mixer_ch + ak->idx_offset * 2;
    727			num_stereo = 1;
    728		} else {
    729			knew.name = ak->adc_info[mixer_ch].name;
    730			num_stereo = ak->adc_info[mixer_ch].num_channels;
    731		}
    732		knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
    733		knew.count = 1;
    734		knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
    735			SNDRV_CTL_ELEM_ACCESS_TLV_READ;
    736		if (num_stereo == 2) {
    737			knew.info = snd_akm4xxx_stereo_volume_info;
    738			knew.get = snd_akm4xxx_stereo_volume_get;
    739			knew.put = snd_akm4xxx_stereo_volume_put;
    740		} else {
    741			knew.info = snd_akm4xxx_volume_info;
    742			knew.get = snd_akm4xxx_volume_get;
    743			knew.put = snd_akm4xxx_volume_put;
    744		}
    745		/* register 4 & 5 */
    746		if (ak->type == SND_AK5365)
    747			max_steps = 152;
    748		else
    749			max_steps = 164;
    750		knew.private_value =
    751			AK_COMPOSE(idx/2, (idx%2) + 4, 0, max_steps) |
    752			AK_VOL_CVT | AK_IPGA;
    753		knew.tlv.p = db_scale_vol_datt;
    754		err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
    755		if (err < 0)
    756			return err;
    757
    758		if (ak->type == SND_AK5365 && (idx % 2) == 0) {
    759			if (! ak->adc_info || 
    760			    ! ak->adc_info[mixer_ch].switch_name) {
    761				knew.name = "Capture Switch";
    762				knew.index = mixer_ch + ak->idx_offset * 2;
    763			} else
    764				knew.name = ak->adc_info[mixer_ch].switch_name;
    765			knew.info = ak4xxx_switch_info;
    766			knew.get = ak4xxx_switch_get;
    767			knew.put = ak4xxx_switch_put;
    768			knew.access = 0;
    769			/* register 2, bit 0 (SMUTE): 0 = normal operation,
    770			   1 = mute */
    771			knew.private_value =
    772				AK_COMPOSE(idx/2, 2, 0, 0) | AK_INVERT;
    773			err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
    774			if (err < 0)
    775				return err;
    776
    777			memset(&knew, 0, sizeof(knew));
    778			if (!ak->adc_info ||
    779				!ak->adc_info[mixer_ch].selector_name) {
    780				knew.name = "Capture Channel";
    781				knew.index = mixer_ch + ak->idx_offset * 2;
    782			} else
    783				knew.name = ak->adc_info[mixer_ch].selector_name;
    784
    785			knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
    786			knew.info = ak4xxx_capture_source_info;
    787			knew.get = ak4xxx_capture_source_get;
    788			knew.put = ak4xxx_capture_source_put;
    789			knew.access = 0;
    790			/* input selector control: reg. 1, bits 0-2.
    791			 * mis-use 'shift' to pass mixer_ch */
    792			knew.private_value
    793				= AK_COMPOSE(idx/2, 1, mixer_ch, 0x07);
    794			err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
    795			if (err < 0)
    796				return err;
    797		}
    798
    799		idx += num_stereo;
    800		mixer_ch++;
    801	}
    802	return 0;
    803}
    804
    805static int build_deemphasis(struct snd_akm4xxx *ak, int num_emphs)
    806{
    807	int idx, err;
    808	struct snd_kcontrol_new knew;
    809
    810	for (idx = 0; idx < num_emphs; idx++) {
    811		memset(&knew, 0, sizeof(knew));
    812		knew.name = "Deemphasis";
    813		knew.index = idx + ak->idx_offset;
    814		knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
    815		knew.count = 1;
    816		knew.info = snd_akm4xxx_deemphasis_info;
    817		knew.get = snd_akm4xxx_deemphasis_get;
    818		knew.put = snd_akm4xxx_deemphasis_put;
    819		switch (ak->type) {
    820		case SND_AK4524:
    821		case SND_AK4528:
    822		case SND_AK4620:
    823			/* register 3 */
    824			knew.private_value = AK_COMPOSE(idx, 3, 0, 0);
    825			break;
    826		case SND_AK4529: {
    827			int shift = idx == 3 ? 6 : (2 - idx) * 2;
    828			/* register 8 with shift */
    829			knew.private_value = AK_COMPOSE(0, 8, shift, 0);
    830			break;
    831		}
    832		case SND_AK4355:
    833		case SND_AK4358:
    834			knew.private_value = AK_COMPOSE(idx, 3, 0, 0);
    835			break;
    836		case SND_AK4381:
    837			knew.private_value = AK_COMPOSE(idx, 1, 1, 0);
    838			break;
    839		default:
    840			return -EINVAL;
    841		}
    842		err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak));
    843		if (err < 0)
    844			return err;
    845	}
    846	return 0;
    847}
    848
    849static void proc_regs_read(struct snd_info_entry *entry,
    850		struct snd_info_buffer *buffer)
    851{
    852	struct snd_akm4xxx *ak = entry->private_data;
    853	int reg, val, chip;
    854	for (chip = 0; chip < ak->num_chips; chip++) {
    855		for (reg = 0; reg < ak->total_regs; reg++) {
    856			val =  snd_akm4xxx_get(ak, chip, reg);
    857			snd_iprintf(buffer, "chip %d: 0x%02x = 0x%02x\n", chip,
    858					reg, val);
    859		}
    860	}
    861}
    862
    863static int proc_init(struct snd_akm4xxx *ak)
    864{
    865	return snd_card_ro_proc_new(ak->card, ak->name, ak, proc_regs_read);
    866}
    867
    868int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
    869{
    870	int err, num_emphs;
    871
    872	err = build_dac_controls(ak);
    873	if (err < 0)
    874		return err;
    875
    876	err = build_adc_controls(ak);
    877	if (err < 0)
    878		return err;
    879	if (ak->type == SND_AK4355 || ak->type == SND_AK4358)
    880		num_emphs = 1;
    881	else if (ak->type == SND_AK4620)
    882		num_emphs = 0;
    883	else
    884		num_emphs = ak->num_dacs / 2;
    885	err = build_deemphasis(ak, num_emphs);
    886	if (err < 0)
    887		return err;
    888	err = proc_init(ak);
    889	if (err < 0)
    890		return err;
    891
    892	return 0;
    893}
    894EXPORT_SYMBOL(snd_akm4xxx_build_controls);