^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ALSA driver for ICEnsemble ICE1712 (Envy24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "ice1712.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "envy24ht.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "revo.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* a non-standard I2C device for revo51 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct revo51_spec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct snd_i2c_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct snd_pt2258 *pt2258;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct ak4114 *ak4114;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* assert PRST# to converters; MT05 bit 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) mdelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* deassert PRST# */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * change the rate of Envy24HT, AK4355 and AK4381
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned char old, tmp, dfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int reg, shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (rate == 0) /* no hint - S/PDIF input is master, simply return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* adjust DFS on codecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (rate > 96000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) dfs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) else if (rate > 48000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) dfs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) dfs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (ak->type == SND_AK4355 || ak->type == SND_AK4358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) reg = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) shift = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) reg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) shift = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) tmp = snd_akm4xxx_get(ak, 0, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) old = (tmp >> shift) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (old == dfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* reset DFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) snd_akm4xxx_reset(ak, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) tmp = snd_akm4xxx_get(ak, 0, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) tmp &= ~(0x03 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) tmp |= dfs << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* snd_akm4xxx_write(ak, 0, reg, tmp); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) snd_akm4xxx_reset(ak, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static void revo_i2c_start(struct snd_i2c_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static void revo_i2c_stop(struct snd_i2c_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned int mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) val |= VT1724_REVO_I2C_CLOCK; /* write SCL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) val |= VT1724_REVO_I2C_DATA; /* write SDA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ice->gpio.direction &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ice->gpio.direction |= val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) snd_ice1712_gpio_set_mask(ice, ~mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) val |= VT1724_REVO_I2C_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) val |= VT1724_REVO_I2C_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) snd_ice1712_gpio_write_bits(ice,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) VT1724_REVO_I2C_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) VT1724_REVO_I2C_CLOCK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct snd_ice1712 *ice = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static struct snd_i2c_bit_ops revo51_bit_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .start = revo_i2c_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .stop = revo_i2c_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .direction = revo_i2c_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .setlines = revo_i2c_setlines,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .getdata = revo_i2c_getdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int revo51_i2c_init(struct snd_ice1712 *ice,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct snd_pt2258 *pt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct revo51_spec *spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) spec = kzalloc(sizeof(*spec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ice->spec = spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* create the I2C bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ice->i2c->private_data = ice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ice->i2c->hw_ops.bit = &revo51_bit_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* create the I2C device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pt->card = ice->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) pt->i2c_bus = ice->i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) pt->i2c_dev = spec->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) spec->pt2258 = pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) snd_pt2258_reset(pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * initialize the chips on M-Audio Revolution cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static const struct snd_akm4xxx_dac_channel revo71_front[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .name = "PCM Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .num_channels = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* front channels DAC supports muting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .switch_name = "PCM Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static const struct snd_akm4xxx_dac_channel revo71_surround[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) AK_DAC("PCM Center Playback Volume", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) AK_DAC("PCM LFE Playback Volume", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) AK_DAC("PCM Side Playback Volume", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) AK_DAC("PCM Rear Playback Volume", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static const struct snd_akm4xxx_dac_channel revo51_dac[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) AK_DAC("PCM Playback Volume", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) AK_DAC("PCM Center Playback Volume", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) AK_DAC("PCM LFE Playback Volume", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) AK_DAC("PCM Rear Playback Volume", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) AK_DAC("PCM Headphone Volume", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static const char *revo51_adc_input_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) "Mic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) "Line",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) "CD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static const struct snd_akm4xxx_adc_channel revo51_adc[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .name = "PCM Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .switch_name = "PCM Capture Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .num_channels = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .input_names = revo51_adc_input_names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static const struct snd_akm4xxx akm_revo_front = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .type = SND_AK4381,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .num_dacs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .set_rate_val = revo_set_rate_val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .dac_info = revo71_front,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static const struct snd_ak4xxx_private akm_revo_front_priv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .caddr = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .cif = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .data_mask = VT1724_REVO_CDOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .clk_mask = VT1724_REVO_CCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .add_flags = VT1724_REVO_CCLK, /* high at init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .mask_flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static const struct snd_akm4xxx akm_revo_surround = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .type = SND_AK4355,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .idx_offset = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .num_dacs = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .set_rate_val = revo_set_rate_val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .dac_info = revo71_surround,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static const struct snd_ak4xxx_private akm_revo_surround_priv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .caddr = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .cif = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .data_mask = VT1724_REVO_CDOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .clk_mask = VT1724_REVO_CCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .add_flags = VT1724_REVO_CCLK, /* high at init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .mask_flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static const struct snd_akm4xxx akm_revo51 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .type = SND_AK4358,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .num_dacs = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .set_rate_val = revo_set_rate_val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .dac_info = revo51_dac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static const struct snd_ak4xxx_private akm_revo51_priv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .caddr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .cif = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .data_mask = VT1724_REVO_CDOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .clk_mask = VT1724_REVO_CCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) .cs_addr = VT1724_REVO_CS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .add_flags = VT1724_REVO_CCLK, /* high at init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .mask_flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static const struct snd_akm4xxx akm_revo51_adc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .type = SND_AK5365,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .num_adcs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .adc_info = revo51_adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static const struct snd_ak4xxx_private akm_revo51_adc_priv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .caddr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .cif = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .data_mask = VT1724_REVO_CDOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .clk_mask = VT1724_REVO_CCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .cs_addr = VT1724_REVO_CS0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .add_flags = VT1724_REVO_CCLK, /* high at init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .mask_flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static struct snd_pt2258 ptc_revo51_volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* AK4358 for AP192 DAC, AK5385A for ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct snd_ice1712 *ice = ak->private_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int dfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) revo_set_rate_val(ak, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* reset CKS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) snd_ice1712_gpio_write_bits(ice, 1 << 8, rate > 96000 ? 1 << 8 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* reset DFS pins of AK5385A for ADC, too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (rate > 96000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dfs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) else if (rate > 48000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) dfs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) dfs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) snd_ice1712_gpio_write_bits(ice, 3 << 9, dfs << 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* reset ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) snd_ice1712_gpio_write_bits(ice, 1 << 11, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) snd_ice1712_gpio_write_bits(ice, 1 << 11, 1 << 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static const struct snd_akm4xxx_dac_channel ap192_dac[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) AK_DAC("PCM Playback Volume", 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static const struct snd_akm4xxx akm_ap192 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .type = SND_AK4358,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .num_dacs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .set_rate_val = ap192_set_rate_val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .dac_info = ap192_dac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static const struct snd_ak4xxx_private akm_ap192_priv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .caddr = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .cif = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .data_mask = VT1724_REVO_CDOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .clk_mask = VT1724_REVO_CCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .cs_addr = VT1724_REVO_CS3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .add_flags = VT1724_REVO_CCLK, /* high at init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .mask_flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* AK4114 support on Audiophile 192 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* CDTO (pin 32) -- GPIO2 pin 52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * CSN (pin 35) -- GPIO7 pin 59
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) #define AK4114_ADDR 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) unsigned int data, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) for (; idx >= 0; idx--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* drop clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) gpio &= ~VT1724_REVO_CCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) snd_ice1712_gpio_write(ice, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* set data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (data & (1 << idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) gpio |= VT1724_REVO_CDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) gpio &= ~VT1724_REVO_CDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) snd_ice1712_gpio_write(ice, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* raise clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) gpio |= VT1724_REVO_CCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) snd_ice1712_gpio_write(ice, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) unsigned char data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) for (; idx >= 0; idx--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* drop clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) gpio &= ~VT1724_REVO_CCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) snd_ice1712_gpio_write(ice, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* read data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) data |= (1 << idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* raise clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) gpio |= VT1724_REVO_CCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) snd_ice1712_gpio_write(ice, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) snd_ice1712_save_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) tmp = snd_ice1712_gpio_read(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) tmp |= VT1724_REVO_CCLK; /* high at init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) tmp |= VT1724_REVO_CS0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) tmp &= ~VT1724_REVO_CS3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) tmp |= VT1724_REVO_CS3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) tmp |= VT1724_REVO_CS0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) snd_ice1712_gpio_write(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) snd_ice1712_restore_gpio_status(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static void ap192_ak4114_write(void *private_data, unsigned char addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct snd_ice1712 *ice = private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned int tmp, addrdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) tmp = ap192_4wire_start(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) addrdata = (addrdata << 8) | data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) write_data(ice, tmp, addrdata, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ap192_4wire_finish(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct snd_ice1712 *ice = private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) unsigned char data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) tmp = ap192_4wire_start(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) data = read_data(ice, tmp, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ap192_4wire_finish(ice, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int ap192_ak4114_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static const unsigned char ak4114_init_vals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) AK4114_RST | AK4114_PWN | AK4114_OCKS0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) AK4114_DIF_I24I2S,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) AK4114_TX1E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static const unsigned char ak4114_init_txcsb[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 0x41, 0x02, 0x2c, 0x00, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct revo51_spec *spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) spec = kzalloc(sizeof(*spec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (!spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ice->spec = spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) err = snd_ak4114_create(ice->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ap192_ak4114_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ap192_ak4114_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ak4114_init_vals, ak4114_init_txcsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ice, &spec->ak4114);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* AK4114 in Revo cannot detect external rate correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * No reason to stop capture stream due to incorrect checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) spec->ak4114->check_flags = AK4114_CHECK_NO_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static int revo_init(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct snd_akm4xxx *ak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /* determine I2C, DACs and ADCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) case VT1724_SUBDEVICE_REVOLUTION71:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ice->num_total_dacs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ice->num_total_adcs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case VT1724_SUBDEVICE_REVOLUTION51:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ice->num_total_dacs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ice->num_total_adcs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) case VT1724_SUBDEVICE_AUDIOPHILE192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ice->num_total_dacs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ice->num_total_adcs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* second stage of initialization, analog parts and others */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (! ak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) case VT1724_SUBDEVICE_REVOLUTION71:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) ice->akm_codecs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) &akm_revo_front_priv, ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) &akm_revo_surround_priv, ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /* unmute all codecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) VT1724_REVO_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) case VT1724_SUBDEVICE_REVOLUTION51:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ice->akm_codecs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) err = snd_ice1712_akm4xxx_init(ak, &akm_revo51,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) &akm_revo51_priv, ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) &akm_revo51_adc_priv, ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) err = revo51_i2c_init(ice, &ptc_revo51_volume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* unmute all codecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) VT1724_REVO_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) case VT1724_SUBDEVICE_AUDIOPHILE192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ice->akm_codecs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) err = ap192_ak4114_init(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* unmute all codecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) VT1724_REVO_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static int revo_add_controls(struct snd_ice1712 *ice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct revo51_spec *spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) switch (ice->eeprom.subvendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) case VT1724_SUBDEVICE_REVOLUTION71:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) err = snd_ice1712_akm4xxx_build_controls(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) case VT1724_SUBDEVICE_REVOLUTION51:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) err = snd_ice1712_akm4xxx_build_controls(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) spec = ice->spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) err = snd_pt2258_build_controls(spec->pt2258);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) case VT1724_SUBDEVICE_AUDIOPHILE192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) err = snd_ice1712_akm4xxx_build_controls(ice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* only capture SPDIF over AK4114 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) err = snd_ak4114_build(spec->ak4114, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* entry point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct snd_ice1712_card_info snd_vt1724_revo_cards[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .subvendor = VT1724_SUBDEVICE_REVOLUTION71,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) .name = "M Audio Revolution-7.1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) .model = "revo71",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) .chip_init = revo_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .build_controls = revo_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .subvendor = VT1724_SUBDEVICE_REVOLUTION51,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .name = "M Audio Revolution-5.1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .model = "revo51",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .chip_init = revo_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) .build_controls = revo_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) .name = "M Audio Audiophile192",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) .model = "ap192",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .chip_init = revo_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .build_controls = revo_add_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) { } /* terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) };