0001
0002
0003
0004
0005
0006
0007
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
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
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
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
0130 udelay(PSC724_SPI_DELAY);
0131 bits |= PSC724_SPI_CLK;
0132 snd_ice1712_gpio_write(ice, bits);
0133 }
0134
0135 udelay(PSC724_SPI_DELAY);
0136 bits |= PSC724_SPI_LOAD;
0137 snd_ice1712_gpio_write(ice, bits);
0138
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
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
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
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
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
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
0365 snd_wm8776_volume_restore(&spec->wm8776);
0366 snd_wm8766_volume_restore(&spec->wm8766);
0367 }
0368
0369
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
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
0423 static const unsigned char psc724_eeprom[] = {
0424 [ICE_EEP2_SYSCONF] = 0x42,
0425 [ICE_EEP2_ACLINK] = 0x80,
0426 [ICE_EEP2_I2S] = 0xf0,
0427 [ICE_EEP2_SPDIF] = 0xc1,
0428
0429 [ICE_EEP2_GPIO_DIR2] = 0x5f,
0430
0431 [ICE_EEP2_GPIO_MASK] = 0xff,
0432 [ICE_EEP2_GPIO_MASK1] = 0xff,
0433 [ICE_EEP2_GPIO_MASK2] = 0xa0,
0434
0435 [ICE_EEP2_GPIO_STATE2] = 0x20,
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 {}
0450 };