^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) * Routines for control of the CS8427 via i2c bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/bitrev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/unaligned.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) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sound/cs8427.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static void snd_cs8427_reset(struct snd_i2c_device *cs8427);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) MODULE_DESCRIPTION("IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CS8427_ADDR (0x20>>1) /* fixed address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct cs8427_stream {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) char hw_status[24]; /* hardware status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) char def_status[24]; /* default status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) char pcm_status[24]; /* PCM private status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) char hw_udata[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct snd_kcontrol *pcm_ctl;
^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) struct cs8427 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned char regmap[0x14]; /* map of first 1 + 13 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) unsigned int reset_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct cs8427_stream playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct cs8427_stream capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned char buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) buf[0] = reg & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) buf[1] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) snd_printk(KERN_ERR "unable to send bytes 0x%02x:0x%02x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) "to CS8427 (%i)\n", buf[0], buf[1], err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) EXPORT_SYMBOL(snd_cs8427_reg_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int snd_cs8427_reg_read(struct snd_i2c_device *device, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned char buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if ((err = snd_i2c_sendbytes(device, ®, 1)) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) snd_printk(KERN_ERR "unable to send register 0x%x byte "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) "to CS8427\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) snd_printk(KERN_ERR "unable to read register 0x%x byte "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) "from CS8427\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return buf;
^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 int snd_cs8427_select_corudata(struct snd_i2c_device *device, int udata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct cs8427 *chip = device->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) udata = udata ? CS8427_BSEL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (udata != (chip->regmap[CS8427_REG_CSDATABUF] & udata)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) chip->regmap[CS8427_REG_CSDATABUF] &= ~CS8427_BSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) chip->regmap[CS8427_REG_CSDATABUF] |= udata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) err = snd_cs8427_reg_write(device, CS8427_REG_CSDATABUF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) chip->regmap[CS8427_REG_CSDATABUF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int udata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned char *ndata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct cs8427 *chip = device->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) char *hw_data = udata ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) chip->playback.hw_udata : chip->playback.hw_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned char data[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int err, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!memcmp(hw_data, ndata, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if ((err = snd_cs8427_select_corudata(device, udata)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) memcpy(hw_data, ndata, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (udata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) memset(data, 0, sizeof(data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (memcmp(hw_data, data, count) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) chip->regmap[CS8427_REG_UDATABUF] &= ~CS8427_UBMMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) chip->regmap[CS8427_REG_UDATABUF] |= CS8427_UBMZEROS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) CS8427_EFTUI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) err = snd_cs8427_reg_write(device, CS8427_REG_UDATABUF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) chip->regmap[CS8427_REG_UDATABUF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return err < 0 ? err : 0;
^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) data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) for (idx = 0; idx < count; idx++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) data[idx + 1] = bitrev8(ndata[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (snd_i2c_sendbytes(device, data, count + 1) != count + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void snd_cs8427_free(struct snd_i2c_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) kfree(device->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int snd_cs8427_init(struct snd_i2c_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct snd_i2c_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static unsigned char initvals1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) CS8427_REG_CONTROL1 | CS8427_REG_AUTOINC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* CS8427_REG_CONTROL1: RMCK to OMCK, valid PCM audio, disable mutes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) TCBL=output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) CS8427_SWCLK | CS8427_TCBLDIR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* CS8427_REG_CONTROL2: hold last valid audio sample, RMCK=256*Fs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) normal stereo operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* CS8427_REG_DATAFLOW: output drivers normal operation, Tx<=serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) Rx=>serial */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) CS8427_TXDSERIAL | CS8427_SPDAES3RECEIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* CS8427_REG_CLOCKSOURCE: Run off, CMCK=256*Fs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) output time base = OMCK, input time base = recovered input clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) recovered input clock source is ILRCK changed to AES3INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) (workaround, see snd_cs8427_reset) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) CS8427_RXDILRCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* CS8427_REG_SERIALINPUT: Serial audio input port data format = I2S,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 24-bit, 64*Fsi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) CS8427_SIDEL | CS8427_SILRPOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* CS8427_REG_SERIALOUTPUT: Serial audio output port data format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) = I2S, 24-bit, 64*Fsi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) CS8427_SODEL | CS8427_SOLRPOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static unsigned char initvals2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) CS8427_REG_RECVERRMASK | CS8427_REG_AUTOINC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* CS8427_REG_RECVERRMASK: unmask the input PLL clock, V, confidence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) biphase, parity status bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* CS8427_UNLOCK | CS8427_V | CS8427_CONF | CS8427_BIP | CS8427_PAR,*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 0xff, /* set everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* CS8427_REG_CSDATABUF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) Registers 32-55 window to CS buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) Inhibit D->E transfers from overwriting first 5 bytes of CS data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) Inhibit D->E transfers (all) of CS data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) Allow E->F transfer of CS data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) One byte mode; both A/B channels get same written CB data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) A channel info is output to chip's EMPH* pin. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) CS8427_CBMR | CS8427_DETCI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* CS8427_REG_UDATABUF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) Use internal buffer to transmit User (U) data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) Chip's U pin is an output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) Transmit all O's for user data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) Inhibit D->E transfers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) Inhibit E->F transfers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) CS8427_UD | CS8427_EFTUI | CS8427_DETUI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct cs8427 *chip = device->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned char buf[24];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) snd_i2c_lock(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (err != CS8427_VER8427A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* give second chance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) snd_printk(KERN_WARNING "invalid CS8427 signature 0x%x: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) "let me try again...\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (err != CS8427_VER8427A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) snd_i2c_unlock(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) snd_printk(KERN_ERR "unable to find CS8427 signature "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) "(expected 0x%x, read 0x%x),\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) CS8427_VER8427A, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) snd_printk(KERN_ERR " initialization is not completed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* turn off run bit while making changes to configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) err = snd_cs8427_reg_write(device, CS8427_REG_CLOCKSOURCE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) goto __fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* send initial values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) memcpy(chip->regmap + (initvals1[0] & 0x7f), initvals1 + 1, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if ((err = snd_i2c_sendbytes(device, initvals1, 7)) != 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) err = err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) goto __fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* Turn off CS8427 interrupt stuff that is not used in hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) memset(buf, 0, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* from address 9 to 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) buf[0] = 9; /* register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if ((err = snd_i2c_sendbytes(device, buf, 7)) != 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto __fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* send transfer initialization sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) memcpy(chip->regmap + (initvals2[0] & 0x7f), initvals2 + 1, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if ((err = snd_i2c_sendbytes(device, initvals2, 4)) != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) err = err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) goto __fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* write default channel status bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) put_unaligned_le32(SNDRV_PCM_DEFAULT_CON_SPDIF, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) memset(buf + 4, 0, 24 - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (snd_cs8427_send_corudata(device, 0, buf, 24) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto __fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) memcpy(chip->playback.def_status, buf, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) memcpy(chip->playback.pcm_status, buf, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) snd_i2c_unlock(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* turn on run bit and rock'n'roll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) snd_cs8427_reset(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) __fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) snd_i2c_unlock(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) EXPORT_SYMBOL(snd_cs8427_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int snd_cs8427_create(struct snd_i2c_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned char addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned int reset_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct snd_i2c_device **r_cs8427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct cs8427 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct snd_i2c_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) err = snd_i2c_device_create(bus, "CS8427", CS8427_ADDR | (addr & 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) &device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (chip == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) snd_i2c_device_free(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) device->private_free = snd_cs8427_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (reset_timeout < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) reset_timeout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) chip->reset_timeout = reset_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) err = snd_cs8427_init(bus, device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) goto __fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #if 0 // it's nice for read tests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) char buf[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int xx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) buf[0] = 0x81;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) snd_i2c_sendbytes(device, buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) snd_i2c_readbytes(device, buf, 127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) for (xx = 0; xx < 127; xx++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (r_cs8427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) *r_cs8427 = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) __fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) snd_i2c_device_free(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) EXPORT_SYMBOL(snd_cs8427_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * Reset the chip using run bit, also lock PLL using ILRCK and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * put back AES3INPUT. This workaround is described in latest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * CS8427 datasheet, otherwise TXDSERIAL will not work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct cs8427 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) unsigned long end_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int data, aes3input = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (snd_BUG_ON(!cs8427))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) chip = cs8427->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) snd_i2c_lock(cs8427->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) CS8427_RXDAES3INPUT) /* AES3 bit is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) aes3input = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) chip->regmap[CS8427_REG_CLOCKSOURCE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) udelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RUN | CS8427_RXDILRCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) chip->regmap[CS8427_REG_CLOCKSOURCE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) udelay(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) snd_i2c_unlock(cs8427->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) end_time = jiffies + chip->reset_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) while (time_after_eq(end_time, jiffies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) snd_i2c_lock(cs8427->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) data = snd_cs8427_reg_read(cs8427, CS8427_REG_RECVERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) snd_i2c_unlock(cs8427->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (!(data & CS8427_UNLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) snd_i2c_lock(cs8427->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (aes3input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) chip->regmap[CS8427_REG_CLOCKSOURCE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) snd_i2c_unlock(cs8427->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int snd_cs8427_in_status_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) uinfo->value.integer.max = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static int snd_cs8427_in_status_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) snd_i2c_lock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) data = snd_cs8427_reg_read(device, kcontrol->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) snd_i2c_unlock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (data < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ucontrol->value.integer.value[0] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static int snd_cs8427_qsubcode_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) uinfo->count = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int snd_cs8427_qsubcode_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) unsigned char reg = CS8427_REG_QSUBCODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) snd_i2c_lock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if ((err = snd_i2c_sendbytes(device, ®, 1)) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) snd_printk(KERN_ERR "unable to send register 0x%x byte "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) "to CS8427\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) snd_i2c_unlock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (err != 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) snd_printk(KERN_ERR "unable to read Q-subcode bytes "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) "from CS8427\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) snd_i2c_unlock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) snd_i2c_unlock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int snd_cs8427_spdif_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int snd_cs8427_spdif_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct cs8427 *chip = device->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) snd_i2c_lock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) memcpy(ucontrol->value.iec958.status, chip->playback.def_status, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) snd_i2c_unlock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int snd_cs8427_spdif_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct cs8427 *chip = device->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) unsigned char *status = kcontrol->private_value ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) chip->playback.pcm_status : chip->playback.def_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct snd_pcm_runtime *runtime = chip->playback.substream ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) chip->playback.substream->runtime : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int err, change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) snd_i2c_lock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) change = memcmp(ucontrol->value.iec958.status, status, 24) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) memcpy(status, ucontrol->value.iec958.status, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (change && (kcontrol->private_value ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) runtime != NULL : runtime == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) err = snd_cs8427_send_corudata(device, 0, status, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) change = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) snd_i2c_unlock(device->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static int snd_cs8427_spdif_mask_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static int snd_cs8427_spdif_mask_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) memset(ucontrol->value.iec958.status, 0xff, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static const struct snd_kcontrol_new snd_cs8427_iec958_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .info = snd_cs8427_in_status_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .name = "IEC958 CS8427 Input Status",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .access = (SNDRV_CTL_ELEM_ACCESS_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) SNDRV_CTL_ELEM_ACCESS_VOLATILE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .get = snd_cs8427_in_status_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .private_value = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .info = snd_cs8427_in_status_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .name = "IEC958 CS8427 Error Status",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .access = (SNDRV_CTL_ELEM_ACCESS_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) SNDRV_CTL_ELEM_ACCESS_VOLATILE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .get = snd_cs8427_in_status_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) .private_value = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .info = snd_cs8427_spdif_mask_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .get = snd_cs8427_spdif_mask_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .info = snd_cs8427_spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .get = snd_cs8427_spdif_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .put = snd_cs8427_spdif_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .private_value = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) SNDRV_CTL_ELEM_ACCESS_INACTIVE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .info = snd_cs8427_spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .get = snd_cs8427_spdif_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .put = snd_cs8427_spdif_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .private_value = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .info = snd_cs8427_qsubcode_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .name = "IEC958 Q-subcode Capture Default",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .access = (SNDRV_CTL_ELEM_ACCESS_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) SNDRV_CTL_ELEM_ACCESS_VOLATILE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) .get = snd_cs8427_qsubcode_get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct snd_pcm_substream *play_substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct snd_pcm_substream *cap_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct cs8427 *chip = cs8427->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (snd_BUG_ON(!play_substream || !cap_substream))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (kctl == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) kctl->id.device = play_substream->pcm->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) kctl->id.subdevice = play_substream->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) err = snd_ctl_add(cs8427->bus->card, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (! strcmp(kctl->id.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) chip->playback.pcm_ctl = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) chip->playback.substream = play_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) chip->capture.substream = cap_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (snd_BUG_ON(!chip->playback.pcm_ctl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) EXPORT_SYMBOL(snd_cs8427_iec958_build);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct cs8427 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (snd_BUG_ON(!cs8427))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) chip = cs8427->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) memcpy(chip->playback.pcm_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) chip->playback.def_status, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) snd_ctl_notify(cs8427->bus->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) &chip->playback.pcm_ctl->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) EXPORT_SYMBOL(snd_cs8427_iec958_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct cs8427 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) char *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int err, reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (snd_BUG_ON(!cs8427))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) chip = cs8427->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) status = chip->playback.pcm_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) snd_i2c_lock(cs8427->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (status[0] & IEC958_AES0_PROFESSIONAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) status[0] &= ~IEC958_AES0_PRO_FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) case 32000: status[0] |= IEC958_AES0_PRO_FS_32000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) case 44100: status[0] |= IEC958_AES0_PRO_FS_44100; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) case 48000: status[0] |= IEC958_AES0_PRO_FS_48000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) default: status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) status[3] &= ~IEC958_AES3_CON_FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) case 32000: status[3] |= IEC958_AES3_CON_FS_32000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) case 44100: status[3] |= IEC958_AES3_CON_FS_44100; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) case 48000: status[3] |= IEC958_AES3_CON_FS_48000; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) err = snd_cs8427_send_corudata(cs8427, 0, status, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) snd_ctl_notify(cs8427->bus->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) &chip->playback.pcm_ctl->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) reset = chip->rate != rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) chip->rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) snd_i2c_unlock(cs8427->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) snd_cs8427_reset(cs8427);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return err < 0 ? err : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) EXPORT_SYMBOL(snd_cs8427_iec958_pcm);