162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * ALSA driver for ICEnsemble VT1724 (Envy24HT) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Lowlevel functions for ONKYO WAVIO SE-90PCI and SE-200PCI 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (c) 2007 Shin-ya Okada sh_okada(at)d4.dion.ne.jp 862306a36Sopenharmony_ci * (at) -> @ 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/delay.h> 1262306a36Sopenharmony_ci#include <linux/interrupt.h> 1362306a36Sopenharmony_ci#include <linux/init.h> 1462306a36Sopenharmony_ci#include <linux/slab.h> 1562306a36Sopenharmony_ci#include <sound/core.h> 1662306a36Sopenharmony_ci#include <sound/tlv.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include "ice1712.h" 1962306a36Sopenharmony_ci#include "envy24ht.h" 2062306a36Sopenharmony_ci#include "se.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistruct se_spec { 2362306a36Sopenharmony_ci struct { 2462306a36Sopenharmony_ci unsigned char ch1, ch2; 2562306a36Sopenharmony_ci } vol[8]; 2662306a36Sopenharmony_ci}; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/****************************************************************************/ 2962306a36Sopenharmony_ci/* ONKYO WAVIO SE-200PCI */ 3062306a36Sopenharmony_ci/****************************************************************************/ 3162306a36Sopenharmony_ci/* 3262306a36Sopenharmony_ci * system configuration ICE_EEP2_SYSCONF=0x4b 3362306a36Sopenharmony_ci * XIN1 49.152MHz 3462306a36Sopenharmony_ci * not have UART 3562306a36Sopenharmony_ci * one stereo ADC and a S/PDIF receiver connected 3662306a36Sopenharmony_ci * four stereo DACs connected 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * AC-Link configuration ICE_EEP2_ACLINK=0x80 3962306a36Sopenharmony_ci * use I2C, not use AC97 4062306a36Sopenharmony_ci * 4162306a36Sopenharmony_ci * I2S converters feature ICE_EEP2_I2S=0x78 4262306a36Sopenharmony_ci * I2S codec has no volume/mute control feature 4362306a36Sopenharmony_ci * I2S codec supports 96KHz and 192KHz 4462306a36Sopenharmony_ci * I2S codec 24bits 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * S/PDIF configuration ICE_EEP2_SPDIF=0xc3 4762306a36Sopenharmony_ci * Enable integrated S/PDIF transmitter 4862306a36Sopenharmony_ci * internal S/PDIF out implemented 4962306a36Sopenharmony_ci * S/PDIF is stereo 5062306a36Sopenharmony_ci * External S/PDIF out implemented 5162306a36Sopenharmony_ci * 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * ** connected chips ** 5462306a36Sopenharmony_ci * 5562306a36Sopenharmony_ci * WM8740 5662306a36Sopenharmony_ci * A 2ch-DAC of main outputs. 5762306a36Sopenharmony_ci * It setuped as I2S mode by wire, so no way to setup from software. 5862306a36Sopenharmony_ci * The sample-rate are automatically changed. 5962306a36Sopenharmony_ci * ML/I2S (28pin) --------+ 6062306a36Sopenharmony_ci * MC/DM1 (27pin) -- 5V | 6162306a36Sopenharmony_ci * MD/DM0 (26pin) -- GND | 6262306a36Sopenharmony_ci * MUTEB (25pin) -- NC | 6362306a36Sopenharmony_ci * MODE (24pin) -- GND | 6462306a36Sopenharmony_ci * CSBIW (23pin) --------+ 6562306a36Sopenharmony_ci * | 6662306a36Sopenharmony_ci * RSTB (22pin) --R(1K)-+ 6762306a36Sopenharmony_ci * Probably it reduce the noise from the control line. 6862306a36Sopenharmony_ci * 6962306a36Sopenharmony_ci * WM8766 7062306a36Sopenharmony_ci * A 6ch-DAC for surrounds. 7162306a36Sopenharmony_ci * It's control wire was connected to GPIOxx (3-wire serial interface) 7262306a36Sopenharmony_ci * ML/I2S (11pin) -- GPIO18 7362306a36Sopenharmony_ci * MC/IWL (12pin) -- GPIO17 7462306a36Sopenharmony_ci * MD/DM (13pin) -- GPIO16 7562306a36Sopenharmony_ci * MUTE (14pin) -- GPIO01 7662306a36Sopenharmony_ci * 7762306a36Sopenharmony_ci * WM8776 7862306a36Sopenharmony_ci * A 2ch-ADC(with 10ch-selector) plus 2ch-DAC. 7962306a36Sopenharmony_ci * It's control wire was connected to SDA/SCLK (2-wire serial interface) 8062306a36Sopenharmony_ci * MODE (16pin) -- R(1K) -- GND 8162306a36Sopenharmony_ci * CE (17pin) -- R(1K) -- GND 2-wire mode (address=0x34) 8262306a36Sopenharmony_ci * DI (18pin) -- SDA 8362306a36Sopenharmony_ci * CL (19pin) -- SCLK 8462306a36Sopenharmony_ci * 8562306a36Sopenharmony_ci * 8662306a36Sopenharmony_ci * ** output pins and device names ** 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * 7.1ch name -- output connector color -- device (-D option) 8962306a36Sopenharmony_ci * 9062306a36Sopenharmony_ci * FRONT 2ch -- green -- plughw:0,0 9162306a36Sopenharmony_ci * CENTER(Lch) SUBWOOFER(Rch) -- black -- plughw:0,2,0 9262306a36Sopenharmony_ci * SURROUND 2ch -- orange -- plughw:0,2,1 9362306a36Sopenharmony_ci * SURROUND BACK 2ch -- white -- plughw:0,2,2 9462306a36Sopenharmony_ci * 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci/****************************************************************************/ 9962306a36Sopenharmony_ci/* WM8740 interface */ 10062306a36Sopenharmony_ci/****************************************************************************/ 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic void se200pci_WM8740_init(struct snd_ice1712 *ice) 10362306a36Sopenharmony_ci{ 10462306a36Sopenharmony_ci /* nothing to do */ 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic void se200pci_WM8740_set_pro_rate(struct snd_ice1712 *ice, 10962306a36Sopenharmony_ci unsigned int rate) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci /* nothing to do */ 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/****************************************************************************/ 11662306a36Sopenharmony_ci/* WM8766 interface */ 11762306a36Sopenharmony_ci/****************************************************************************/ 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistatic void se200pci_WM8766_write(struct snd_ice1712 *ice, 12062306a36Sopenharmony_ci unsigned int addr, unsigned int data) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci unsigned int st; 12362306a36Sopenharmony_ci unsigned int bits; 12462306a36Sopenharmony_ci int i; 12562306a36Sopenharmony_ci const unsigned int DATA = 0x010000; 12662306a36Sopenharmony_ci const unsigned int CLOCK = 0x020000; 12762306a36Sopenharmony_ci const unsigned int LOAD = 0x040000; 12862306a36Sopenharmony_ci const unsigned int ALL_MASK = (DATA | CLOCK | LOAD); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci snd_ice1712_save_gpio_status(ice); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci st = ((addr & 0x7f) << 9) | (data & 0x1ff); 13362306a36Sopenharmony_ci snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | ALL_MASK); 13462306a36Sopenharmony_ci snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~ALL_MASK); 13562306a36Sopenharmony_ci bits = snd_ice1712_gpio_read(ice) & ~ALL_MASK; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci snd_ice1712_gpio_write(ice, bits); 13862306a36Sopenharmony_ci for (i = 0; i < 16; i++) { 13962306a36Sopenharmony_ci udelay(1); 14062306a36Sopenharmony_ci bits &= ~CLOCK; 14162306a36Sopenharmony_ci st = (st << 1); 14262306a36Sopenharmony_ci if (st & 0x10000) 14362306a36Sopenharmony_ci bits |= DATA; 14462306a36Sopenharmony_ci else 14562306a36Sopenharmony_ci bits &= ~DATA; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci snd_ice1712_gpio_write(ice, bits); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci udelay(1); 15062306a36Sopenharmony_ci bits |= CLOCK; 15162306a36Sopenharmony_ci snd_ice1712_gpio_write(ice, bits); 15262306a36Sopenharmony_ci } 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci udelay(1); 15562306a36Sopenharmony_ci bits |= LOAD; 15662306a36Sopenharmony_ci snd_ice1712_gpio_write(ice, bits); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci udelay(1); 15962306a36Sopenharmony_ci bits |= (DATA | CLOCK); 16062306a36Sopenharmony_ci snd_ice1712_gpio_write(ice, bits); 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci snd_ice1712_restore_gpio_status(ice); 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch, 16662306a36Sopenharmony_ci unsigned int vol1, unsigned int vol2) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci switch (ch) { 16962306a36Sopenharmony_ci case 0: 17062306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x000, vol1); 17162306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x001, vol2 | 0x100); 17262306a36Sopenharmony_ci break; 17362306a36Sopenharmony_ci case 1: 17462306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x004, vol1); 17562306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x005, vol2 | 0x100); 17662306a36Sopenharmony_ci break; 17762306a36Sopenharmony_ci case 2: 17862306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x006, vol1); 17962306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x007, vol2 | 0x100); 18062306a36Sopenharmony_ci break; 18162306a36Sopenharmony_ci } 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_cistatic void se200pci_WM8766_init(struct snd_ice1712 *ice) 18562306a36Sopenharmony_ci{ 18662306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */ 18762306a36Sopenharmony_ci udelay(10); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci se200pci_WM8766_set_volume(ice, 0, 0, 0); /* volume L=0 R=0 */ 19062306a36Sopenharmony_ci se200pci_WM8766_set_volume(ice, 1, 0, 0); /* volume L=0 R=0 */ 19162306a36Sopenharmony_ci se200pci_WM8766_set_volume(ice, 2, 0, 0); /* volume L=0 R=0 */ 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x03, 0x022); /* serial mode I2S-24bits */ 19462306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */ 19562306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x12, 0x000); /* MDP=0 */ 19662306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x15, 0x000); /* MDP=0 */ 19762306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x09, 0x000); /* demp=off mute=off */ 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x02, 0x124); /* ch-assign L=L R=R RESET */ 20062306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x02, 0x120); /* ch-assign L=L R=R */ 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistatic void se200pci_WM8766_set_pro_rate(struct snd_ice1712 *ice, 20462306a36Sopenharmony_ci unsigned int rate) 20562306a36Sopenharmony_ci{ 20662306a36Sopenharmony_ci if (rate > 96000) 20762306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x0a, 0x000); /* MCLK=128fs */ 20862306a36Sopenharmony_ci else 20962306a36Sopenharmony_ci se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */ 21062306a36Sopenharmony_ci} 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci/****************************************************************************/ 21462306a36Sopenharmony_ci/* WM8776 interface */ 21562306a36Sopenharmony_ci/****************************************************************************/ 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_cistatic void se200pci_WM8776_write(struct snd_ice1712 *ice, 21862306a36Sopenharmony_ci unsigned int addr, unsigned int data) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci unsigned int val; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci val = (addr << 9) | data; 22362306a36Sopenharmony_ci snd_vt1724_write_i2c(ice, 0x34, val >> 8, val & 0xff); 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_cistatic void se200pci_WM8776_set_output_volume(struct snd_ice1712 *ice, 22862306a36Sopenharmony_ci unsigned int vol1, unsigned int vol2) 22962306a36Sopenharmony_ci{ 23062306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x03, vol1); 23162306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x04, vol2 | 0x100); 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice, 23562306a36Sopenharmony_ci unsigned int vol1, unsigned int vol2) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x0e, vol1); 23862306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100); 23962306a36Sopenharmony_ci} 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_cistatic const char * const se200pci_sel[] = { 24262306a36Sopenharmony_ci "LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL 24362306a36Sopenharmony_ci}; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cistatic void se200pci_WM8776_set_input_selector(struct snd_ice1712 *ice, 24662306a36Sopenharmony_ci unsigned int sel) 24762306a36Sopenharmony_ci{ 24862306a36Sopenharmony_ci static const unsigned char vals[] = { 24962306a36Sopenharmony_ci /* LINE, CD, MIC, ALL, GND */ 25062306a36Sopenharmony_ci 0x10, 0x04, 0x08, 0x1c, 0x03 25162306a36Sopenharmony_ci }; 25262306a36Sopenharmony_ci if (sel > 4) 25362306a36Sopenharmony_ci sel = 4; 25462306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x15, vals[sel]); 25562306a36Sopenharmony_ci} 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistatic void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl) 25862306a36Sopenharmony_ci{ 25962306a36Sopenharmony_ci /* AFL -- After Fader Listening */ 26062306a36Sopenharmony_ci if (afl) 26162306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x16, 0x005); 26262306a36Sopenharmony_ci else 26362306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x16, 0x001); 26462306a36Sopenharmony_ci} 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic const char * const se200pci_agc[] = { 26762306a36Sopenharmony_ci "Off", "LimiterMode", "ALCMode", NULL 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc) 27162306a36Sopenharmony_ci{ 27262306a36Sopenharmony_ci /* AGC -- Auto Gain Control of the input */ 27362306a36Sopenharmony_ci switch (agc) { 27462306a36Sopenharmony_ci case 0: 27562306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x11, 0x000); /* Off */ 27662306a36Sopenharmony_ci break; 27762306a36Sopenharmony_ci case 1: 27862306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x10, 0x07b); 27962306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x11, 0x100); /* LimiterMode */ 28062306a36Sopenharmony_ci break; 28162306a36Sopenharmony_ci case 2: 28262306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x10, 0x1fb); 28362306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x11, 0x100); /* ALCMode */ 28462306a36Sopenharmony_ci break; 28562306a36Sopenharmony_ci } 28662306a36Sopenharmony_ci} 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_cistatic void se200pci_WM8776_init(struct snd_ice1712 *ice) 28962306a36Sopenharmony_ci{ 29062306a36Sopenharmony_ci int i; 29162306a36Sopenharmony_ci static const unsigned short default_values[] = { 29262306a36Sopenharmony_ci 0x100, 0x100, 0x100, 29362306a36Sopenharmony_ci 0x100, 0x100, 0x100, 29462306a36Sopenharmony_ci 0x000, 0x090, 0x000, 0x000, 29562306a36Sopenharmony_ci 0x022, 0x022, 0x022, 29662306a36Sopenharmony_ci 0x008, 0x0cf, 0x0cf, 0x07b, 0x000, 29762306a36Sopenharmony_ci 0x032, 0x000, 0x0a6, 0x001, 0x001 29862306a36Sopenharmony_ci }; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x17, 0x000); /* reset all */ 30162306a36Sopenharmony_ci /* ADC and DAC interface is I2S 24bits mode */ 30262306a36Sopenharmony_ci /* The sample-rate are automatically changed */ 30362306a36Sopenharmony_ci udelay(10); 30462306a36Sopenharmony_ci /* BUT my board can not do reset all, so I load all by manually. */ 30562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(default_values); i++) 30662306a36Sopenharmony_ci se200pci_WM8776_write(ice, i, default_values[i]); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci se200pci_WM8776_set_input_selector(ice, 0); 30962306a36Sopenharmony_ci se200pci_WM8776_set_afl(ice, 0); 31062306a36Sopenharmony_ci se200pci_WM8776_set_agc(ice, 0); 31162306a36Sopenharmony_ci se200pci_WM8776_set_input_volume(ice, 0, 0); 31262306a36Sopenharmony_ci se200pci_WM8776_set_output_volume(ice, 0, 0); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci /* head phone mute and power down */ 31562306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x00, 0); 31662306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x01, 0); 31762306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x02, 0x100); 31862306a36Sopenharmony_ci se200pci_WM8776_write(ice, 0x0d, 0x080); 31962306a36Sopenharmony_ci} 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_cistatic void se200pci_WM8776_set_pro_rate(struct snd_ice1712 *ice, 32262306a36Sopenharmony_ci unsigned int rate) 32362306a36Sopenharmony_ci{ 32462306a36Sopenharmony_ci /* nothing to do */ 32562306a36Sopenharmony_ci} 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci/****************************************************************************/ 32962306a36Sopenharmony_ci/* runtime interface */ 33062306a36Sopenharmony_ci/****************************************************************************/ 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_cistatic void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate) 33362306a36Sopenharmony_ci{ 33462306a36Sopenharmony_ci se200pci_WM8740_set_pro_rate(ice, rate); 33562306a36Sopenharmony_ci se200pci_WM8766_set_pro_rate(ice, rate); 33662306a36Sopenharmony_ci se200pci_WM8776_set_pro_rate(ice, rate); 33762306a36Sopenharmony_ci} 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_cistruct se200pci_control { 34062306a36Sopenharmony_ci const char *name; 34162306a36Sopenharmony_ci enum { 34262306a36Sopenharmony_ci WM8766, 34362306a36Sopenharmony_ci WM8776in, 34462306a36Sopenharmony_ci WM8776out, 34562306a36Sopenharmony_ci WM8776sel, 34662306a36Sopenharmony_ci WM8776agc, 34762306a36Sopenharmony_ci WM8776afl 34862306a36Sopenharmony_ci } target; 34962306a36Sopenharmony_ci enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type; 35062306a36Sopenharmony_ci int ch; 35162306a36Sopenharmony_ci const char * const *member; 35262306a36Sopenharmony_ci const char *comment; 35362306a36Sopenharmony_ci}; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_cistatic const struct se200pci_control se200pci_cont[] = { 35662306a36Sopenharmony_ci { 35762306a36Sopenharmony_ci .name = "Front Playback Volume", 35862306a36Sopenharmony_ci .target = WM8776out, 35962306a36Sopenharmony_ci .type = VOLUME1, 36062306a36Sopenharmony_ci .comment = "Front(green)" 36162306a36Sopenharmony_ci }, 36262306a36Sopenharmony_ci { 36362306a36Sopenharmony_ci .name = "Side Playback Volume", 36462306a36Sopenharmony_ci .target = WM8766, 36562306a36Sopenharmony_ci .type = VOLUME1, 36662306a36Sopenharmony_ci .ch = 1, 36762306a36Sopenharmony_ci .comment = "Surround(orange)" 36862306a36Sopenharmony_ci }, 36962306a36Sopenharmony_ci { 37062306a36Sopenharmony_ci .name = "Surround Playback Volume", 37162306a36Sopenharmony_ci .target = WM8766, 37262306a36Sopenharmony_ci .type = VOLUME1, 37362306a36Sopenharmony_ci .ch = 2, 37462306a36Sopenharmony_ci .comment = "SurroundBack(white)" 37562306a36Sopenharmony_ci }, 37662306a36Sopenharmony_ci { 37762306a36Sopenharmony_ci .name = "CLFE Playback Volume", 37862306a36Sopenharmony_ci .target = WM8766, 37962306a36Sopenharmony_ci .type = VOLUME1, 38062306a36Sopenharmony_ci .ch = 0, 38162306a36Sopenharmony_ci .comment = "Center(Lch)&SubWoofer(Rch)(black)" 38262306a36Sopenharmony_ci }, 38362306a36Sopenharmony_ci { 38462306a36Sopenharmony_ci .name = "Capture Volume", 38562306a36Sopenharmony_ci .target = WM8776in, 38662306a36Sopenharmony_ci .type = VOLUME2 38762306a36Sopenharmony_ci }, 38862306a36Sopenharmony_ci { 38962306a36Sopenharmony_ci .name = "Capture Select", 39062306a36Sopenharmony_ci .target = WM8776sel, 39162306a36Sopenharmony_ci .type = ENUM, 39262306a36Sopenharmony_ci .member = se200pci_sel 39362306a36Sopenharmony_ci }, 39462306a36Sopenharmony_ci { 39562306a36Sopenharmony_ci .name = "AGC Capture Mode", 39662306a36Sopenharmony_ci .target = WM8776agc, 39762306a36Sopenharmony_ci .type = ENUM, 39862306a36Sopenharmony_ci .member = se200pci_agc 39962306a36Sopenharmony_ci }, 40062306a36Sopenharmony_ci { 40162306a36Sopenharmony_ci .name = "AFL Bypass Playback Switch", 40262306a36Sopenharmony_ci .target = WM8776afl, 40362306a36Sopenharmony_ci .type = BOOLEAN 40462306a36Sopenharmony_ci } 40562306a36Sopenharmony_ci}; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_cistatic int se200pci_get_enum_count(int n) 40862306a36Sopenharmony_ci{ 40962306a36Sopenharmony_ci const char * const *member; 41062306a36Sopenharmony_ci int c; 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci member = se200pci_cont[n].member; 41362306a36Sopenharmony_ci if (!member) 41462306a36Sopenharmony_ci return 0; 41562306a36Sopenharmony_ci for (c = 0; member[c]; c++) 41662306a36Sopenharmony_ci ; 41762306a36Sopenharmony_ci return c; 41862306a36Sopenharmony_ci} 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_cistatic int se200pci_cont_volume_info(struct snd_kcontrol *kc, 42162306a36Sopenharmony_ci struct snd_ctl_elem_info *uinfo) 42262306a36Sopenharmony_ci{ 42362306a36Sopenharmony_ci uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 42462306a36Sopenharmony_ci uinfo->count = 2; 42562306a36Sopenharmony_ci uinfo->value.integer.min = 0; /* mute */ 42662306a36Sopenharmony_ci uinfo->value.integer.max = 0xff; /* 0dB */ 42762306a36Sopenharmony_ci return 0; 42862306a36Sopenharmony_ci} 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci#define se200pci_cont_boolean_info snd_ctl_boolean_mono_info 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_cistatic int se200pci_cont_enum_info(struct snd_kcontrol *kc, 43362306a36Sopenharmony_ci struct snd_ctl_elem_info *uinfo) 43462306a36Sopenharmony_ci{ 43562306a36Sopenharmony_ci int n, c; 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci n = kc->private_value; 43862306a36Sopenharmony_ci c = se200pci_get_enum_count(n); 43962306a36Sopenharmony_ci if (!c) 44062306a36Sopenharmony_ci return -EINVAL; 44162306a36Sopenharmony_ci return snd_ctl_enum_info(uinfo, 1, c, se200pci_cont[n].member); 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_cistatic int se200pci_cont_volume_get(struct snd_kcontrol *kc, 44562306a36Sopenharmony_ci struct snd_ctl_elem_value *uc) 44662306a36Sopenharmony_ci{ 44762306a36Sopenharmony_ci struct snd_ice1712 *ice = snd_kcontrol_chip(kc); 44862306a36Sopenharmony_ci struct se_spec *spec = ice->spec; 44962306a36Sopenharmony_ci int n = kc->private_value; 45062306a36Sopenharmony_ci uc->value.integer.value[0] = spec->vol[n].ch1; 45162306a36Sopenharmony_ci uc->value.integer.value[1] = spec->vol[n].ch2; 45262306a36Sopenharmony_ci return 0; 45362306a36Sopenharmony_ci} 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_cistatic int se200pci_cont_boolean_get(struct snd_kcontrol *kc, 45662306a36Sopenharmony_ci struct snd_ctl_elem_value *uc) 45762306a36Sopenharmony_ci{ 45862306a36Sopenharmony_ci struct snd_ice1712 *ice = snd_kcontrol_chip(kc); 45962306a36Sopenharmony_ci struct se_spec *spec = ice->spec; 46062306a36Sopenharmony_ci int n = kc->private_value; 46162306a36Sopenharmony_ci uc->value.integer.value[0] = spec->vol[n].ch1; 46262306a36Sopenharmony_ci return 0; 46362306a36Sopenharmony_ci} 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_cistatic int se200pci_cont_enum_get(struct snd_kcontrol *kc, 46662306a36Sopenharmony_ci struct snd_ctl_elem_value *uc) 46762306a36Sopenharmony_ci{ 46862306a36Sopenharmony_ci struct snd_ice1712 *ice = snd_kcontrol_chip(kc); 46962306a36Sopenharmony_ci struct se_spec *spec = ice->spec; 47062306a36Sopenharmony_ci int n = kc->private_value; 47162306a36Sopenharmony_ci uc->value.enumerated.item[0] = spec->vol[n].ch1; 47262306a36Sopenharmony_ci return 0; 47362306a36Sopenharmony_ci} 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_cistatic void se200pci_cont_update(struct snd_ice1712 *ice, int n) 47662306a36Sopenharmony_ci{ 47762306a36Sopenharmony_ci struct se_spec *spec = ice->spec; 47862306a36Sopenharmony_ci switch (se200pci_cont[n].target) { 47962306a36Sopenharmony_ci case WM8766: 48062306a36Sopenharmony_ci se200pci_WM8766_set_volume(ice, 48162306a36Sopenharmony_ci se200pci_cont[n].ch, 48262306a36Sopenharmony_ci spec->vol[n].ch1, 48362306a36Sopenharmony_ci spec->vol[n].ch2); 48462306a36Sopenharmony_ci break; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci case WM8776in: 48762306a36Sopenharmony_ci se200pci_WM8776_set_input_volume(ice, 48862306a36Sopenharmony_ci spec->vol[n].ch1, 48962306a36Sopenharmony_ci spec->vol[n].ch2); 49062306a36Sopenharmony_ci break; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci case WM8776out: 49362306a36Sopenharmony_ci se200pci_WM8776_set_output_volume(ice, 49462306a36Sopenharmony_ci spec->vol[n].ch1, 49562306a36Sopenharmony_ci spec->vol[n].ch2); 49662306a36Sopenharmony_ci break; 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci case WM8776sel: 49962306a36Sopenharmony_ci se200pci_WM8776_set_input_selector(ice, 50062306a36Sopenharmony_ci spec->vol[n].ch1); 50162306a36Sopenharmony_ci break; 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci case WM8776agc: 50462306a36Sopenharmony_ci se200pci_WM8776_set_agc(ice, spec->vol[n].ch1); 50562306a36Sopenharmony_ci break; 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ci case WM8776afl: 50862306a36Sopenharmony_ci se200pci_WM8776_set_afl(ice, spec->vol[n].ch1); 50962306a36Sopenharmony_ci break; 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci default: 51262306a36Sopenharmony_ci break; 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci} 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cistatic int se200pci_cont_volume_put(struct snd_kcontrol *kc, 51762306a36Sopenharmony_ci struct snd_ctl_elem_value *uc) 51862306a36Sopenharmony_ci{ 51962306a36Sopenharmony_ci struct snd_ice1712 *ice = snd_kcontrol_chip(kc); 52062306a36Sopenharmony_ci struct se_spec *spec = ice->spec; 52162306a36Sopenharmony_ci int n = kc->private_value; 52262306a36Sopenharmony_ci unsigned int vol1, vol2; 52362306a36Sopenharmony_ci int changed; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci changed = 0; 52662306a36Sopenharmony_ci vol1 = uc->value.integer.value[0] & 0xff; 52762306a36Sopenharmony_ci vol2 = uc->value.integer.value[1] & 0xff; 52862306a36Sopenharmony_ci if (spec->vol[n].ch1 != vol1) { 52962306a36Sopenharmony_ci spec->vol[n].ch1 = vol1; 53062306a36Sopenharmony_ci changed = 1; 53162306a36Sopenharmony_ci } 53262306a36Sopenharmony_ci if (spec->vol[n].ch2 != vol2) { 53362306a36Sopenharmony_ci spec->vol[n].ch2 = vol2; 53462306a36Sopenharmony_ci changed = 1; 53562306a36Sopenharmony_ci } 53662306a36Sopenharmony_ci if (changed) 53762306a36Sopenharmony_ci se200pci_cont_update(ice, n); 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci return changed; 54062306a36Sopenharmony_ci} 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_cistatic int se200pci_cont_boolean_put(struct snd_kcontrol *kc, 54362306a36Sopenharmony_ci struct snd_ctl_elem_value *uc) 54462306a36Sopenharmony_ci{ 54562306a36Sopenharmony_ci struct snd_ice1712 *ice = snd_kcontrol_chip(kc); 54662306a36Sopenharmony_ci struct se_spec *spec = ice->spec; 54762306a36Sopenharmony_ci int n = kc->private_value; 54862306a36Sopenharmony_ci unsigned int vol1; 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci vol1 = !!uc->value.integer.value[0]; 55162306a36Sopenharmony_ci if (spec->vol[n].ch1 != vol1) { 55262306a36Sopenharmony_ci spec->vol[n].ch1 = vol1; 55362306a36Sopenharmony_ci se200pci_cont_update(ice, n); 55462306a36Sopenharmony_ci return 1; 55562306a36Sopenharmony_ci } 55662306a36Sopenharmony_ci return 0; 55762306a36Sopenharmony_ci} 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_cistatic int se200pci_cont_enum_put(struct snd_kcontrol *kc, 56062306a36Sopenharmony_ci struct snd_ctl_elem_value *uc) 56162306a36Sopenharmony_ci{ 56262306a36Sopenharmony_ci struct snd_ice1712 *ice = snd_kcontrol_chip(kc); 56362306a36Sopenharmony_ci struct se_spec *spec = ice->spec; 56462306a36Sopenharmony_ci int n = kc->private_value; 56562306a36Sopenharmony_ci unsigned int vol1; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci vol1 = uc->value.enumerated.item[0]; 56862306a36Sopenharmony_ci if (vol1 >= se200pci_get_enum_count(n)) 56962306a36Sopenharmony_ci return -EINVAL; 57062306a36Sopenharmony_ci if (spec->vol[n].ch1 != vol1) { 57162306a36Sopenharmony_ci spec->vol[n].ch1 = vol1; 57262306a36Sopenharmony_ci se200pci_cont_update(ice, n); 57362306a36Sopenharmony_ci return 1; 57462306a36Sopenharmony_ci } 57562306a36Sopenharmony_ci return 0; 57662306a36Sopenharmony_ci} 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1); 57962306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1); 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_cistatic int se200pci_add_controls(struct snd_ice1712 *ice) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci int i; 58462306a36Sopenharmony_ci struct snd_kcontrol_new cont; 58562306a36Sopenharmony_ci int err; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci memset(&cont, 0, sizeof(cont)); 58862306a36Sopenharmony_ci cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 58962306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(se200pci_cont); i++) { 59062306a36Sopenharmony_ci cont.private_value = i; 59162306a36Sopenharmony_ci cont.name = se200pci_cont[i].name; 59262306a36Sopenharmony_ci cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 59362306a36Sopenharmony_ci cont.tlv.p = NULL; 59462306a36Sopenharmony_ci switch (se200pci_cont[i].type) { 59562306a36Sopenharmony_ci case VOLUME1: 59662306a36Sopenharmony_ci case VOLUME2: 59762306a36Sopenharmony_ci cont.info = se200pci_cont_volume_info; 59862306a36Sopenharmony_ci cont.get = se200pci_cont_volume_get; 59962306a36Sopenharmony_ci cont.put = se200pci_cont_volume_put; 60062306a36Sopenharmony_ci cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 60162306a36Sopenharmony_ci if (se200pci_cont[i].type == VOLUME1) 60262306a36Sopenharmony_ci cont.tlv.p = db_scale_gain1; 60362306a36Sopenharmony_ci else 60462306a36Sopenharmony_ci cont.tlv.p = db_scale_gain2; 60562306a36Sopenharmony_ci break; 60662306a36Sopenharmony_ci case BOOLEAN: 60762306a36Sopenharmony_ci cont.info = se200pci_cont_boolean_info; 60862306a36Sopenharmony_ci cont.get = se200pci_cont_boolean_get; 60962306a36Sopenharmony_ci cont.put = se200pci_cont_boolean_put; 61062306a36Sopenharmony_ci break; 61162306a36Sopenharmony_ci case ENUM: 61262306a36Sopenharmony_ci cont.info = se200pci_cont_enum_info; 61362306a36Sopenharmony_ci cont.get = se200pci_cont_enum_get; 61462306a36Sopenharmony_ci cont.put = se200pci_cont_enum_put; 61562306a36Sopenharmony_ci break; 61662306a36Sopenharmony_ci default: 61762306a36Sopenharmony_ci snd_BUG(); 61862306a36Sopenharmony_ci return -EINVAL; 61962306a36Sopenharmony_ci } 62062306a36Sopenharmony_ci err = snd_ctl_add(ice->card, snd_ctl_new1(&cont, ice)); 62162306a36Sopenharmony_ci if (err < 0) 62262306a36Sopenharmony_ci return err; 62362306a36Sopenharmony_ci } 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci return 0; 62662306a36Sopenharmony_ci} 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci/****************************************************************************/ 63062306a36Sopenharmony_ci/* ONKYO WAVIO SE-90PCI */ 63162306a36Sopenharmony_ci/****************************************************************************/ 63262306a36Sopenharmony_ci/* 63362306a36Sopenharmony_ci * system configuration ICE_EEP2_SYSCONF=0x4b 63462306a36Sopenharmony_ci * AC-Link configuration ICE_EEP2_ACLINK=0x80 63562306a36Sopenharmony_ci * I2S converters feature ICE_EEP2_I2S=0x78 63662306a36Sopenharmony_ci * S/PDIF configuration ICE_EEP2_SPDIF=0xc3 63762306a36Sopenharmony_ci * 63862306a36Sopenharmony_ci * ** connected chip ** 63962306a36Sopenharmony_ci * 64062306a36Sopenharmony_ci * WM8716 64162306a36Sopenharmony_ci * A 2ch-DAC of main outputs. 64262306a36Sopenharmony_ci * It setuped as I2S mode by wire, so no way to setup from software. 64362306a36Sopenharmony_ci * ML/I2S (28pin) -- +5V 64462306a36Sopenharmony_ci * MC/DM1 (27pin) -- GND 64562306a36Sopenharmony_ci * MC/DM0 (26pin) -- GND 64662306a36Sopenharmony_ci * MUTEB (25pin) -- open (internal pull-up) 64762306a36Sopenharmony_ci * MODE (24pin) -- GND 64862306a36Sopenharmony_ci * CSBIWO (23pin) -- +5V 64962306a36Sopenharmony_ci * 65062306a36Sopenharmony_ci */ 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci /* Nothing to do for this chip. */ 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci/****************************************************************************/ 65662306a36Sopenharmony_ci/* probe/initialize/setup */ 65762306a36Sopenharmony_ci/****************************************************************************/ 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_cistatic int se_init(struct snd_ice1712 *ice) 66062306a36Sopenharmony_ci{ 66162306a36Sopenharmony_ci struct se_spec *spec; 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci spec = kzalloc(sizeof(*spec), GFP_KERNEL); 66462306a36Sopenharmony_ci if (!spec) 66562306a36Sopenharmony_ci return -ENOMEM; 66662306a36Sopenharmony_ci ice->spec = spec; 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) { 66962306a36Sopenharmony_ci ice->num_total_dacs = 2; 67062306a36Sopenharmony_ci ice->num_total_adcs = 0; 67162306a36Sopenharmony_ci ice->vt1720 = 1; 67262306a36Sopenharmony_ci return 0; 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci } else if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) { 67562306a36Sopenharmony_ci ice->num_total_dacs = 8; 67662306a36Sopenharmony_ci ice->num_total_adcs = 2; 67762306a36Sopenharmony_ci se200pci_WM8740_init(ice); 67862306a36Sopenharmony_ci se200pci_WM8766_init(ice); 67962306a36Sopenharmony_ci se200pci_WM8776_init(ice); 68062306a36Sopenharmony_ci ice->gpio.set_pro_rate = se200pci_set_pro_rate; 68162306a36Sopenharmony_ci return 0; 68262306a36Sopenharmony_ci } 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci return -ENOENT; 68562306a36Sopenharmony_ci} 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_cistatic int se_add_controls(struct snd_ice1712 *ice) 68862306a36Sopenharmony_ci{ 68962306a36Sopenharmony_ci int err; 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ci err = 0; 69262306a36Sopenharmony_ci /* nothing to do for VT1724_SUBDEVICE_SE90PCI */ 69362306a36Sopenharmony_ci if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) 69462306a36Sopenharmony_ci err = se200pci_add_controls(ice); 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci return err; 69762306a36Sopenharmony_ci} 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci/****************************************************************************/ 70162306a36Sopenharmony_ci/* entry point */ 70262306a36Sopenharmony_ci/****************************************************************************/ 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_cistatic const unsigned char se200pci_eeprom[] = { 70562306a36Sopenharmony_ci [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */ 70662306a36Sopenharmony_ci [ICE_EEP2_ACLINK] = 0x80, /* I2S */ 70762306a36Sopenharmony_ci [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */ 70862306a36Sopenharmony_ci [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ 70962306a36Sopenharmony_ci 71062306a36Sopenharmony_ci [ICE_EEP2_GPIO_DIR] = 0x02, /* WM8766 mute 1=output */ 71162306a36Sopenharmony_ci [ICE_EEP2_GPIO_DIR1] = 0x00, /* not used */ 71262306a36Sopenharmony_ci [ICE_EEP2_GPIO_DIR2] = 0x07, /* WM8766 ML/MC/MD 1=output */ 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci [ICE_EEP2_GPIO_MASK] = 0x00, /* 0=writable */ 71562306a36Sopenharmony_ci [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0=writable */ 71662306a36Sopenharmony_ci [ICE_EEP2_GPIO_MASK2] = 0x00, /* 0=writable */ 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci [ICE_EEP2_GPIO_STATE] = 0x00, /* WM8766 mute=0 */ 71962306a36Sopenharmony_ci [ICE_EEP2_GPIO_STATE1] = 0x00, /* not used */ 72062306a36Sopenharmony_ci [ICE_EEP2_GPIO_STATE2] = 0x07, /* WM8766 ML/MC/MD */ 72162306a36Sopenharmony_ci}; 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_cistatic const unsigned char se90pci_eeprom[] = { 72462306a36Sopenharmony_ci [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */ 72562306a36Sopenharmony_ci [ICE_EEP2_ACLINK] = 0x80, /* I2S */ 72662306a36Sopenharmony_ci [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */ 72762306a36Sopenharmony_ci [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci /* ALL GPIO bits are in input mode */ 73062306a36Sopenharmony_ci}; 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_cistruct snd_ice1712_card_info snd_vt1724_se_cards[] = { 73362306a36Sopenharmony_ci { 73462306a36Sopenharmony_ci .subvendor = VT1724_SUBDEVICE_SE200PCI, 73562306a36Sopenharmony_ci .name = "ONKYO SE200PCI", 73662306a36Sopenharmony_ci .model = "se200pci", 73762306a36Sopenharmony_ci .chip_init = se_init, 73862306a36Sopenharmony_ci .build_controls = se_add_controls, 73962306a36Sopenharmony_ci .eeprom_size = sizeof(se200pci_eeprom), 74062306a36Sopenharmony_ci .eeprom_data = se200pci_eeprom, 74162306a36Sopenharmony_ci }, 74262306a36Sopenharmony_ci { 74362306a36Sopenharmony_ci .subvendor = VT1724_SUBDEVICE_SE90PCI, 74462306a36Sopenharmony_ci .name = "ONKYO SE90PCI", 74562306a36Sopenharmony_ci .model = "se90pci", 74662306a36Sopenharmony_ci .chip_init = se_init, 74762306a36Sopenharmony_ci .build_controls = se_add_controls, 74862306a36Sopenharmony_ci .eeprom_size = sizeof(se90pci_eeprom), 74962306a36Sopenharmony_ci .eeprom_data = se90pci_eeprom, 75062306a36Sopenharmony_ci }, 75162306a36Sopenharmony_ci {} /*terminator*/ 75262306a36Sopenharmony_ci}; 753