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 Philips PSC724 Ultimate Edge
0006  *
0007  *  Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.org>
0008  */
0009 
0010 #include <linux/delay.h>
0011 #include <linux/init.h>
0012 #include <linux/slab.h>
0013 #include <sound/core.h>
0014 
0015 #include "ice1712.h"
0016 #include "envy24ht.h"
0017 #include "psc724.h"
0018 #include "wm8766.h"
0019 #include "wm8776.h"
0020 
0021 struct psc724_spec {
0022     struct snd_wm8766 wm8766;
0023     struct snd_wm8776 wm8776;
0024     bool mute_all, jack_detect;
0025     struct snd_ice1712 *ice;
0026     struct delayed_work hp_work;
0027     bool hp_connected;
0028 };
0029 
0030 /****************************************************************************/
0031 /*  PHILIPS PSC724 ULTIMATE EDGE                                            */
0032 /****************************************************************************/
0033 /*
0034  *  VT1722 (Envy24GT) - 6 outputs, 4 inputs (only 2 used), 24-bit/96kHz
0035  *
0036  *  system configuration ICE_EEP2_SYSCONF=0x42
0037  *    XIN1 49.152MHz
0038  *    no MPU401
0039  *    one stereo ADC, no S/PDIF receiver
0040  *    three stereo DACs (FRONT, REAR, CENTER+LFE)
0041  *
0042  *  AC-Link configuration ICE_EEP2_ACLINK=0x80
0043  *    use I2S, not AC97
0044  *
0045  *  I2S converters feature ICE_EEP2_I2S=0x30
0046  *    I2S codec has no volume/mute control feature (bug!)
0047  *    I2S codec does not support 96KHz or 192KHz (bug!)
0048  *    I2S codec 24bits
0049  *
0050  *  S/PDIF configuration ICE_EEP2_SPDIF=0xc1
0051  *    Enable integrated S/PDIF transmitter
0052  *    internal S/PDIF out implemented
0053  *    No S/PDIF input
0054  *    External S/PDIF out implemented
0055  *
0056  *
0057  * ** connected chips **
0058  *
0059  *  WM8776
0060  *     2-channel DAC used for main output and stereo ADC (with 10-channel MUX)
0061  *     AIN1: LINE IN, AIN2: CD/VIDEO, AIN3: AUX, AIN4: Front MIC, AIN5: Rear MIC
0062  *     Controlled by I2C using VT1722 I2C interface:
0063  *          MODE (pin16) -- GND
0064  *          CE   (pin17) -- GND  I2C mode (address=0x34)
0065  *          DI   (pin18) -- SDA  (VT1722 pin70)
0066  *          CL   (pin19) -- SCLK (VT1722 pin71)
0067  *
0068  *  WM8766
0069  *      6-channel DAC used for rear & center/LFE outputs (only 4 channels used)
0070  *      Controlled by SPI using VT1722 GPIO pins:
0071  *          MODE   (pin 1) -- GPIO19 (VT1722 pin99)
0072  *          ML/I2S (pin11) -- GPIO18 (VT1722 pin98)
0073  *          MC/IWL (pin12) -- GPIO17 (VT1722 pin97)
0074  *          MD/DM  (pin13) -- GPIO16 (VT1722 pin96)
0075  *          MUTE   (pin14) -- GPIO20 (VT1722 pin101)
0076  *
0077  *  GPIO14 is used as input for headphone jack detection (1 = connected)
0078  *  GPIO22 is used as MUTE ALL output, grounding all 6 channels
0079  *
0080  * ** output pins and device names **
0081  *
0082  *   5.1ch name -- output connector color -- device (-D option)
0083  *
0084  *      FRONT 2ch                  -- green  -- plughw:0,0
0085  *      CENTER(Lch) SUBWOOFER(Rch) -- orange -- plughw:0,2,0
0086  *      REAR 2ch                   -- black  -- plughw:0,2,1
0087  */
0088 
0089 /* codec access low-level functions */
0090 
0091 #define GPIO_HP_JACK    (1 << 14)
0092 #define GPIO_MUTE_SUR   (1 << 20)
0093 #define GPIO_MUTE_ALL   (1 << 22)
0094 
0095 #define JACK_INTERVAL   1000
0096 
0097 #define PSC724_SPI_DELAY 1
0098 
0099 #define PSC724_SPI_DATA (1 << 16)
0100 #define PSC724_SPI_CLK  (1 << 17)
0101 #define PSC724_SPI_LOAD (1 << 18)
0102 #define PSC724_SPI_MASK (PSC724_SPI_DATA | PSC724_SPI_CLK | PSC724_SPI_LOAD)
0103 
0104 static void psc724_wm8766_write(struct snd_wm8766 *wm, u16 addr, u16 data)
0105 {
0106     struct psc724_spec *spec = container_of(wm, struct psc724_spec, wm8766);
0107     struct snd_ice1712 *ice = spec->ice;
0108     u32 st, bits;
0109     int i;
0110 
0111     snd_ice1712_save_gpio_status(ice);
0112 
0113     st = ((addr & 0x7f) << 9) | (data & 0x1ff);
0114     snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | PSC724_SPI_MASK);
0115     snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~PSC724_SPI_MASK);
0116     bits = snd_ice1712_gpio_read(ice) & ~PSC724_SPI_MASK;
0117     snd_ice1712_gpio_write(ice, bits);
0118 
0119     for (i = 0; i < 16; i++) {
0120         udelay(PSC724_SPI_DELAY);
0121         bits &= ~PSC724_SPI_CLK;
0122         /* MSB first */
0123         st <<= 1;
0124         if (st & 0x10000)
0125             bits |= PSC724_SPI_DATA;
0126         else
0127             bits &= ~PSC724_SPI_DATA;
0128         snd_ice1712_gpio_write(ice, bits);
0129         /* CLOCK high */
0130         udelay(PSC724_SPI_DELAY);
0131         bits |= PSC724_SPI_CLK;
0132         snd_ice1712_gpio_write(ice, bits);
0133     }
0134     /* LOAD high */
0135     udelay(PSC724_SPI_DELAY);
0136     bits |= PSC724_SPI_LOAD;
0137     snd_ice1712_gpio_write(ice, bits);
0138     /* LOAD low, DATA and CLOCK high */
0139     udelay(PSC724_SPI_DELAY);
0140     bits |= (PSC724_SPI_DATA | PSC724_SPI_CLK);
0141     snd_ice1712_gpio_write(ice, bits);
0142 
0143     snd_ice1712_restore_gpio_status(ice);
0144 }
0145 
0146 static void psc724_wm8776_write(struct snd_wm8776 *wm, u8 addr, u8 data)
0147 {
0148     struct psc724_spec *spec = container_of(wm, struct psc724_spec, wm8776);
0149 
0150     snd_vt1724_write_i2c(spec->ice, 0x34, addr, data);
0151 }
0152 
0153 /* mute all */
0154 
0155 static void psc724_set_master_switch(struct snd_ice1712 *ice, bool on)
0156 {
0157     unsigned int bits = snd_ice1712_gpio_read(ice);
0158     struct psc724_spec *spec = ice->spec;
0159 
0160     spec->mute_all = !on;
0161     if (on)
0162         bits &= ~(GPIO_MUTE_ALL | GPIO_MUTE_SUR);
0163     else
0164         bits |= GPIO_MUTE_ALL | GPIO_MUTE_SUR;
0165     snd_ice1712_gpio_write(ice, bits);
0166 }
0167 
0168 static bool psc724_get_master_switch(struct snd_ice1712 *ice)
0169 {
0170     struct psc724_spec *spec = ice->spec;
0171 
0172     return !spec->mute_all;
0173 }
0174 
0175 /* jack detection */
0176 
0177 static void psc724_set_jack_state(struct snd_ice1712 *ice, bool hp_connected)
0178 {
0179     struct psc724_spec *spec = ice->spec;
0180     struct snd_ctl_elem_id elem_id;
0181     struct snd_kcontrol *kctl;
0182     u16 power = spec->wm8776.regs[WM8776_REG_PWRDOWN] & ~WM8776_PWR_HPPD;
0183 
0184     psc724_set_master_switch(ice, !hp_connected);
0185     if (!hp_connected)
0186         power |= WM8776_PWR_HPPD;
0187     snd_wm8776_set_power(&spec->wm8776, power);
0188     spec->hp_connected = hp_connected;
0189     /* notify about master speaker mute change */
0190     memset(&elem_id, 0, sizeof(elem_id));
0191     elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0192     strscpy(elem_id.name, "Master Speakers Playback Switch",
0193                         sizeof(elem_id.name));
0194     kctl = snd_ctl_find_id(ice->card, &elem_id);
0195     snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
0196     /* and headphone mute change */
0197     strscpy(elem_id.name, spec->wm8776.ctl[WM8776_CTL_HP_SW].name,
0198                         sizeof(elem_id.name));
0199     kctl = snd_ctl_find_id(ice->card, &elem_id);
0200     snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
0201 }
0202 
0203 static void psc724_update_hp_jack_state(struct work_struct *work)
0204 {
0205     struct psc724_spec *spec = container_of(work, struct psc724_spec,
0206                         hp_work.work);
0207     struct snd_ice1712 *ice = spec->ice;
0208     bool hp_connected = snd_ice1712_gpio_read(ice) & GPIO_HP_JACK;
0209 
0210     schedule_delayed_work(&spec->hp_work, msecs_to_jiffies(JACK_INTERVAL));
0211     if (hp_connected == spec->hp_connected)
0212         return;
0213     psc724_set_jack_state(ice, hp_connected);
0214 }
0215 
0216 static void psc724_set_jack_detection(struct snd_ice1712 *ice, bool on)
0217 {
0218     struct psc724_spec *spec = ice->spec;
0219 
0220     if (spec->jack_detect == on)
0221         return;
0222 
0223     spec->jack_detect = on;
0224     if (on) {
0225         bool hp_connected = snd_ice1712_gpio_read(ice) & GPIO_HP_JACK;
0226         psc724_set_jack_state(ice, hp_connected);
0227         schedule_delayed_work(&spec->hp_work,
0228                     msecs_to_jiffies(JACK_INTERVAL));
0229     } else
0230         cancel_delayed_work_sync(&spec->hp_work);
0231 }
0232 
0233 static bool psc724_get_jack_detection(struct snd_ice1712 *ice)
0234 {
0235     struct psc724_spec *spec = ice->spec;
0236 
0237     return spec->jack_detect;
0238 }
0239 
0240 /* mixer controls */
0241 
0242 struct psc724_control {
0243     const char *name;
0244     void (*set)(struct snd_ice1712 *ice, bool on);
0245     bool (*get)(struct snd_ice1712 *ice);
0246 };
0247 
0248 static const struct psc724_control psc724_cont[] = {
0249     {
0250         .name = "Master Speakers Playback Switch",
0251         .set = psc724_set_master_switch,
0252         .get = psc724_get_master_switch,
0253     },
0254     {
0255         .name = "Headphone Jack Detection Playback Switch",
0256         .set = psc724_set_jack_detection,
0257         .get = psc724_get_jack_detection,
0258     },
0259 };
0260 
0261 static int psc724_ctl_get(struct snd_kcontrol *kcontrol,
0262                   struct snd_ctl_elem_value *ucontrol)
0263 {
0264     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0265     int n = kcontrol->private_value;
0266 
0267     ucontrol->value.integer.value[0] = psc724_cont[n].get(ice);
0268 
0269     return 0;
0270 }
0271 
0272 static int psc724_ctl_put(struct snd_kcontrol *kcontrol,
0273                   struct snd_ctl_elem_value *ucontrol)
0274 {
0275     struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
0276     int n = kcontrol->private_value;
0277 
0278     psc724_cont[n].set(ice, ucontrol->value.integer.value[0]);
0279 
0280     return 0;
0281 }
0282 
0283 static const char *front_volume = "Front Playback Volume";
0284 static const char *front_switch = "Front Playback Switch";
0285 static const char *front_zc = "Front Zero Cross Detect Playback Switch";
0286 static const char *front_izd    = "Front Infinite Zero Detect Playback Switch";
0287 static const char *front_phase  = "Front Phase Invert Playback Switch";
0288 static const char *front_deemph = "Front Deemphasis Playback Switch";
0289 static const char *ain1_switch  = "Line Capture Switch";
0290 static const char *ain2_switch  = "CD Capture Switch";
0291 static const char *ain3_switch  = "AUX Capture Switch";
0292 static const char *ain4_switch  = "Front Mic Capture Switch";
0293 static const char *ain5_switch  = "Rear Mic Capture Switch";
0294 static const char *rear_volume  = "Surround Playback Volume";
0295 static const char *clfe_volume  = "CLFE Playback Volume";
0296 static const char *rear_switch  = "Surround Playback Switch";
0297 static const char *clfe_switch  = "CLFE Playback Switch";
0298 static const char *rear_phase   = "Surround Phase Invert Playback Switch";
0299 static const char *clfe_phase   = "CLFE Phase Invert Playback Switch";
0300 static const char *rear_deemph  = "Surround Deemphasis Playback Switch";
0301 static const char *clfe_deemph  = "CLFE Deemphasis Playback Switch";
0302 static const char *rear_clfe_izd = "Rear Infinite Zero Detect Playback Switch";
0303 static const char *rear_clfe_zc = "Rear Zero Cross Detect Playback Switch";
0304 
0305 static int psc724_add_controls(struct snd_ice1712 *ice)
0306 {
0307     struct snd_kcontrol_new cont;
0308     struct snd_kcontrol *ctl;
0309     int err, i;
0310     struct psc724_spec *spec = ice->spec;
0311 
0312     spec->wm8776.ctl[WM8776_CTL_DAC_VOL].name = front_volume;
0313     spec->wm8776.ctl[WM8776_CTL_DAC_SW].name = front_switch;
0314     spec->wm8776.ctl[WM8776_CTL_DAC_ZC_SW].name = front_zc;
0315     spec->wm8776.ctl[WM8776_CTL_AUX_SW].name = NULL;
0316     spec->wm8776.ctl[WM8776_CTL_DAC_IZD_SW].name = front_izd;
0317     spec->wm8776.ctl[WM8776_CTL_PHASE_SW].name = front_phase;
0318     spec->wm8776.ctl[WM8776_CTL_DEEMPH_SW].name = front_deemph;
0319     spec->wm8776.ctl[WM8776_CTL_INPUT1_SW].name = ain1_switch;
0320     spec->wm8776.ctl[WM8776_CTL_INPUT2_SW].name = ain2_switch;
0321     spec->wm8776.ctl[WM8776_CTL_INPUT3_SW].name = ain3_switch;
0322     spec->wm8776.ctl[WM8776_CTL_INPUT4_SW].name = ain4_switch;
0323     spec->wm8776.ctl[WM8776_CTL_INPUT5_SW].name = ain5_switch;
0324     snd_wm8776_build_controls(&spec->wm8776);
0325     spec->wm8766.ctl[WM8766_CTL_CH1_VOL].name = rear_volume;
0326     spec->wm8766.ctl[WM8766_CTL_CH2_VOL].name = clfe_volume;
0327     spec->wm8766.ctl[WM8766_CTL_CH3_VOL].name = NULL;
0328     spec->wm8766.ctl[WM8766_CTL_CH1_SW].name = rear_switch;
0329     spec->wm8766.ctl[WM8766_CTL_CH2_SW].name = clfe_switch;
0330     spec->wm8766.ctl[WM8766_CTL_CH3_SW].name = NULL;
0331     spec->wm8766.ctl[WM8766_CTL_PHASE1_SW].name = rear_phase;
0332     spec->wm8766.ctl[WM8766_CTL_PHASE2_SW].name = clfe_phase;
0333     spec->wm8766.ctl[WM8766_CTL_PHASE3_SW].name = NULL;
0334     spec->wm8766.ctl[WM8766_CTL_DEEMPH1_SW].name = rear_deemph;
0335     spec->wm8766.ctl[WM8766_CTL_DEEMPH2_SW].name = clfe_deemph;
0336     spec->wm8766.ctl[WM8766_CTL_DEEMPH3_SW].name = NULL;
0337     spec->wm8766.ctl[WM8766_CTL_IZD_SW].name = rear_clfe_izd;
0338     spec->wm8766.ctl[WM8766_CTL_ZC_SW].name = rear_clfe_zc;
0339     snd_wm8766_build_controls(&spec->wm8766);
0340 
0341     memset(&cont, 0, sizeof(cont));
0342     cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
0343     for (i = 0; i < ARRAY_SIZE(psc724_cont); i++) {
0344         cont.private_value = i;
0345         cont.name = psc724_cont[i].name;
0346         cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
0347         cont.info = snd_ctl_boolean_mono_info;
0348         cont.get = psc724_ctl_get;
0349         cont.put = psc724_ctl_put;
0350         ctl = snd_ctl_new1(&cont, ice);
0351         if (!ctl)
0352             return -ENOMEM;
0353         err = snd_ctl_add(ice->card, ctl);
0354         if (err < 0)
0355             return err;
0356     }
0357 
0358     return 0;
0359 }
0360 
0361 static void psc724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)
0362 {
0363     struct psc724_spec *spec = ice->spec;
0364     /* restore codec volume settings after rate change (PMCLK stop) */
0365     snd_wm8776_volume_restore(&spec->wm8776);
0366     snd_wm8766_volume_restore(&spec->wm8766);
0367 }
0368 
0369 /* power management */
0370 
0371 #ifdef CONFIG_PM_SLEEP
0372 static int psc724_resume(struct snd_ice1712 *ice)
0373 {
0374     struct psc724_spec *spec = ice->spec;
0375 
0376     snd_wm8776_resume(&spec->wm8776);
0377     snd_wm8766_resume(&spec->wm8766);
0378 
0379     return 0;
0380 }
0381 #endif
0382 
0383 /* init */
0384 
0385 static int psc724_init(struct snd_ice1712 *ice)
0386 {
0387     struct psc724_spec *spec;
0388 
0389     spec = kzalloc(sizeof(*spec), GFP_KERNEL);
0390     if (!spec)
0391         return -ENOMEM;
0392     ice->spec = spec;
0393     spec->ice = ice;
0394 
0395     ice->num_total_dacs = 6;
0396     ice->num_total_adcs = 2;
0397     spec->wm8776.ops.write = psc724_wm8776_write;
0398     spec->wm8776.card = ice->card;
0399     snd_wm8776_init(&spec->wm8776);
0400     spec->wm8766.ops.write = psc724_wm8766_write;
0401     spec->wm8766.card = ice->card;
0402 #ifdef CONFIG_PM_SLEEP
0403     ice->pm_resume = psc724_resume;
0404     ice->pm_suspend_enabled = 1;
0405 #endif
0406     snd_wm8766_init(&spec->wm8766);
0407     snd_wm8766_set_if(&spec->wm8766,
0408             WM8766_IF_FMT_I2S | WM8766_IF_IWL_24BIT);
0409     ice->gpio.set_pro_rate = psc724_set_pro_rate;
0410     INIT_DELAYED_WORK(&spec->hp_work, psc724_update_hp_jack_state);
0411     psc724_set_jack_detection(ice, true);
0412     return 0;
0413 }
0414 
0415 static void psc724_exit(struct snd_ice1712 *ice)
0416 {
0417     struct psc724_spec *spec = ice->spec;
0418 
0419     cancel_delayed_work_sync(&spec->hp_work);
0420 }
0421 
0422 /* PSC724 has buggy EEPROM (no 96&192kHz, all FFh GPIOs), so override it here */
0423 static const unsigned char psc724_eeprom[] = {
0424     [ICE_EEP2_SYSCONF]  = 0x42, /* 49.152MHz, 1 ADC, 3 DACs */
0425     [ICE_EEP2_ACLINK]   = 0x80, /* I2S */
0426     [ICE_EEP2_I2S]      = 0xf0, /* I2S volume, 96kHz, 24bit */
0427     [ICE_EEP2_SPDIF]    = 0xc1, /* spdif out-en, out-int, no input */
0428     /* GPIO outputs */
0429     [ICE_EEP2_GPIO_DIR2]    = 0x5f, /* MUTE_ALL,WM8766 MUTE/MODE/ML/MC/MD */
0430     /* GPIO write enable */
0431     [ICE_EEP2_GPIO_MASK]    = 0xff, /* read-only */
0432     [ICE_EEP2_GPIO_MASK1]   = 0xff, /* read-only */
0433     [ICE_EEP2_GPIO_MASK2]   = 0xa0, /* MUTE_ALL,WM8766 MUTE/MODE/ML/MC/MD */
0434     /* GPIO initial state */
0435     [ICE_EEP2_GPIO_STATE2]  = 0x20, /* unmuted, all WM8766 pins low */
0436 };
0437 
0438 struct snd_ice1712_card_info snd_vt1724_psc724_cards[] = {
0439     {
0440         .subvendor = VT1724_SUBDEVICE_PSC724,
0441         .name = "Philips PSC724 Ultimate Edge",
0442         .model = "psc724",
0443         .chip_init = psc724_init,
0444         .chip_exit = psc724_exit,
0445         .build_controls = psc724_add_controls,
0446         .eeprom_size = sizeof(psc724_eeprom),
0447         .eeprom_data = psc724_eeprom,
0448     },
0449     {} /*terminator*/
0450 };