~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/ice1712/phase.c

Version: ~ [ linux-5.6-rc3 ] ~ [ linux-5.5.6 ] ~ [ linux-5.4.22 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.106 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.171 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.214 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.214 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *   ALSA driver for ICEnsemble ICE1724 (Envy24)
  3  *
  4  *   Lowlevel functions for Terratec PHASE 22
  5  *
  6  *      Copyright (c) 2005 Misha Zhilin <misha@epiphan.com>
  7  *
  8  *   This program is free software; you can redistribute it and/or modify
  9  *   it under the terms of the GNU General Public License as published by
 10  *   the Free Software Foundation; either version 2 of the License, or
 11  *   (at your option) any later version.
 12  *
 13  *   This program is distributed in the hope that it will be useful,
 14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16  *   GNU General Public License for more details.
 17  *
 18  *   You should have received a copy of the GNU General Public License
 19  *   along with this program; if not, write to the Free Software
 20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 21  *
 22  */
 23 
 24 /* PHASE 22 overview:
 25  *   Audio controller: VIA Envy24HT-S (slightly trimmed down Envy24HT, 4in/4out)
 26  *   Analog chip: AK4524 (partially via Philip's 74HCT125)
 27  *   Digital receiver: CS8414-CS (supported in this release)
 28  *              PHASE 22 revision 2.0 and Terrasoniq/Musonik TS22PCI have CS8416
 29  *              (support status unknown, please test and report)
 30  *
 31  *   Envy connects to AK4524
 32  *      - CS directly from GPIO 10
 33  *      - CCLK via 74HCT125's gate #4 from GPIO 4
 34  *      - CDTI via 74HCT125's gate #2 from GPIO 5
 35  *              CDTI may be completely blocked by 74HCT125's gate #1
 36  *              controlled by GPIO 3
 37  */
 38 
 39 /* PHASE 28 overview:
 40  *   Audio controller: VIA Envy24HT (full untrimmed version, 4in/8out)
 41  *   Analog chip: WM8770 (8 channel 192k DAC, 2 channel 96k ADC)
 42  *   Digital receiver: CS8414-CS (supported in this release)
 43  */
 44 
 45 #include <linux/delay.h>
 46 #include <linux/interrupt.h>
 47 #include <linux/init.h>
 48 #include <linux/slab.h>
 49 #include <linux/mutex.h>
 50 
 51 #include <sound/core.h>
 52 
 53 #include "ice1712.h"
 54 #include "envy24ht.h"
 55 #include "phase.h"
 56 #include <sound/tlv.h>
 57 
 58 /* AC97 register cache for Phase28 */
 59 struct phase28_spec {
 60         unsigned short master[2];
 61         unsigned short vol[8];
 62 };
 63 
 64 /* WM8770 registers */
 65 #define WM_DAC_ATTEN            0x00    /* DAC1-8 analog attenuation */
 66 #define WM_DAC_MASTER_ATTEN     0x08    /* DAC master analog attenuation */
 67 #define WM_DAC_DIG_ATTEN        0x09    /* DAC1-8 digital attenuation */
 68 #define WM_DAC_DIG_MASTER_ATTEN 0x11    /* DAC master digital attenuation */
 69 #define WM_PHASE_SWAP           0x12    /* DAC phase */
 70 #define WM_DAC_CTRL1            0x13    /* DAC control bits */
 71 #define WM_MUTE                 0x14    /* mute controls */
 72 #define WM_DAC_CTRL2            0x15    /* de-emphasis and zefo-flag */
 73 #define WM_INT_CTRL             0x16    /* interface control */
 74 #define WM_MASTER               0x17    /* master clock and mode */
 75 #define WM_POWERDOWN            0x18    /* power-down controls */
 76 #define WM_ADC_GAIN             0x19    /* ADC gain L(19)/R(1a) */
 77 #define WM_ADC_MUX              0x1b    /* input MUX */
 78 #define WM_OUT_MUX1             0x1c    /* output MUX */
 79 #define WM_OUT_MUX2             0x1e    /* output MUX */
 80 #define WM_RESET                0x1f    /* software reset */
 81 
 82 
 83 /*
 84  * Logarithmic volume values for WM8770
 85  * Computed as 20 * Log10(255 / x)
 86  */
 87 static const unsigned char wm_vol[256] = {
 88         127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24,
 89         24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18,
 90         17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14,
 91         14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
 92         11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9,
 93         9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,
 94         7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5,
 95         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 96         4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 97         3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 98         2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 99         1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
100 };
101 
102 #define WM_VOL_MAX      (sizeof(wm_vol) - 1)
103 #define WM_VOL_MUTE     0x8000
104 
105 static struct snd_akm4xxx akm_phase22 = {
106         .type = SND_AK4524,
107         .num_dacs = 2,
108         .num_adcs = 2,
109 };
110 
111 static struct snd_ak4xxx_private akm_phase22_priv = {
112         .caddr =        2,
113         .cif =          1,
114         .data_mask =    1 << 4,
115         .clk_mask =     1 << 5,
116         .cs_mask =      1 << 10,
117         .cs_addr =      1 << 10,
118         .cs_none =      0,
119         .add_flags =    1 << 3,
120         .mask_flags =   0,
121 };
122 
123 static int phase22_init(struct snd_ice1712 *ice)
124 {
125         struct snd_akm4xxx *ak;
126         int err;
127 
128         /* Configure DAC/ADC description for generic part of ice1724 */
129         switch (ice->eeprom.subvendor) {
130         case VT1724_SUBDEVICE_PHASE22:
131         case VT1724_SUBDEVICE_TS22:
132                 ice->num_total_dacs = 2;
133                 ice->num_total_adcs = 2;
134                 ice->vt1720 = 1; /* Envy24HT-S have 16 bit wide GPIO */
135                 break;
136         default:
137                 snd_BUG();
138                 return -EINVAL;
139         }
140 
141         /* Initialize analog chips */
142         ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
143         ak = ice->akm;
144         if (!ak)
145                 return -ENOMEM;
146         ice->akm_codecs = 1;
147         switch (ice->eeprom.subvendor) {
148         case VT1724_SUBDEVICE_PHASE22:
149         case VT1724_SUBDEVICE_TS22:
150                 err = snd_ice1712_akm4xxx_init(ak, &akm_phase22,
151                                                 &akm_phase22_priv, ice);
152                 if (err < 0)
153                         return err;
154                 break;
155         }
156 
157         return 0;
158 }
159 
160 static int phase22_add_controls(struct snd_ice1712 *ice)
161 {
162         int err = 0;
163 
164         switch (ice->eeprom.subvendor) {
165         case VT1724_SUBDEVICE_PHASE22:
166         case VT1724_SUBDEVICE_TS22:
167                 err = snd_ice1712_akm4xxx_build_controls(ice);
168                 if (err < 0)
169                         return err;
170         }
171         return 0;
172 }
173 
174 static unsigned char phase22_eeprom[] = {
175         [ICE_EEP2_SYSCONF]     = 0x28,  /* clock 512, mpu 401,
176                                         spdif-in/1xADC, 1xDACs */
177         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
178         [ICE_EEP2_I2S]         = 0xf0,  /* vol, 96k, 24bit */
179         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
180         [ICE_EEP2_GPIO_DIR]    = 0xff,
181         [ICE_EEP2_GPIO_DIR1]   = 0xff,
182         [ICE_EEP2_GPIO_DIR2]   = 0xff,
183         [ICE_EEP2_GPIO_MASK]   = 0x00,
184         [ICE_EEP2_GPIO_MASK1]  = 0x00,
185         [ICE_EEP2_GPIO_MASK2]  = 0x00,
186         [ICE_EEP2_GPIO_STATE]  = 0x00,
187         [ICE_EEP2_GPIO_STATE1] = 0x00,
188         [ICE_EEP2_GPIO_STATE2] = 0x00,
189 };
190 
191 static unsigned char phase28_eeprom[] = {
192         [ICE_EEP2_SYSCONF]     = 0x2b,  /* clock 512, mpu401,
193                                         spdif-in/1xADC, 4xDACs */
194         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
195         [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
196         [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
197         [ICE_EEP2_GPIO_DIR]    = 0xff,
198         [ICE_EEP2_GPIO_DIR1]   = 0xff,
199         [ICE_EEP2_GPIO_DIR2]   = 0x5f,
200         [ICE_EEP2_GPIO_MASK]   = 0x00,
201         [ICE_EEP2_GPIO_MASK1]  = 0x00,
202         [ICE_EEP2_GPIO_MASK2]  = 0x00,
203         [ICE_EEP2_GPIO_STATE]  = 0x00,
204         [ICE_EEP2_GPIO_STATE1] = 0x00,
205         [ICE_EEP2_GPIO_STATE2] = 0x00,
206 };
207 
208 /*
209  * write data in the SPI mode
210  */
211 static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs,
212                                 unsigned int data, int bits)
213 {
214         unsigned int tmp;
215         int i;
216 
217         tmp = snd_ice1712_gpio_read(ice);
218 
219         snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|
220                                         PHASE28_SPI_CLK|PHASE28_WM_CS));
221         tmp |= PHASE28_WM_RW;
222         tmp &= ~cs;
223         snd_ice1712_gpio_write(ice, tmp);
224         udelay(1);
225 
226         for (i = bits - 1; i >= 0; i--) {
227                 tmp &= ~PHASE28_SPI_CLK;
228                 snd_ice1712_gpio_write(ice, tmp);
229                 udelay(1);
230                 if (data & (1 << i))
231                         tmp |= PHASE28_SPI_MOSI;
232                 else
233                         tmp &= ~PHASE28_SPI_MOSI;
234                 snd_ice1712_gpio_write(ice, tmp);
235                 udelay(1);
236                 tmp |= PHASE28_SPI_CLK;
237                 snd_ice1712_gpio_write(ice, tmp);
238                 udelay(1);
239         }
240 
241         tmp &= ~PHASE28_SPI_CLK;
242         tmp |= cs;
243         snd_ice1712_gpio_write(ice, tmp);
244         udelay(1);
245         tmp |= PHASE28_SPI_CLK;
246         snd_ice1712_gpio_write(ice, tmp);
247         udelay(1);
248 }
249 
250 /*
251  * get the current register value of WM codec
252  */
253 static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
254 {
255         reg <<= 1;
256         return ((unsigned short)ice->akm[0].images[reg] << 8) |
257                 ice->akm[0].images[reg + 1];
258 }
259 
260 /*
261  * set the register value of WM codec
262  */
263 static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
264 {
265         phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16);
266 }
267 
268 /*
269  * set the register value of WM codec and remember it
270  */
271 static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
272 {
273         wm_put_nocache(ice, reg, val);
274         reg <<= 1;
275         ice->akm[0].images[reg] = val >> 8;
276         ice->akm[0].images[reg + 1] = val;
277 }
278 
279 static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
280                         unsigned short vol, unsigned short master)
281 {
282         unsigned char nvol;
283 
284         if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
285                 nvol = 0;
286         else
287                 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) *
288                         (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
289 
290         wm_put(ice, index, nvol);
291         wm_put_nocache(ice, index, 0x180 | nvol);
292 }
293 
294 /*
295  * DAC mute control
296  */
297 #define wm_pcm_mute_info        snd_ctl_boolean_mono_info
298 
299 static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol,
300                                 struct snd_ctl_elem_value *ucontrol)
301 {
302         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
303 
304         mutex_lock(&ice->gpio_mutex);
305         ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ?
306                                                 0 : 1;
307         mutex_unlock(&ice->gpio_mutex);
308         return 0;
309 }
310 
311 static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol,
312                                 struct snd_ctl_elem_value *ucontrol)
313 {
314         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
315         unsigned short nval, oval;
316         int change;
317 
318         snd_ice1712_save_gpio_status(ice);
319         oval = wm_get(ice, WM_MUTE);
320         nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
321         change = (nval != oval);
322         if (change)
323                 wm_put(ice, WM_MUTE, nval);
324         snd_ice1712_restore_gpio_status(ice);
325 
326         return change;
327 }
328 
329 /*
330  * Master volume attenuation mixer control
331  */
332 static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
333                                 struct snd_ctl_elem_info *uinfo)
334 {
335         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
336         uinfo->count = 2;
337         uinfo->value.integer.min = 0;
338         uinfo->value.integer.max = WM_VOL_MAX;
339         return 0;
340 }
341 
342 static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
343                                 struct snd_ctl_elem_value *ucontrol)
344 {
345         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
346         struct phase28_spec *spec = ice->spec;
347         int i;
348         for (i = 0; i < 2; i++)
349                 ucontrol->value.integer.value[i] = spec->master[i] &
350                                                         ~WM_VOL_MUTE;
351         return 0;
352 }
353 
354 static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
355                                 struct snd_ctl_elem_value *ucontrol)
356 {
357         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
358         struct phase28_spec *spec = ice->spec;
359         int ch, change = 0;
360 
361         snd_ice1712_save_gpio_status(ice);
362         for (ch = 0; ch < 2; ch++) {
363                 unsigned int vol = ucontrol->value.integer.value[ch];
364                 if (vol > WM_VOL_MAX)
365                         continue;
366                 vol |= spec->master[ch] & WM_VOL_MUTE;
367                 if (vol != spec->master[ch]) {
368                         int dac;
369                         spec->master[ch] = vol;
370                         for (dac = 0; dac < ice->num_total_dacs; dac += 2)
371                                 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
372                                            spec->vol[dac + ch],
373                                            spec->master[ch]);
374                         change = 1;
375                 }
376         }
377         snd_ice1712_restore_gpio_status(ice);
378         return change;
379 }
380 
381 static int phase28_init(struct snd_ice1712 *ice)
382 {
383         static const unsigned short wm_inits_phase28[] = {
384                 /* These come first to reduce init pop noise */
385                 0x1b, 0x044,    /* ADC Mux (AC'97 source) */
386                 0x1c, 0x00B,    /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
387                 0x1d, 0x009,    /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
388 
389                 0x18, 0x000,    /* All power-up */
390 
391                 0x16, 0x122,    /* I2S, normal polarity, 24bit */
392                 0x17, 0x022,    /* 256fs, slave mode */
393                 0x00, 0,        /* DAC1 analog mute */
394                 0x01, 0,        /* DAC2 analog mute */
395                 0x02, 0,        /* DAC3 analog mute */
396                 0x03, 0,        /* DAC4 analog mute */
397                 0x04, 0,        /* DAC5 analog mute */
398                 0x05, 0,        /* DAC6 analog mute */
399                 0x06, 0,        /* DAC7 analog mute */
400                 0x07, 0,        /* DAC8 analog mute */
401                 0x08, 0x100,    /* master analog mute */
402                 0x09, 0xff,     /* DAC1 digital full */
403                 0x0a, 0xff,     /* DAC2 digital full */
404                 0x0b, 0xff,     /* DAC3 digital full */
405                 0x0c, 0xff,     /* DAC4 digital full */
406                 0x0d, 0xff,     /* DAC5 digital full */
407                 0x0e, 0xff,     /* DAC6 digital full */
408                 0x0f, 0xff,     /* DAC7 digital full */
409                 0x10, 0xff,     /* DAC8 digital full */
410                 0x11, 0x1ff,    /* master digital full */
411                 0x12, 0x000,    /* phase normal */
412                 0x13, 0x090,    /* unmute DAC L/R */
413                 0x14, 0x000,    /* all unmute */
414                 0x15, 0x000,    /* no deemphasis, no ZFLG */
415                 0x19, 0x000,    /* -12dB ADC/L */
416                 0x1a, 0x000,    /* -12dB ADC/R */
417                 (unsigned short)-1
418         };
419 
420         unsigned int tmp;
421         struct snd_akm4xxx *ak;
422         struct phase28_spec *spec;
423         const unsigned short *p;
424         int i;
425 
426         ice->num_total_dacs = 8;
427         ice->num_total_adcs = 2;
428 
429         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
430         if (!spec)
431                 return -ENOMEM;
432         ice->spec = spec;
433 
434         /* Initialize analog chips */
435         ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
436         ak = ice->akm;
437         if (!ak)
438                 return -ENOMEM;
439         ice->akm_codecs = 1;
440 
441         snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for time being */
442 
443         /* reset the wm codec as the SPI mode */
444         snd_ice1712_save_gpio_status(ice);
445         snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|
446                                         PHASE28_HP_SEL));
447 
448         tmp = snd_ice1712_gpio_read(ice);
449         tmp &= ~PHASE28_WM_RESET;
450         snd_ice1712_gpio_write(ice, tmp);
451         udelay(1);
452         tmp |= PHASE28_WM_CS;
453         snd_ice1712_gpio_write(ice, tmp);
454         udelay(1);
455         tmp |= PHASE28_WM_RESET;
456         snd_ice1712_gpio_write(ice, tmp);
457         udelay(1);
458 
459         p = wm_inits_phase28;
460         for (; *p != (unsigned short)-1; p += 2)
461                 wm_put(ice, p[0], p[1]);
462 
463         snd_ice1712_restore_gpio_status(ice);
464 
465         spec->master[0] = WM_VOL_MUTE;
466         spec->master[1] = WM_VOL_MUTE;
467         for (i = 0; i < ice->num_total_dacs; i++) {
468                 spec->vol[i] = WM_VOL_MUTE;
469                 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
470         }
471 
472         return 0;
473 }
474 
475 /*
476  * DAC volume attenuation mixer control
477  */
478 static int wm_vol_info(struct snd_kcontrol *kcontrol,
479                         struct snd_ctl_elem_info *uinfo)
480 {
481         int voices = kcontrol->private_value >> 8;
482         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
483         uinfo->count = voices;
484         uinfo->value.integer.min = 0;           /* mute (-101dB) */
485         uinfo->value.integer.max = 0x7F;        /* 0dB */
486         return 0;
487 }
488 
489 static int wm_vol_get(struct snd_kcontrol *kcontrol,
490                         struct snd_ctl_elem_value *ucontrol)
491 {
492         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
493         struct phase28_spec *spec = ice->spec;
494         int i, ofs, voices;
495 
496         voices = kcontrol->private_value >> 8;
497         ofs = kcontrol->private_value & 0xff;
498         for (i = 0; i < voices; i++)
499                 ucontrol->value.integer.value[i] =
500                         spec->vol[ofs+i] & ~WM_VOL_MUTE;
501         return 0;
502 }
503 
504 static int wm_vol_put(struct snd_kcontrol *kcontrol,
505                         struct snd_ctl_elem_value *ucontrol)
506 {
507         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
508         struct phase28_spec *spec = ice->spec;
509         int i, idx, ofs, voices;
510         int change = 0;
511 
512         voices = kcontrol->private_value >> 8;
513         ofs = kcontrol->private_value & 0xff;
514         snd_ice1712_save_gpio_status(ice);
515         for (i = 0; i < voices; i++) {
516                 unsigned int vol;
517                 vol = ucontrol->value.integer.value[i];
518                 if (vol > 0x7f)
519                         continue;
520                 vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
521                 if (vol != spec->vol[ofs+i]) {
522                         spec->vol[ofs+i] = vol;
523                         idx  = WM_DAC_ATTEN + ofs + i;
524                         wm_set_vol(ice, idx, spec->vol[ofs+i],
525                                    spec->master[i]);
526                         change = 1;
527                 }
528         }
529         snd_ice1712_restore_gpio_status(ice);
530         return change;
531 }
532 
533 /*
534  * WM8770 mute control
535  */
536 static int wm_mute_info(struct snd_kcontrol *kcontrol,
537                         struct snd_ctl_elem_info *uinfo) {
538         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
539         uinfo->count = kcontrol->private_value >> 8;
540         uinfo->value.integer.min = 0;
541         uinfo->value.integer.max = 1;
542         return 0;
543 }
544 
545 static int wm_mute_get(struct snd_kcontrol *kcontrol,
546                         struct snd_ctl_elem_value *ucontrol)
547 {
548         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
549         struct phase28_spec *spec = ice->spec;
550         int voices, ofs, i;
551 
552         voices = kcontrol->private_value >> 8;
553         ofs = kcontrol->private_value & 0xFF;
554 
555         for (i = 0; i < voices; i++)
556                 ucontrol->value.integer.value[i] =
557                         (spec->vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
558         return 0;
559 }
560 
561 static int wm_mute_put(struct snd_kcontrol *kcontrol,
562                         struct snd_ctl_elem_value *ucontrol)
563 {
564         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
565         struct phase28_spec *spec = ice->spec;
566         int change = 0, voices, ofs, i;
567 
568         voices = kcontrol->private_value >> 8;
569         ofs = kcontrol->private_value & 0xFF;
570 
571         snd_ice1712_save_gpio_status(ice);
572         for (i = 0; i < voices; i++) {
573                 int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
574                 if (ucontrol->value.integer.value[i] != val) {
575                         spec->vol[ofs + i] &= ~WM_VOL_MUTE;
576                         spec->vol[ofs + i] |=
577                                 ucontrol->value.integer.value[i] ? 0 :
578                                 WM_VOL_MUTE;
579                         wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
580                                         spec->master[i]);
581                         change = 1;
582                 }
583         }
584         snd_ice1712_restore_gpio_status(ice);
585 
586         return change;
587 }
588 
589 /*
590  * WM8770 master mute control
591  */
592 #define wm_master_mute_info             snd_ctl_boolean_stereo_info
593 
594 static int wm_master_mute_get(struct snd_kcontrol *kcontrol,
595                                 struct snd_ctl_elem_value *ucontrol)
596 {
597         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
598         struct phase28_spec *spec = ice->spec;
599 
600         ucontrol->value.integer.value[0] =
601                 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
602         ucontrol->value.integer.value[1] =
603                 (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
604         return 0;
605 }
606 
607 static int wm_master_mute_put(struct snd_kcontrol *kcontrol,
608                                 struct snd_ctl_elem_value *ucontrol)
609 {
610         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
611         struct phase28_spec *spec = ice->spec;
612         int change = 0, i;
613 
614         snd_ice1712_save_gpio_status(ice);
615         for (i = 0; i < 2; i++) {
616                 int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
617                 if (ucontrol->value.integer.value[i] != val) {
618                         int dac;
619                         spec->master[i] &= ~WM_VOL_MUTE;
620                         spec->master[i] |=
621                                 ucontrol->value.integer.value[i] ? 0 :
622                                 WM_VOL_MUTE;
623                         for (dac = 0; dac < ice->num_total_dacs; dac += 2)
624                                 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
625                                                 spec->vol[dac + i],
626                                                 spec->master[i]);
627                         change = 1;
628                 }
629         }
630         snd_ice1712_restore_gpio_status(ice);
631 
632         return change;
633 }
634 
635 /* digital master volume */
636 #define PCM_0dB 0xff
637 #define PCM_RES 128     /* -64dB */
638 #define PCM_MIN (PCM_0dB - PCM_RES)
639 static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol,
640                                 struct snd_ctl_elem_info *uinfo)
641 {
642         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
643         uinfo->count = 1;
644         uinfo->value.integer.min = 0;           /* mute (-64dB) */
645         uinfo->value.integer.max = PCM_RES;     /* 0dB */
646         return 0;
647 }
648 
649 static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol,
650                                 struct snd_ctl_elem_value *ucontrol)
651 {
652         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
653         unsigned short val;
654 
655         mutex_lock(&ice->gpio_mutex);
656         val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
657         val = val > PCM_MIN ? (val - PCM_MIN) : 0;
658         ucontrol->value.integer.value[0] = val;
659         mutex_unlock(&ice->gpio_mutex);
660         return 0;
661 }
662 
663 static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol,
664                                 struct snd_ctl_elem_value *ucontrol)
665 {
666         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
667         unsigned short ovol, nvol;
668         int change = 0;
669 
670         nvol = ucontrol->value.integer.value[0];
671         if (nvol > PCM_RES)
672                 return -EINVAL;
673         snd_ice1712_save_gpio_status(ice);
674         nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
675         ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
676         if (ovol != nvol) {
677                 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
678                 /* update */
679                 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100);
680                 change = 1;
681         }
682         snd_ice1712_restore_gpio_status(ice);
683         return change;
684 }
685 
686 /*
687  * Deemphasis
688  */
689 #define phase28_deemp_info      snd_ctl_boolean_mono_info
690 
691 static int phase28_deemp_get(struct snd_kcontrol *kcontrol,
692                                 struct snd_ctl_elem_value *ucontrol)
693 {
694         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
695         ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) ==
696                                                 0xf;
697         return 0;
698 }
699 
700 static int phase28_deemp_put(struct snd_kcontrol *kcontrol,
701                                 struct snd_ctl_elem_value *ucontrol)
702 {
703         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
704         int temp, temp2;
705         temp = wm_get(ice, WM_DAC_CTRL2);
706         temp2 = temp;
707         if (ucontrol->value.integer.value[0])
708                 temp |= 0xf;
709         else
710                 temp &= ~0xf;
711         if (temp != temp2) {
712                 wm_put(ice, WM_DAC_CTRL2, temp);
713                 return 1;
714         }
715         return 0;
716 }
717 
718 /*
719  * ADC Oversampling
720  */
721 static int phase28_oversampling_info(struct snd_kcontrol *k,
722                                         struct snd_ctl_elem_info *uinfo)
723 {
724         static const char * const texts[2] = { "128x", "64x"    };
725 
726         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
727         uinfo->count = 1;
728         uinfo->value.enumerated.items = 2;
729 
730         if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
731                 uinfo->value.enumerated.item = uinfo->value.enumerated.items -
732                                                 1;
733         strcpy(uinfo->value.enumerated.name,
734                 texts[uinfo->value.enumerated.item]);
735 
736         return 0;
737 }
738 
739 static int phase28_oversampling_get(struct snd_kcontrol *kcontrol,
740                                         struct snd_ctl_elem_value *ucontrol)
741 {
742         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
743         ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) ==
744                                                 0x8;
745         return 0;
746 }
747 
748 static int phase28_oversampling_put(struct snd_kcontrol *kcontrol,
749                                         struct snd_ctl_elem_value *ucontrol)
750 {
751         int temp, temp2;
752         struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
753 
754         temp = wm_get(ice, WM_MASTER);
755         temp2 = temp;
756 
757         if (ucontrol->value.enumerated.item[0])
758                 temp |= 0x8;
759         else
760                 temp &= ~0x8;
761 
762         if (temp != temp2) {
763                 wm_put(ice, WM_MASTER, temp);
764                 return 1;
765         }
766         return 0;
767 }
768 
769 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
770 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
771 
772 static struct snd_kcontrol_new phase28_dac_controls[] = {
773         {
774                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
775                 .name = "Master Playback Switch",
776                 .info = wm_master_mute_info,
777                 .get = wm_master_mute_get,
778                 .put = wm_master_mute_put
779         },
780         {
781                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
782                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
783                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
784                 .name = "Master Playback Volume",
785                 .info = wm_master_vol_info,
786                 .get = wm_master_vol_get,
787                 .put = wm_master_vol_put,
788                 .tlv = { .p = db_scale_wm_dac }
789         },
790         {
791                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
792                 .name = "Front Playback Switch",
793                 .info = wm_mute_info,
794                 .get = wm_mute_get,
795                 .put = wm_mute_put,
796                 .private_value = (2 << 8) | 0
797         },
798         {
799                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
800                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
801                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
802                 .name = "Front Playback Volume",
803                 .info = wm_vol_info,
804                 .get = wm_vol_get,
805                 .put = wm_vol_put,
806                 .private_value = (2 << 8) | 0,
807                 .tlv = { .p = db_scale_wm_dac }
808         },
809         {
810                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
811                 .name = "Rear Playback Switch",
812                 .info = wm_mute_info,
813                 .get = wm_mute_get,
814                 .put = wm_mute_put,
815                 .private_value = (2 << 8) | 2
816         },
817         {
818                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
819                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
820                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
821                 .name = "Rear Playback Volume",
822                 .info = wm_vol_info,
823                 .get = wm_vol_get,
824                 .put = wm_vol_put,
825                 .private_value = (2 << 8) | 2,
826                 .tlv = { .p = db_scale_wm_dac }
827         },
828         {
829                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
830                 .name = "Center Playback Switch",
831                 .info = wm_mute_info,
832                 .get = wm_mute_get,
833                 .put = wm_mute_put,
834                 .private_value = (1 << 8) | 4
835         },
836         {
837                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
838                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
839                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
840                 .name = "Center Playback Volume",
841                 .info = wm_vol_info,
842                 .get = wm_vol_get,
843                 .put = wm_vol_put,
844                 .private_value = (1 << 8) | 4,
845                 .tlv = { .p = db_scale_wm_dac }
846         },
847         {
848                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
849                 .name = "LFE Playback Switch",
850                 .info = wm_mute_info,
851                 .get = wm_mute_get,
852                 .put = wm_mute_put,
853                 .private_value = (1 << 8) | 5
854         },
855         {
856                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
857                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
858                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
859                 .name = "LFE Playback Volume",
860                 .info = wm_vol_info,
861                 .get = wm_vol_get,
862                 .put = wm_vol_put,
863                 .private_value = (1 << 8) | 5,
864                 .tlv = { .p = db_scale_wm_dac }
865         },
866         {
867                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
868                 .name = "Side Playback Switch",
869                 .info = wm_mute_info,
870                 .get = wm_mute_get,
871                 .put = wm_mute_put,
872                 .private_value = (2 << 8) | 6
873         },
874         {
875                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
876                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
877                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
878                 .name = "Side Playback Volume",
879                 .info = wm_vol_info,
880                 .get = wm_vol_get,
881                 .put = wm_vol_put,
882                 .private_value = (2 << 8) | 6,
883                 .tlv = { .p = db_scale_wm_dac }
884         }
885 };
886 
887 static struct snd_kcontrol_new wm_controls[] = {
888         {
889                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
890                 .name = "PCM Playback Switch",
891                 .info = wm_pcm_mute_info,
892                 .get = wm_pcm_mute_get,
893                 .put = wm_pcm_mute_put
894         },
895         {
896                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
897                 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
898                            SNDRV_CTL_ELEM_ACCESS_TLV_READ),
899                 .name = "PCM Playback Volume",
900                 .info = wm_pcm_vol_info,
901                 .get = wm_pcm_vol_get,
902                 .put = wm_pcm_vol_put,
903                 .tlv = { .p = db_scale_wm_pcm }
904         },
905         {
906                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
907                 .name = "DAC Deemphasis Switch",
908                 .info = phase28_deemp_info,
909                 .get = phase28_deemp_get,
910                 .put = phase28_deemp_put
911         },
912         {
913                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
914                 .name = "ADC Oversampling",
915                 .info = phase28_oversampling_info,
916                 .get = phase28_oversampling_get,
917                 .put = phase28_oversampling_put
918         }
919 };
920 
921 static int phase28_add_controls(struct snd_ice1712 *ice)
922 {
923         unsigned int i, counts;
924         int err;
925 
926         counts = ARRAY_SIZE(phase28_dac_controls);
927         for (i = 0; i < counts; i++) {
928                 err = snd_ctl_add(ice->card,
929                                         snd_ctl_new1(&phase28_dac_controls[i],
930                                                         ice));
931                 if (err < 0)
932                         return err;
933         }
934 
935         for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
936                 err = snd_ctl_add(ice->card,
937                                         snd_ctl_new1(&wm_controls[i], ice));
938                 if (err < 0)
939                         return err;
940         }
941 
942         return 0;
943 }
944 
945 struct snd_ice1712_card_info snd_vt1724_phase_cards[] = {
946         {
947                 .subvendor = VT1724_SUBDEVICE_PHASE22,
948                 .name = "Terratec PHASE 22",
949                 .model = "phase22",
950                 .chip_init = phase22_init,
951                 .build_controls = phase22_add_controls,
952                 .eeprom_size = sizeof(phase22_eeprom),
953                 .eeprom_data = phase22_eeprom,
954         },
955         {
956                 .subvendor = VT1724_SUBDEVICE_PHASE28,
957                 .name = "Terratec PHASE 28",
958                 .model = "phase28",
959                 .chip_init = phase28_init,
960                 .build_controls = phase28_add_controls,
961                 .eeprom_size = sizeof(phase28_eeprom),
962                 .eeprom_data = phase28_eeprom,
963         },
964         {
965                 .subvendor = VT1724_SUBDEVICE_TS22,
966                 .name = "Terrasoniq TS22 PCI",
967                 .model = "TS22",
968                 .chip_init = phase22_init,
969                 .build_controls = phase22_add_controls,
970                 .eeprom_size = sizeof(phase22_eeprom),
971                 .eeprom_data = phase22_eeprom,
972         },
973         { } /* terminator */
974 };
975 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp