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

pontis.c (21334B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
      4 *
      5 *   Lowlevel functions for Pontis MS300
      6 *
      7 *	Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
      8 */
      9
     10#include <linux/delay.h>
     11#include <linux/interrupt.h>
     12#include <linux/init.h>
     13#include <linux/slab.h>
     14#include <linux/mutex.h>
     15
     16#include <sound/core.h>
     17#include <sound/info.h>
     18#include <sound/tlv.h>
     19
     20#include "ice1712.h"
     21#include "envy24ht.h"
     22#include "pontis.h"
     23
     24/* I2C addresses */
     25#define WM_DEV		0x34
     26#define CS_DEV		0x20
     27
     28/* WM8776 registers */
     29#define WM_HP_ATTEN_L		0x00	/* headphone left attenuation */
     30#define WM_HP_ATTEN_R		0x01	/* headphone left attenuation */
     31#define WM_HP_MASTER		0x02	/* headphone master (both channels) */
     32					/* override LLR */
     33#define WM_DAC_ATTEN_L		0x03	/* digital left attenuation */
     34#define WM_DAC_ATTEN_R		0x04
     35#define WM_DAC_MASTER		0x05
     36#define WM_PHASE_SWAP		0x06	/* DAC phase swap */
     37#define WM_DAC_CTRL1		0x07
     38#define WM_DAC_MUTE		0x08
     39#define WM_DAC_CTRL2		0x09
     40#define WM_DAC_INT		0x0a
     41#define WM_ADC_INT		0x0b
     42#define WM_MASTER_CTRL		0x0c
     43#define WM_POWERDOWN		0x0d
     44#define WM_ADC_ATTEN_L		0x0e
     45#define WM_ADC_ATTEN_R		0x0f
     46#define WM_ALC_CTRL1		0x10
     47#define WM_ALC_CTRL2		0x11
     48#define WM_ALC_CTRL3		0x12
     49#define WM_NOISE_GATE		0x13
     50#define WM_LIMITER		0x14
     51#define WM_ADC_MUX		0x15
     52#define WM_OUT_MUX		0x16
     53#define WM_RESET		0x17
     54
     55/*
     56 * GPIO
     57 */
     58#define PONTIS_CS_CS		(1<<4)	/* CS */
     59#define PONTIS_CS_CLK		(1<<5)	/* CLK */
     60#define PONTIS_CS_RDATA		(1<<6)	/* CS8416 -> VT1720 */
     61#define PONTIS_CS_WDATA		(1<<7)	/* VT1720 -> CS8416 */
     62
     63
     64/*
     65 * get the current register value of WM codec
     66 */
     67static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
     68{
     69	reg <<= 1;
     70	return ((unsigned short)ice->akm[0].images[reg] << 8) |
     71		ice->akm[0].images[reg + 1];
     72}
     73
     74/*
     75 * set the register value of WM codec and remember it
     76 */
     77static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
     78{
     79	unsigned short cval;
     80	cval = (reg << 9) | val;
     81	snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
     82}
     83
     84static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
     85{
     86	wm_put_nocache(ice, reg, val);
     87	reg <<= 1;
     88	ice->akm[0].images[reg] = val >> 8;
     89	ice->akm[0].images[reg + 1] = val;
     90}
     91
     92/*
     93 * DAC volume attenuation mixer control (-64dB to 0dB)
     94 */
     95
     96#define DAC_0dB	0xff
     97#define DAC_RES	128
     98#define DAC_MIN	(DAC_0dB - DAC_RES)
     99
    100static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
    101{
    102	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    103	uinfo->count = 2;
    104	uinfo->value.integer.min = 0;	/* mute */
    105	uinfo->value.integer.max = DAC_RES;	/* 0dB, 0.5dB step */
    106	return 0;
    107}
    108
    109static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    110{
    111	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    112	unsigned short val;
    113	int i;
    114
    115	mutex_lock(&ice->gpio_mutex);
    116	for (i = 0; i < 2; i++) {
    117		val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff;
    118		val = val > DAC_MIN ? (val - DAC_MIN) : 0;
    119		ucontrol->value.integer.value[i] = val;
    120	}
    121	mutex_unlock(&ice->gpio_mutex);
    122	return 0;
    123}
    124
    125static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    126{
    127	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    128	unsigned short oval, nval;
    129	int i, idx, change = 0;
    130
    131	mutex_lock(&ice->gpio_mutex);
    132	for (i = 0; i < 2; i++) {
    133		nval = ucontrol->value.integer.value[i];
    134		nval = (nval ? (nval + DAC_MIN) : 0) & 0xff;
    135		idx = WM_DAC_ATTEN_L + i;
    136		oval = wm_get(ice, idx) & 0xff;
    137		if (oval != nval) {
    138			wm_put(ice, idx, nval);
    139			wm_put_nocache(ice, idx, nval | 0x100);
    140			change = 1;
    141		}
    142	}
    143	mutex_unlock(&ice->gpio_mutex);
    144	return change;
    145}
    146
    147/*
    148 * ADC gain mixer control (-64dB to 0dB)
    149 */
    150
    151#define ADC_0dB	0xcf
    152#define ADC_RES	128
    153#define ADC_MIN	(ADC_0dB - ADC_RES)
    154
    155static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
    156{
    157	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    158	uinfo->count = 2;
    159	uinfo->value.integer.min = 0;	/* mute (-64dB) */
    160	uinfo->value.integer.max = ADC_RES;	/* 0dB, 0.5dB step */
    161	return 0;
    162}
    163
    164static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    165{
    166	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    167	unsigned short val;
    168	int i;
    169
    170	mutex_lock(&ice->gpio_mutex);
    171	for (i = 0; i < 2; i++) {
    172		val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
    173		val = val > ADC_MIN ? (val - ADC_MIN) : 0;
    174		ucontrol->value.integer.value[i] = val;
    175	}
    176	mutex_unlock(&ice->gpio_mutex);
    177	return 0;
    178}
    179
    180static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    181{
    182	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    183	unsigned short ovol, nvol;
    184	int i, idx, change = 0;
    185
    186	mutex_lock(&ice->gpio_mutex);
    187	for (i = 0; i < 2; i++) {
    188		nvol = ucontrol->value.integer.value[i];
    189		nvol = nvol ? (nvol + ADC_MIN) : 0;
    190		idx  = WM_ADC_ATTEN_L + i;
    191		ovol = wm_get(ice, idx) & 0xff;
    192		if (ovol != nvol) {
    193			wm_put(ice, idx, nvol);
    194			change = 1;
    195		}
    196	}
    197	mutex_unlock(&ice->gpio_mutex);
    198	return change;
    199}
    200
    201/*
    202 * ADC input mux mixer control
    203 */
    204#define wm_adc_mux_info		snd_ctl_boolean_mono_info
    205
    206static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    207{
    208	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    209	int bit = kcontrol->private_value;
    210
    211	mutex_lock(&ice->gpio_mutex);
    212	ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
    213	mutex_unlock(&ice->gpio_mutex);
    214	return 0;
    215}
    216
    217static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    218{
    219	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    220	int bit = kcontrol->private_value;
    221	unsigned short oval, nval;
    222	int change;
    223
    224	mutex_lock(&ice->gpio_mutex);
    225	nval = oval = wm_get(ice, WM_ADC_MUX);
    226	if (ucontrol->value.integer.value[0])
    227		nval |= (1 << bit);
    228	else
    229		nval &= ~(1 << bit);
    230	change = nval != oval;
    231	if (change) {
    232		wm_put(ice, WM_ADC_MUX, nval);
    233	}
    234	mutex_unlock(&ice->gpio_mutex);
    235	return change;
    236}
    237
    238/*
    239 * Analog bypass (In -> Out)
    240 */
    241#define wm_bypass_info		snd_ctl_boolean_mono_info
    242
    243static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    244{
    245	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    246
    247	mutex_lock(&ice->gpio_mutex);
    248	ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
    249	mutex_unlock(&ice->gpio_mutex);
    250	return 0;
    251}
    252
    253static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    254{
    255	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    256	unsigned short val, oval;
    257	int change = 0;
    258
    259	mutex_lock(&ice->gpio_mutex);
    260	val = oval = wm_get(ice, WM_OUT_MUX);
    261	if (ucontrol->value.integer.value[0])
    262		val |= 0x04;
    263	else
    264		val &= ~0x04;
    265	if (val != oval) {
    266		wm_put(ice, WM_OUT_MUX, val);
    267		change = 1;
    268	}
    269	mutex_unlock(&ice->gpio_mutex);
    270	return change;
    271}
    272
    273/*
    274 * Left/Right swap
    275 */
    276#define wm_chswap_info		snd_ctl_boolean_mono_info
    277
    278static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    279{
    280	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    281
    282	mutex_lock(&ice->gpio_mutex);
    283	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
    284	mutex_unlock(&ice->gpio_mutex);
    285	return 0;
    286}
    287
    288static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    289{
    290	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    291	unsigned short val, oval;
    292	int change = 0;
    293
    294	mutex_lock(&ice->gpio_mutex);
    295	oval = wm_get(ice, WM_DAC_CTRL1);
    296	val = oval & 0x0f;
    297	if (ucontrol->value.integer.value[0])
    298		val |= 0x60;
    299	else
    300		val |= 0x90;
    301	if (val != oval) {
    302		wm_put(ice, WM_DAC_CTRL1, val);
    303		wm_put_nocache(ice, WM_DAC_CTRL1, val);
    304		change = 1;
    305	}
    306	mutex_unlock(&ice->gpio_mutex);
    307	return change;
    308}
    309
    310/*
    311 * write data in the SPI mode
    312 */
    313static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
    314{
    315	unsigned int tmp = snd_ice1712_gpio_read(ice);
    316	if (val)
    317		tmp |= bit;
    318	else
    319		tmp &= ~bit;
    320	snd_ice1712_gpio_write(ice, tmp);
    321}
    322
    323static void spi_send_byte(struct snd_ice1712 *ice, unsigned char data)
    324{
    325	int i;
    326	for (i = 0; i < 8; i++) {
    327		set_gpio_bit(ice, PONTIS_CS_CLK, 0);
    328		udelay(1);
    329		set_gpio_bit(ice, PONTIS_CS_WDATA, data & 0x80);
    330		udelay(1);
    331		set_gpio_bit(ice, PONTIS_CS_CLK, 1);
    332		udelay(1);
    333		data <<= 1;
    334	}
    335}
    336
    337static unsigned int spi_read_byte(struct snd_ice1712 *ice)
    338{
    339	int i;
    340	unsigned int val = 0;
    341
    342	for (i = 0; i < 8; i++) {
    343		val <<= 1;
    344		set_gpio_bit(ice, PONTIS_CS_CLK, 0);
    345		udelay(1);
    346		if (snd_ice1712_gpio_read(ice) & PONTIS_CS_RDATA)
    347			val |= 1;
    348		udelay(1);
    349		set_gpio_bit(ice, PONTIS_CS_CLK, 1);
    350		udelay(1);
    351	}
    352	return val;
    353}
    354
    355
    356static void spi_write(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg, unsigned int data)
    357{
    358	snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
    359	snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
    360	set_gpio_bit(ice, PONTIS_CS_CS, 0);
    361	spi_send_byte(ice, dev & ~1); /* WRITE */
    362	spi_send_byte(ice, reg); /* MAP */
    363	spi_send_byte(ice, data); /* DATA */
    364	/* trigger */
    365	set_gpio_bit(ice, PONTIS_CS_CS, 1);
    366	udelay(1);
    367	/* restore */
    368	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
    369	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
    370}
    371
    372static unsigned int spi_read(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg)
    373{
    374	unsigned int val;
    375	snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
    376	snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
    377	set_gpio_bit(ice, PONTIS_CS_CS, 0);
    378	spi_send_byte(ice, dev & ~1); /* WRITE */
    379	spi_send_byte(ice, reg); /* MAP */
    380	/* trigger */
    381	set_gpio_bit(ice, PONTIS_CS_CS, 1);
    382	udelay(1);
    383	set_gpio_bit(ice, PONTIS_CS_CS, 0);
    384	spi_send_byte(ice, dev | 1); /* READ */
    385	val = spi_read_byte(ice);
    386	/* trigger */
    387	set_gpio_bit(ice, PONTIS_CS_CS, 1);
    388	udelay(1);
    389	/* restore */
    390	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
    391	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
    392	return val;
    393}
    394
    395
    396/*
    397 * SPDIF input source
    398 */
    399static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
    400{
    401	static const char * const texts[] = {
    402		"Coax",		/* RXP0 */
    403		"Optical",	/* RXP1 */
    404		"CD",		/* RXP2 */
    405	};
    406	return snd_ctl_enum_info(uinfo, 1, 3, texts);
    407}
    408
    409static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    410{
    411	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    412
    413	mutex_lock(&ice->gpio_mutex);
    414	ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];
    415	mutex_unlock(&ice->gpio_mutex);
    416	return 0;
    417}
    418
    419static int cs_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    420{
    421	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    422	unsigned char val;
    423	int change = 0;
    424
    425	mutex_lock(&ice->gpio_mutex);
    426	if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) {
    427		ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3;
    428		val = 0x80 | (ice->gpio.saved[0] << 3);
    429		spi_write(ice, CS_DEV, 0x04, val);
    430		change = 1;
    431	}
    432	mutex_unlock(&ice->gpio_mutex);
    433	return change;
    434}
    435
    436
    437/*
    438 * GPIO controls
    439 */
    440static int pontis_gpio_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
    441{
    442	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    443	uinfo->count = 1;
    444	uinfo->value.integer.min = 0;
    445	uinfo->value.integer.max = 0xffff; /* 16bit */
    446	return 0;
    447}
    448
    449static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    450{
    451	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    452	mutex_lock(&ice->gpio_mutex);
    453	/* 4-7 reserved */
    454	ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;
    455	mutex_unlock(&ice->gpio_mutex);
    456	return 0;
    457}
    458	
    459static int pontis_gpio_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    460{
    461	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    462	unsigned int val;
    463	int changed;
    464	mutex_lock(&ice->gpio_mutex);
    465	/* 4-7 reserved */
    466	val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0;
    467	changed = val != ice->gpio.write_mask;
    468	ice->gpio.write_mask = val;
    469	mutex_unlock(&ice->gpio_mutex);
    470	return changed;
    471}
    472
    473static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    474{
    475	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    476	mutex_lock(&ice->gpio_mutex);
    477	/* 4-7 reserved */
    478	ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;
    479	mutex_unlock(&ice->gpio_mutex);
    480	return 0;
    481}
    482	
    483static int pontis_gpio_dir_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    484{
    485	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    486	unsigned int val;
    487	int changed;
    488	mutex_lock(&ice->gpio_mutex);
    489	/* 4-7 reserved */
    490	val = ucontrol->value.integer.value[0] & 0xff0f;
    491	changed = (val != ice->gpio.direction);
    492	ice->gpio.direction = val;
    493	mutex_unlock(&ice->gpio_mutex);
    494	return changed;
    495}
    496
    497static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    498{
    499	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    500	mutex_lock(&ice->gpio_mutex);
    501	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
    502	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
    503	ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff;
    504	mutex_unlock(&ice->gpio_mutex);
    505	return 0;
    506}
    507
    508static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
    509{
    510	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
    511	unsigned int val, nval;
    512	int changed = 0;
    513	mutex_lock(&ice->gpio_mutex);
    514	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
    515	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
    516	val = snd_ice1712_gpio_read(ice) & 0xffff;
    517	nval = ucontrol->value.integer.value[0] & 0xffff;
    518	if (val != nval) {
    519		snd_ice1712_gpio_write(ice, nval);
    520		changed = 1;
    521	}
    522	mutex_unlock(&ice->gpio_mutex);
    523	return changed;
    524}
    525
    526static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1);
    527
    528/*
    529 * mixers
    530 */
    531
    532static const struct snd_kcontrol_new pontis_controls[] = {
    533	{
    534		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    535		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
    536			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
    537		.name = "PCM Playback Volume",
    538		.info = wm_dac_vol_info,
    539		.get = wm_dac_vol_get,
    540		.put = wm_dac_vol_put,
    541		.tlv = { .p = db_scale_volume },
    542	},
    543	{
    544		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    545		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
    546			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
    547		.name = "Capture Volume",
    548		.info = wm_adc_vol_info,
    549		.get = wm_adc_vol_get,
    550		.put = wm_adc_vol_put,
    551		.tlv = { .p = db_scale_volume },
    552	},
    553	{
    554		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    555		.name = "CD Capture Switch",
    556		.info = wm_adc_mux_info,
    557		.get = wm_adc_mux_get,
    558		.put = wm_adc_mux_put,
    559		.private_value = 0,
    560	},
    561	{
    562		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    563		.name = "Line Capture Switch",
    564		.info = wm_adc_mux_info,
    565		.get = wm_adc_mux_get,
    566		.put = wm_adc_mux_put,
    567		.private_value = 1,
    568	},
    569	{
    570		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    571		.name = "Analog Bypass Switch",
    572		.info = wm_bypass_info,
    573		.get = wm_bypass_get,
    574		.put = wm_bypass_put,
    575	},
    576	{
    577		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    578		.name = "Swap Output Channels",
    579		.info = wm_chswap_info,
    580		.get = wm_chswap_get,
    581		.put = wm_chswap_put,
    582	},
    583	{
    584		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
    585		.name = "IEC958 Input Source",
    586		.info = cs_source_info,
    587		.get = cs_source_get,
    588		.put = cs_source_put,
    589	},
    590	/* FIXME: which interface? */
    591	{
    592		.iface = SNDRV_CTL_ELEM_IFACE_CARD,
    593		.name = "GPIO Mask",
    594		.info = pontis_gpio_mask_info,
    595		.get = pontis_gpio_mask_get,
    596		.put = pontis_gpio_mask_put,
    597	},
    598	{
    599		.iface = SNDRV_CTL_ELEM_IFACE_CARD,
    600		.name = "GPIO Direction",
    601		.info = pontis_gpio_mask_info,
    602		.get = pontis_gpio_dir_get,
    603		.put = pontis_gpio_dir_put,
    604	},
    605	{
    606		.iface = SNDRV_CTL_ELEM_IFACE_CARD,
    607		.name = "GPIO Data",
    608		.info = pontis_gpio_mask_info,
    609		.get = pontis_gpio_data_get,
    610		.put = pontis_gpio_data_put,
    611	},
    612};
    613
    614
    615/*
    616 * WM codec registers
    617 */
    618static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
    619{
    620	struct snd_ice1712 *ice = entry->private_data;
    621	char line[64];
    622	unsigned int reg, val;
    623	mutex_lock(&ice->gpio_mutex);
    624	while (!snd_info_get_line(buffer, line, sizeof(line))) {
    625		if (sscanf(line, "%x %x", &reg, &val) != 2)
    626			continue;
    627		if (reg <= 0x17 && val <= 0xffff)
    628			wm_put(ice, reg, val);
    629	}
    630	mutex_unlock(&ice->gpio_mutex);
    631}
    632
    633static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
    634{
    635	struct snd_ice1712 *ice = entry->private_data;
    636	int reg, val;
    637
    638	mutex_lock(&ice->gpio_mutex);
    639	for (reg = 0; reg <= 0x17; reg++) {
    640		val = wm_get(ice, reg);
    641		snd_iprintf(buffer, "%02x = %04x\n", reg, val);
    642	}
    643	mutex_unlock(&ice->gpio_mutex);
    644}
    645
    646static void wm_proc_init(struct snd_ice1712 *ice)
    647{
    648	snd_card_rw_proc_new(ice->card, "wm_codec", ice, wm_proc_regs_read,
    649			     wm_proc_regs_write);
    650}
    651
    652static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
    653{
    654	struct snd_ice1712 *ice = entry->private_data;
    655	int reg, val;
    656
    657	mutex_lock(&ice->gpio_mutex);
    658	for (reg = 0; reg <= 0x26; reg++) {
    659		val = spi_read(ice, CS_DEV, reg);
    660		snd_iprintf(buffer, "%02x = %02x\n", reg, val);
    661	}
    662	val = spi_read(ice, CS_DEV, 0x7f);
    663	snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val);
    664	mutex_unlock(&ice->gpio_mutex);
    665}
    666
    667static void cs_proc_init(struct snd_ice1712 *ice)
    668{
    669	snd_card_ro_proc_new(ice->card, "cs_codec", ice, cs_proc_regs_read);
    670}
    671
    672
    673static int pontis_add_controls(struct snd_ice1712 *ice)
    674{
    675	unsigned int i;
    676	int err;
    677
    678	for (i = 0; i < ARRAY_SIZE(pontis_controls); i++) {
    679		err = snd_ctl_add(ice->card, snd_ctl_new1(&pontis_controls[i], ice));
    680		if (err < 0)
    681			return err;
    682	}
    683
    684	wm_proc_init(ice);
    685	cs_proc_init(ice);
    686
    687	return 0;
    688}
    689
    690
    691/*
    692 * initialize the chip
    693 */
    694static int pontis_init(struct snd_ice1712 *ice)
    695{
    696	static const unsigned short wm_inits[] = {
    697		/* These come first to reduce init pop noise */
    698		WM_ADC_MUX,	0x00c0,	/* ADC mute */
    699		WM_DAC_MUTE,	0x0001,	/* DAC softmute */
    700		WM_DAC_CTRL1,	0x0000,	/* DAC mute */
    701
    702		WM_POWERDOWN,	0x0008,	/* All power-up except HP */
    703		WM_RESET,	0x0000,	/* reset */
    704	};
    705	static const unsigned short wm_inits2[] = {
    706		WM_MASTER_CTRL,	0x0022,	/* 256fs, slave mode */
    707		WM_DAC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
    708		WM_ADC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
    709		WM_DAC_CTRL1,	0x0090,	/* DAC L/R */
    710		WM_OUT_MUX,	0x0001,	/* OUT DAC */
    711		WM_HP_ATTEN_L,	0x0179,	/* HP 0dB */
    712		WM_HP_ATTEN_R,	0x0179,	/* HP 0dB */
    713		WM_DAC_ATTEN_L,	0x0000,	/* DAC 0dB */
    714		WM_DAC_ATTEN_L,	0x0100,	/* DAC 0dB */
    715		WM_DAC_ATTEN_R,	0x0000,	/* DAC 0dB */
    716		WM_DAC_ATTEN_R,	0x0100,	/* DAC 0dB */
    717		/* WM_DAC_MASTER,	0x0100, */	/* DAC master muted */
    718		WM_PHASE_SWAP,	0x0000,	/* phase normal */
    719		WM_DAC_CTRL2,	0x0000,	/* no deemphasis, no ZFLG */
    720		WM_ADC_ATTEN_L,	0x0000,	/* ADC muted */
    721		WM_ADC_ATTEN_R,	0x0000,	/* ADC muted */
    722#if 0
    723		WM_ALC_CTRL1,	0x007b,	/* */
    724		WM_ALC_CTRL2,	0x0000,	/* */
    725		WM_ALC_CTRL3,	0x0000,	/* */
    726		WM_NOISE_GATE,	0x0000,	/* */
    727#endif
    728		WM_DAC_MUTE,	0x0000,	/* DAC unmute */
    729		WM_ADC_MUX,	0x0003,	/* ADC unmute, both CD/Line On */
    730	};
    731	static const unsigned char cs_inits[] = {
    732		0x04,	0x80,	/* RUN, RXP0 */
    733		0x05,	0x05,	/* slave, 24bit */
    734		0x01,	0x00,
    735		0x02,	0x00,
    736		0x03,	0x00,
    737	};
    738	unsigned int i;
    739
    740	ice->vt1720 = 1;
    741	ice->num_total_dacs = 2;
    742	ice->num_total_adcs = 2;
    743
    744	/* to remember the register values */
    745	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
    746	if (! ice->akm)
    747		return -ENOMEM;
    748	ice->akm_codecs = 1;
    749
    750	/* HACK - use this as the SPDIF source.
    751	 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
    752	 */
    753	ice->gpio.saved[0] = 0;
    754
    755	/* initialize WM8776 codec */
    756	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
    757		wm_put(ice, wm_inits[i], wm_inits[i+1]);
    758	schedule_timeout_uninterruptible(1);
    759	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
    760		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
    761
    762	/* initialize CS8416 codec */
    763	/* assert PRST#; MT05 bit 7 */
    764	outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
    765	mdelay(5);
    766	/* deassert PRST# */
    767	outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
    768
    769	for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)
    770		spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);
    771
    772	return 0;
    773}
    774
    775
    776/*
    777 * Pontis boards don't provide the EEPROM data at all.
    778 * hence the driver needs to sets up it properly.
    779 */
    780
    781static const unsigned char pontis_eeprom[] = {
    782	[ICE_EEP2_SYSCONF]     = 0x08,	/* clock 256, mpu401, spdif-in/ADC, 1DAC */
    783	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
    784	[ICE_EEP2_I2S]         = 0xf8,	/* vol, 96k, 24bit, 192k */
    785	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
    786	[ICE_EEP2_GPIO_DIR]    = 0x07,
    787	[ICE_EEP2_GPIO_DIR1]   = 0x00,
    788	[ICE_EEP2_GPIO_DIR2]   = 0x00,	/* ignored */
    789	[ICE_EEP2_GPIO_MASK]   = 0x0f,	/* 4-7 reserved for CS8416 */
    790	[ICE_EEP2_GPIO_MASK1]  = 0xff,
    791	[ICE_EEP2_GPIO_MASK2]  = 0x00,	/* ignored */
    792	[ICE_EEP2_GPIO_STATE]  = 0x06,	/* 0-low, 1-high, 2-high */
    793	[ICE_EEP2_GPIO_STATE1] = 0x00,
    794	[ICE_EEP2_GPIO_STATE2] = 0x00,	/* ignored */
    795};
    796
    797/* entry point */
    798struct snd_ice1712_card_info snd_vt1720_pontis_cards[] = {
    799	{
    800		.subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
    801		.name = "Pontis MS300",
    802		.model = "ms300",
    803		.chip_init = pontis_init,
    804		.build_controls = pontis_add_controls,
    805		.eeprom_size = sizeof(pontis_eeprom),
    806		.eeprom_data = pontis_eeprom,
    807	},
    808	{ } /* terminator */
    809};