Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
0004  *
0005  *   Lowlevel functions for AudioTrak Prodigy 192 cards
0006  *   Supported IEC958 input from optional MI/ODI/O add-on card.
0007  *
0008  *   Specifics (SW, HW):
0009  *   -------------------
0010  *      * 49.5MHz crystal
0011  *      * SPDIF-OUT on the card:
0012  *        - coax (through isolation transformer)/toslink supplied by
0013  *          74HC04 gates - 3 in parallel
0014  *        - output switched between on-board CD drive dig-out connector
0015  *          and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled
0016  *          by GPIO20 (0 = CD dig-out, 1 = SPDTX)
0017  *      * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax
0018  *
0019  *      * MI/ODI/O card: AK4114 based, used for iec958 input only
0020  *          - toslink input -> RX0
0021  *          - coax input -> RX1
0022  *          - 4wire protocol:
0023  *              AK4114      ICE1724
0024  *              ------------------------------
0025  *          CDTO (pin 32) -- GPIO11 pin 86
0026  *          CDTI (pin 33) -- GPIO10 pin 77
0027  *          CCLK (pin 34) -- GPIO9 pin 76
0028  *          CSN  (pin 35) -- GPIO8 pin 75
0029  *          - output data Mode 7 (24bit, I2S, slave)
0030  *      - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which
0031  *        outputs master clock to SPMCLKIN of ice1724.
0032  *        Experimentally I found out that only a combination of
0033  *        OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 -
0034  *        VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct
0035  *        sampling rate. That means that the FPGA doubles the
0036  *        MCK01 rate.
0037  *
0038  *  Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
0039  *      Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
0040  *      Copyright (c) 2004 Kouichi ONO <co2b@ceres.dti.ne.jp>
0041  */      
0042 
0043 #include <linux/delay.h>
0044 #include <linux/interrupt.h>
0045 #include <linux/init.h>
0046 #include <linux/slab.h>
0047 #include <sound/core.h>
0048 
0049 #include "ice1712.h"
0050 #include "envy24ht.h"
0051 #include "prodigy192.h"
0052 #include "stac946x.h"
0053 #include <sound/tlv.h>
0054 
0055 struct prodigy192_spec {
0056     struct ak4114 *ak4114;
0057     /* rate change needs atomic mute/unmute of all dacs*/
0058     struct mutex mute_mutex;
0059 };
0060 
0061 static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val)
0062 {
0063     snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
0064 }
0065 
0066 static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
0067 {
0068     return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg);
0069 }
0070 
0071 /*
0072  * DAC mute control
0073  */
0074 
0075 /*
0076  * idx = STAC9460 volume register number, mute: 0 = mute, 1 = unmute
0077  */
0078 static int stac9460_dac_mute(struct snd_ice1712 *ice, int idx,
0079         unsigned char mute)
0080 {
0081     unsigned char new, old;
0082     int change;
0083     old = stac9460_get(ice, idx);
0084     new = (~mute << 7 & 0x80) | (old & ~0x80);
0085     change = (new != old);
0086     if (change)
0087         /* dev_dbg(ice->card->dev, "Volume register 0x%02x: 0x%02x\n", idx, new);*/
0088         stac9460_put(ice, idx, new);
0089     return change;
0090 }
0091 
0092 #define stac9460_dac_mute_info      snd_ctl_boolean_mono_info
0093 
0094 static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0095 {
0096     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0097     unsigned char val;
0098     int idx;
0099 
0100     if (kcontrol->private_value)
0101         idx = STAC946X_MASTER_VOLUME;
0102     else
0103         idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
0104     val = stac9460_get(ice, idx);
0105     ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
0106     return 0;
0107 }
0108 
0109 static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0110 {
0111     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0112     struct prodigy192_spec *spec = ice->spec;
0113     int idx, change;
0114 
0115     if (kcontrol->private_value)
0116         idx = STAC946X_MASTER_VOLUME;
0117     else
0118         idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
0119     /* due to possible conflicts with stac9460_set_rate_val, mutexing */
0120     mutex_lock(&spec->mute_mutex);
0121     /*
0122     dev_dbg(ice->card->dev, "Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
0123            ucontrol->value.integer.value[0]);
0124     */
0125     change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]);
0126     mutex_unlock(&spec->mute_mutex);
0127     return change;
0128 }
0129 
0130 /*
0131  * DAC volume attenuation mixer control
0132  */
0133 static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0134 {
0135     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0136     uinfo->count = 1;
0137     uinfo->value.integer.min = 0;           /* mute */
0138     uinfo->value.integer.max = 0x7f;        /* 0dB */
0139     return 0;
0140 }
0141 
0142 static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0143 {
0144     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0145     int idx;
0146     unsigned char vol;
0147 
0148     if (kcontrol->private_value)
0149         idx = STAC946X_MASTER_VOLUME;
0150     else
0151         idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
0152     vol = stac9460_get(ice, idx) & 0x7f;
0153     ucontrol->value.integer.value[0] = 0x7f - vol;
0154 
0155     return 0;
0156 }
0157 
0158 static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0159 {
0160     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0161     int idx;
0162     unsigned char tmp, ovol, nvol;
0163     int change;
0164 
0165     if (kcontrol->private_value)
0166         idx = STAC946X_MASTER_VOLUME;
0167     else
0168         idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
0169     nvol = ucontrol->value.integer.value[0];
0170     tmp = stac9460_get(ice, idx);
0171     ovol = 0x7f - (tmp & 0x7f);
0172     change = (ovol != nvol);
0173     if (change) {
0174         ovol =  (0x7f - nvol) | (tmp & 0x80);
0175         /*
0176         dev_dbg(ice->card->dev, "DAC Volume: reg 0x%02x: 0x%02x\n",
0177                idx, ovol);
0178         */
0179         stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
0180     }
0181     return change;
0182 }
0183 
0184 /*
0185  * ADC mute control
0186  */
0187 #define stac9460_adc_mute_info      snd_ctl_boolean_stereo_info
0188 
0189 static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0190 {
0191     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0192     unsigned char val;
0193     int i;
0194 
0195     for (i = 0; i < 2; ++i) {
0196         val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
0197         ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
0198     }
0199 
0200     return 0;
0201 }
0202 
0203 static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0204 {
0205     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0206     unsigned char new, old;
0207     int i, reg;
0208     int change;
0209 
0210     for (i = 0; i < 2; ++i) {
0211         reg = STAC946X_MIC_L_VOLUME + i;
0212         old = stac9460_get(ice, reg);
0213         new = (~ucontrol->value.integer.value[i]<<7&0x80) | (old&~0x80);
0214         change = (new != old);
0215         if (change)
0216             stac9460_put(ice, reg, new);
0217     }
0218 
0219     return change;
0220 }
0221 
0222 /*
0223  * ADC gain mixer control
0224  */
0225 static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0226 {
0227     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0228     uinfo->count = 2;
0229     uinfo->value.integer.min = 0;       /* 0dB */
0230     uinfo->value.integer.max = 0x0f;    /* 22.5dB */
0231     return 0;
0232 }
0233 
0234 static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0235 {
0236     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0237     int i, reg;
0238     unsigned char vol;
0239 
0240     for (i = 0; i < 2; ++i) {
0241         reg = STAC946X_MIC_L_VOLUME + i;
0242         vol = stac9460_get(ice, reg) & 0x0f;
0243         ucontrol->value.integer.value[i] = 0x0f - vol;
0244     }
0245 
0246     return 0;
0247 }
0248 
0249 static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0250 {
0251     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0252     int i, reg;
0253     unsigned char ovol, nvol;
0254     int change;
0255 
0256     for (i = 0; i < 2; ++i) {
0257         reg = STAC946X_MIC_L_VOLUME + i;
0258         nvol = ucontrol->value.integer.value[i] & 0x0f;
0259         ovol = 0x0f - stac9460_get(ice, reg);
0260         change = ((ovol & 0x0f)  != nvol);
0261         if (change)
0262             stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f));
0263     }
0264 
0265     return change;
0266 }
0267 
0268 static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
0269                     struct snd_ctl_elem_info *uinfo)
0270 {
0271     static const char * const texts[2] = { "Line In", "Mic" };
0272 
0273     return snd_ctl_enum_info(uinfo, 1, 2, texts);
0274 }
0275 
0276 
0277 static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
0278                 struct snd_ctl_elem_value *ucontrol)
0279 {
0280     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0281     unsigned char val;
0282         
0283     val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
0284     ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1;
0285     return 0;
0286 }
0287 
0288 static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
0289                 struct snd_ctl_elem_value *ucontrol)
0290 {
0291     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0292     unsigned char new, old;
0293     int change;
0294     old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
0295     new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
0296     change = (new != old);
0297     if (change)
0298         stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
0299     return change;
0300 }
0301 /*
0302  * Handler for setting correct codec rate - called when rate change is detected
0303  */
0304 static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
0305 {
0306     unsigned char old, new;
0307     int idx;
0308     unsigned char changed[7];
0309     struct prodigy192_spec *spec = ice->spec;
0310 
0311     if (rate == 0)  /* no hint - S/PDIF input is master, simply return */
0312         return;
0313     else if (rate <= 48000)
0314         new = 0x08; /* 256x, base rate mode */
0315     else if (rate <= 96000)
0316         new = 0x11; /* 256x, mid rate mode */
0317     else
0318         new = 0x12; /* 128x, high rate mode */
0319     old = stac9460_get(ice, STAC946X_MASTER_CLOCKING);
0320     if (old == new)
0321         return;
0322     /* change detected, setting master clock, muting first */
0323     /* due to possible conflicts with mute controls - mutexing */
0324     mutex_lock(&spec->mute_mutex);
0325     /* we have to remember current mute status for each DAC */
0326     for (idx = 0; idx < 7 ; ++idx)
0327         changed[idx] = stac9460_dac_mute(ice,
0328                 STAC946X_MASTER_VOLUME + idx, 0);
0329     /*dev_dbg(ice->card->dev, "Rate change: %d, new MC: 0x%02x\n", rate, new);*/
0330     stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);
0331     udelay(10);
0332     /* unmuting - only originally unmuted dacs -
0333      * i.e. those changed when muting */
0334     for (idx = 0; idx < 7 ; ++idx) {
0335         if (changed[idx])
0336             stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1);
0337     }
0338     mutex_unlock(&spec->mute_mutex);
0339 }
0340 
0341 
0342 static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
0343 static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
0344 
0345 /*
0346  * mixers
0347  */
0348 
0349 static const struct snd_kcontrol_new stac_controls[] = {
0350     {
0351         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0352         .name = "Master Playback Switch",
0353         .info = stac9460_dac_mute_info,
0354         .get = stac9460_dac_mute_get,
0355         .put = stac9460_dac_mute_put,
0356         .private_value = 1,
0357         .tlv = { .p = db_scale_dac }
0358     },
0359     {
0360         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0361         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0362                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0363         .name = "Master Playback Volume",
0364         .info = stac9460_dac_vol_info,
0365         .get = stac9460_dac_vol_get,
0366         .put = stac9460_dac_vol_put,
0367         .private_value = 1,
0368         .tlv = { .p = db_scale_dac }
0369     },
0370     {
0371         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0372         .name = "DAC Switch",
0373         .count = 6,
0374         .info = stac9460_dac_mute_info,
0375         .get = stac9460_dac_mute_get,
0376         .put = stac9460_dac_mute_put,
0377     },
0378     {
0379         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0380         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0381                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0382         .name = "DAC Volume",
0383         .count = 6,
0384         .info = stac9460_dac_vol_info,
0385         .get = stac9460_dac_vol_get,
0386         .put = stac9460_dac_vol_put,
0387         .tlv = { .p = db_scale_dac }
0388     },
0389     {
0390         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0391         .name = "ADC Capture Switch",
0392         .count = 1,
0393         .info = stac9460_adc_mute_info,
0394         .get = stac9460_adc_mute_get,
0395         .put = stac9460_adc_mute_put,
0396 
0397     },
0398     {
0399         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0400         .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
0401                SNDRV_CTL_ELEM_ACCESS_TLV_READ),
0402         .name = "ADC Capture Volume",
0403         .count = 1,
0404         .info = stac9460_adc_vol_info,
0405         .get = stac9460_adc_vol_get,
0406         .put = stac9460_adc_vol_put,
0407         .tlv = { .p = db_scale_adc }
0408     },
0409     {
0410         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0411         .name = "Analog Capture Input",
0412         .info = stac9460_mic_sw_info,
0413         .get = stac9460_mic_sw_get,
0414         .put = stac9460_mic_sw_put,
0415 
0416     },
0417 };
0418 
0419 /* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */
0420 /* CDTO (pin 32) -- GPIO11 pin 86
0421  * CDTI (pin 33) -- GPIO10 pin 77
0422  * CCLK (pin 34) -- GPIO9 pin 76
0423  * CSN  (pin 35) -- GPIO8 pin 75
0424  */
0425 #define AK4114_ADDR 0x00 /* C1-C0: Chip Address
0426                   * (According to datasheet fixed to “00”)
0427                   */
0428 
0429 /*
0430  * 4wire ak4114 protocol - writing data
0431  */
0432 static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
0433                unsigned int data, int idx)
0434 {
0435     for (; idx >= 0; idx--) {
0436         /* drop clock */
0437         gpio &= ~VT1724_PRODIGY192_CCLK;
0438         snd_ice1712_gpio_write(ice, gpio);
0439         udelay(1);
0440         /* set data */
0441         if (data & (1 << idx))
0442             gpio |= VT1724_PRODIGY192_CDOUT;
0443         else
0444             gpio &= ~VT1724_PRODIGY192_CDOUT;
0445         snd_ice1712_gpio_write(ice, gpio);
0446         udelay(1);
0447         /* raise clock */
0448         gpio |= VT1724_PRODIGY192_CCLK;
0449         snd_ice1712_gpio_write(ice, gpio);
0450         udelay(1);
0451     }
0452 }
0453 
0454 /*
0455  * 4wire ak4114 protocol - reading data
0456  */
0457 static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
0458                    int idx)
0459 {
0460     unsigned char data = 0;
0461 
0462     for (; idx >= 0; idx--) {
0463         /* drop clock */
0464         gpio &= ~VT1724_PRODIGY192_CCLK;
0465         snd_ice1712_gpio_write(ice, gpio);
0466         udelay(1);
0467         /* read data */
0468         if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN)
0469             data |= (1 << idx);
0470         udelay(1);
0471         /* raise clock */
0472         gpio |= VT1724_PRODIGY192_CCLK;
0473         snd_ice1712_gpio_write(ice, gpio);
0474         udelay(1);
0475     }
0476     return data;
0477 }
0478 /*
0479  * 4wire ak4114 protocol - starting sequence
0480  */
0481 static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice)
0482 {
0483     unsigned int tmp;
0484 
0485     snd_ice1712_save_gpio_status(ice);
0486     tmp = snd_ice1712_gpio_read(ice);
0487 
0488     tmp |= VT1724_PRODIGY192_CCLK; /* high at init */
0489     tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */
0490     snd_ice1712_gpio_write(ice, tmp);
0491     udelay(1);
0492     return tmp;
0493 }
0494 
0495 /*
0496  * 4wire ak4114 protocol - final sequence
0497  */
0498 static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
0499 {
0500     tmp |= VT1724_PRODIGY192_CS; /* raise chip select */
0501     snd_ice1712_gpio_write(ice, tmp);
0502     udelay(1);
0503     snd_ice1712_restore_gpio_status(ice);
0504 }
0505 
0506 /*
0507  * Write data to addr register of ak4114
0508  */
0509 static void prodigy192_ak4114_write(void *private_data, unsigned char addr,
0510                    unsigned char data)
0511 {
0512     struct snd_ice1712 *ice = private_data;
0513     unsigned int tmp, addrdata;
0514     tmp = prodigy192_4wire_start(ice);
0515     addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
0516     addrdata = (addrdata << 8) | data;
0517     write_data(ice, tmp, addrdata, 15);
0518     prodigy192_4wire_finish(ice, tmp);
0519 }
0520 
0521 /*
0522  * Read data from addr register of ak4114
0523  */
0524 static unsigned char prodigy192_ak4114_read(void *private_data,
0525                         unsigned char addr)
0526 {
0527     struct snd_ice1712 *ice = private_data;
0528     unsigned int tmp;
0529     unsigned char data;
0530 
0531     tmp = prodigy192_4wire_start(ice);
0532     write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
0533     data = read_data(ice, tmp, 7);
0534     prodigy192_4wire_finish(ice, tmp);
0535     return data;
0536 }
0537 
0538 
0539 static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol,
0540                     struct snd_ctl_elem_info *uinfo)
0541 {
0542     static const char * const texts[2] = { "Toslink", "Coax" };
0543 
0544     return snd_ctl_enum_info(uinfo, 1, 2, texts);
0545 }
0546 
0547 
0548 static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol,
0549                 struct snd_ctl_elem_value *ucontrol)
0550 {
0551     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0552     unsigned char val;
0553         
0554     val = prodigy192_ak4114_read(ice, AK4114_REG_IO1);
0555     /* AK4114_IPS0 bit = 0 -> RX0 = Toslink
0556      * AK4114_IPS0 bit = 1 -> RX1 = Coax
0557      */
0558     ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0;
0559     return 0;
0560 }
0561 
0562 static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol,
0563                 struct snd_ctl_elem_value *ucontrol)
0564 {
0565     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0566     unsigned char new, old, itemvalue;
0567     int change;
0568 
0569     old = prodigy192_ak4114_read(ice, AK4114_REG_IO1);
0570     /* AK4114_IPS0 could be any bit */
0571     itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00;
0572 
0573     new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0);
0574     change = (new != old);
0575     if (change)
0576         prodigy192_ak4114_write(ice, AK4114_REG_IO1, new);
0577     return change;
0578 }
0579 
0580 
0581 static const struct snd_kcontrol_new ak4114_controls[] = {
0582     {
0583         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0584         .name = "MIODIO IEC958 Capture Input",
0585         .info = ak4114_input_sw_info,
0586         .get = ak4114_input_sw_get,
0587         .put = ak4114_input_sw_put,
0588 
0589     }
0590 };
0591 
0592 
0593 static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
0594 {
0595     static const unsigned char ak4114_init_vals[] = {
0596         AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
0597         /* ice1724 expects I2S and provides clock,
0598          * DEM0 disables the deemphasis filter
0599          */
0600         AK4114_DIF_I24I2S | AK4114_DEM0 ,
0601         AK4114_TX1E,
0602         AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */
0603         0,
0604         0
0605     };
0606     static const unsigned char ak4114_init_txcsb[] = {
0607         0x41, 0x02, 0x2c, 0x00, 0x00
0608     };
0609     struct prodigy192_spec *spec = ice->spec;
0610     int err;
0611 
0612     err = snd_ak4114_create(ice->card,
0613                  prodigy192_ak4114_read,
0614                  prodigy192_ak4114_write,
0615                  ak4114_init_vals, ak4114_init_txcsb,
0616                  ice, &spec->ak4114);
0617     if (err < 0)
0618         return err;
0619     /* AK4114 in Prodigy192 cannot detect external rate correctly.
0620      * No reason to stop capture stream due to incorrect checks */
0621     spec->ak4114->check_flags = AK4114_CHECK_NO_RATE;
0622     return 0;
0623 }
0624 
0625 static void stac9460_proc_regs_read(struct snd_info_entry *entry,
0626         struct snd_info_buffer *buffer)
0627 {
0628     struct snd_ice1712 *ice = entry->private_data;
0629     int reg, val;
0630     /* registers 0x0 - 0x14 */
0631     for (reg = 0; reg <= 0x15; reg++) {
0632         val = stac9460_get(ice, reg);
0633         snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val);
0634     }
0635 }
0636 
0637 
0638 static void stac9460_proc_init(struct snd_ice1712 *ice)
0639 {
0640     snd_card_ro_proc_new(ice->card, "stac9460_codec", ice,
0641                  stac9460_proc_regs_read);
0642 }
0643 
0644 
0645 static int prodigy192_add_controls(struct snd_ice1712 *ice)
0646 {
0647     struct prodigy192_spec *spec = ice->spec;
0648     unsigned int i;
0649     int err;
0650 
0651     for (i = 0; i < ARRAY_SIZE(stac_controls); i++) {
0652         err = snd_ctl_add(ice->card,
0653                   snd_ctl_new1(&stac_controls[i], ice));
0654         if (err < 0)
0655             return err;
0656     }
0657     if (spec->ak4114) {
0658         /* ak4114 is connected */
0659         for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) {
0660             err = snd_ctl_add(ice->card,
0661                       snd_ctl_new1(&ak4114_controls[i],
0662                                ice));
0663             if (err < 0)
0664                 return err;
0665         }
0666         err = snd_ak4114_build(spec->ak4114,
0667                 NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */
0668                 ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
0669         if (err < 0)
0670             return err;
0671     }
0672     stac9460_proc_init(ice);
0673     return 0;
0674 }
0675 
0676 /*
0677  * check for presence of MI/ODI/O add-on card with digital inputs
0678  */
0679 static int prodigy192_miodio_exists(struct snd_ice1712 *ice)
0680 {
0681 
0682     unsigned char orig_value;
0683     const unsigned char test_data = 0xd1;   /* random value */
0684     unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */
0685     int exists = 0;
0686 
0687     orig_value = prodigy192_ak4114_read(ice, addr);
0688     prodigy192_ak4114_write(ice, addr, test_data);
0689     if (prodigy192_ak4114_read(ice, addr) == test_data) {
0690         /* ak4114 seems to communicate, apparently exists */
0691         /* writing back original value */
0692         prodigy192_ak4114_write(ice, addr, orig_value);
0693         exists = 1;
0694     }
0695     return exists;
0696 }
0697 
0698 /*
0699  * initialize the chip
0700  */
0701 static int prodigy192_init(struct snd_ice1712 *ice)
0702 {
0703     static const unsigned short stac_inits_prodigy[] = {
0704         STAC946X_RESET, 0,
0705         STAC946X_MASTER_CLOCKING, 0x11,
0706 /*      STAC946X_MASTER_VOLUME, 0,
0707         STAC946X_LF_VOLUME, 0,
0708         STAC946X_RF_VOLUME, 0,
0709         STAC946X_LR_VOLUME, 0,
0710         STAC946X_RR_VOLUME, 0,
0711         STAC946X_CENTER_VOLUME, 0,
0712         STAC946X_LFE_VOLUME, 0,*/
0713         (unsigned short)-1
0714     };
0715     const unsigned short *p;
0716     int err = 0;
0717     struct prodigy192_spec *spec;
0718 
0719     /* prodigy 192 */
0720     ice->num_total_dacs = 6;
0721     ice->num_total_adcs = 2;
0722     ice->vt1720 = 0;  /* ice1724, e.g. 23 GPIOs */
0723     
0724     spec = kzalloc(sizeof(*spec), GFP_KERNEL);
0725     if (!spec)
0726         return -ENOMEM;
0727     ice->spec = spec;
0728     mutex_init(&spec->mute_mutex);
0729 
0730     /* initialize codec */
0731     p = stac_inits_prodigy;
0732     for (; *p != (unsigned short)-1; p += 2)
0733         stac9460_put(ice, p[0], p[1]);
0734     ice->gpio.set_pro_rate = stac9460_set_rate_val;
0735 
0736     /* MI/ODI/O add on card with AK4114 */
0737     if (prodigy192_miodio_exists(ice)) {
0738         err = prodigy192_ak4114_init(ice);
0739         /* from this moment if err = 0 then
0740          * spec->ak4114 should not be null
0741          */
0742         dev_dbg(ice->card->dev,
0743             "AK4114 initialized with status %d\n", err);
0744     } else
0745         dev_dbg(ice->card->dev, "AK4114 not found\n");
0746 
0747     return err;
0748 }
0749 
0750 
0751 /*
0752  * Aureon boards don't provide the EEPROM data except for the vendor IDs.
0753  * hence the driver needs to sets up it properly.
0754  */
0755 
0756 static const unsigned char prodigy71_eeprom[] = {
0757     [ICE_EEP2_SYSCONF]     = 0x6a,  /* 49MHz crystal, mpu401,
0758                      * spdif-in+ 1 stereo ADC,
0759                      * 3 stereo DACs
0760                      */
0761     [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
0762     [ICE_EEP2_I2S]         = 0xf8,  /* vol, 96k, 24bit, 192k */
0763     [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
0764     [ICE_EEP2_GPIO_DIR]    = 0xff,
0765     [ICE_EEP2_GPIO_DIR1]   = ~(VT1724_PRODIGY192_CDIN >> 8) ,
0766     [ICE_EEP2_GPIO_DIR2]   = 0xbf,
0767     [ICE_EEP2_GPIO_MASK]   = 0x00,
0768     [ICE_EEP2_GPIO_MASK1]  = 0x00,
0769     [ICE_EEP2_GPIO_MASK2]  = 0x00,
0770     [ICE_EEP2_GPIO_STATE]  = 0x00,
0771     [ICE_EEP2_GPIO_STATE1] = 0x00,
0772     [ICE_EEP2_GPIO_STATE2] = 0x10,  /* GPIO20: 0 = CD drive dig. input
0773                      * passthrough,
0774                      * 1 = SPDIF-OUT from ice1724
0775                      */
0776 };
0777 
0778 
0779 /* entry point */
0780 struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] = {
0781     {
0782         .subvendor = VT1724_SUBDEVICE_PRODIGY192VE,
0783         .name = "Audiotrak Prodigy 192",
0784         .model = "prodigy192",
0785         .chip_init = prodigy192_init,
0786         .build_controls = prodigy192_add_controls,
0787         .eeprom_size = sizeof(prodigy71_eeprom),
0788         .eeprom_data = prodigy71_eeprom,
0789     },
0790     { } /* terminator */
0791 };