Merge tag 'asoc-fix-v5.6-rc4' of https://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / sound / pci / ice1712 / maya44.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
4  *
5  *   Lowlevel functions for ESI Maya44 cards
6  *
7  *      Copyright (c) 2009 Takashi Iwai <tiwai@suse.de>
8  *      Based on the patches by Rainer Zimmermann <mail@lightshed.de>
9  */
10
11 #include <linux/init.h>
12 #include <linux/slab.h>
13 #include <sound/core.h>
14 #include <sound/control.h>
15 #include <sound/pcm.h>
16 #include <sound/tlv.h>
17
18 #include "ice1712.h"
19 #include "envy24ht.h"
20 #include "maya44.h"
21
22 /* WM8776 register indexes */
23 #define WM8776_REG_HEADPHONE_L          0x00
24 #define WM8776_REG_HEADPHONE_R          0x01
25 #define WM8776_REG_HEADPHONE_MASTER     0x02
26 #define WM8776_REG_DAC_ATTEN_L          0x03
27 #define WM8776_REG_DAC_ATTEN_R          0x04
28 #define WM8776_REG_DAC_ATTEN_MASTER     0x05
29 #define WM8776_REG_DAC_PHASE            0x06
30 #define WM8776_REG_DAC_CONTROL          0x07
31 #define WM8776_REG_DAC_MUTE             0x08
32 #define WM8776_REG_DAC_DEEMPH           0x09
33 #define WM8776_REG_DAC_IF_CONTROL       0x0a
34 #define WM8776_REG_ADC_IF_CONTROL       0x0b
35 #define WM8776_REG_MASTER_MODE_CONTROL  0x0c
36 #define WM8776_REG_POWERDOWN            0x0d
37 #define WM8776_REG_ADC_ATTEN_L          0x0e
38 #define WM8776_REG_ADC_ATTEN_R          0x0f
39 #define WM8776_REG_ADC_ALC1             0x10
40 #define WM8776_REG_ADC_ALC2             0x11
41 #define WM8776_REG_ADC_ALC3             0x12
42 #define WM8776_REG_ADC_NOISE_GATE       0x13
43 #define WM8776_REG_ADC_LIMITER          0x14
44 #define WM8776_REG_ADC_MUX              0x15
45 #define WM8776_REG_OUTPUT_MUX           0x16
46 #define WM8776_REG_RESET                0x17
47
48 #define WM8776_NUM_REGS                 0x18
49
50 /* clock ratio identifiers for snd_wm8776_set_rate() */
51 #define WM8776_CLOCK_RATIO_128FS        0
52 #define WM8776_CLOCK_RATIO_192FS        1
53 #define WM8776_CLOCK_RATIO_256FS        2
54 #define WM8776_CLOCK_RATIO_384FS        3
55 #define WM8776_CLOCK_RATIO_512FS        4
56 #define WM8776_CLOCK_RATIO_768FS        5
57
58 enum { WM_VOL_HP, WM_VOL_DAC, WM_VOL_ADC, WM_NUM_VOLS };
59 enum { WM_SW_DAC, WM_SW_BYPASS, WM_NUM_SWITCHES };
60
61 struct snd_wm8776 {
62         unsigned char addr;
63         unsigned short regs[WM8776_NUM_REGS];
64         unsigned char volumes[WM_NUM_VOLS][2];
65         unsigned int switch_bits;
66 };
67
68 struct snd_maya44 {
69         struct snd_ice1712 *ice;
70         struct snd_wm8776 wm[2];
71         struct mutex mutex;
72 };
73
74
75 /* write the given register and save the data to the cache */
76 static void wm8776_write(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
77                          unsigned char reg, unsigned short val)
78 {
79         /*
80          * WM8776 registers are up to 9 bits wide, bit 8 is placed in the LSB
81          * of the address field
82          */
83         snd_vt1724_write_i2c(ice, wm->addr,
84                              (reg << 1) | ((val >> 8) & 1),
85                              val & 0xff);
86         wm->regs[reg] = val;
87 }
88
89 /*
90  * update the given register with and/or mask and save the data to the cache
91  */
92 static int wm8776_write_bits(struct snd_ice1712 *ice, struct snd_wm8776 *wm,
93                              unsigned char reg,
94                              unsigned short mask, unsigned short val)
95 {
96         val |= wm->regs[reg] & ~mask;
97         if (val != wm->regs[reg]) {
98                 wm8776_write(ice, wm, reg, val);
99                 return 1;
100         }
101         return 0;
102 }
103
104
105 /*
106  * WM8776 volume controls
107  */
108
109 struct maya_vol_info {
110         unsigned int maxval;            /* volume range: 0..maxval */
111         unsigned char regs[2];          /* left and right registers */
112         unsigned short mask;            /* value mask */
113         unsigned short offset;          /* zero-value offset */
114         unsigned short mute;            /* mute bit */
115         unsigned short update;          /* update bits */
116         unsigned char mux_bits[2];      /* extra bits for ADC mute */
117 };
118
119 static const struct maya_vol_info vol_info[WM_NUM_VOLS] = {
120         [WM_VOL_HP] = {
121                 .maxval = 80,
122                 .regs = { WM8776_REG_HEADPHONE_L, WM8776_REG_HEADPHONE_R },
123                 .mask = 0x7f,
124                 .offset = 0x30,
125                 .mute = 0x00,
126                 .update = 0x180,        /* update and zero-cross enable */
127         },
128         [WM_VOL_DAC] = {
129                 .maxval = 255,
130                 .regs = { WM8776_REG_DAC_ATTEN_L, WM8776_REG_DAC_ATTEN_R },
131                 .mask = 0xff,
132                 .offset = 0x01,
133                 .mute = 0x00,
134                 .update = 0x100,        /* zero-cross enable */
135         },
136         [WM_VOL_ADC] = {
137                 .maxval = 91,
138                 .regs = { WM8776_REG_ADC_ATTEN_L, WM8776_REG_ADC_ATTEN_R },
139                 .mask = 0xff,
140                 .offset = 0xa5,
141                 .mute = 0xa5,
142                 .update = 0x100,        /* update */
143                 .mux_bits = { 0x80, 0x40 }, /* ADCMUX bits */
144         },
145 };
146
147 /*
148  * dB tables
149  */
150 /* headphone output: mute, -73..+6db (1db step) */
151 static const DECLARE_TLV_DB_SCALE(db_scale_hp, -7400, 100, 1);
152 /* DAC output: mute, -127..0db (0.5db step) */
153 static const DECLARE_TLV_DB_SCALE(db_scale_dac, -12750, 50, 1);
154 /* ADC gain: mute, -21..+24db (0.5db step) */
155 static const DECLARE_TLV_DB_SCALE(db_scale_adc, -2100, 50, 1);
156
157 static int maya_vol_info(struct snd_kcontrol *kcontrol,
158                          struct snd_ctl_elem_info *uinfo)
159 {
160         unsigned int idx = kcontrol->private_value;
161         const struct maya_vol_info *vol = &vol_info[idx];
162
163         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
164         uinfo->count = 2;
165         uinfo->value.integer.min = 0;
166         uinfo->value.integer.max = vol->maxval;
167         return 0;
168 }
169
170 static int maya_vol_get(struct snd_kcontrol *kcontrol,
171                         struct snd_ctl_elem_value *ucontrol)
172 {
173         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
174         struct snd_wm8776 *wm =
175                 &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
176         unsigned int idx = kcontrol->private_value;
177
178         mutex_lock(&chip->mutex);
179         ucontrol->value.integer.value[0] = wm->volumes[idx][0];
180         ucontrol->value.integer.value[1] = wm->volumes[idx][1];
181         mutex_unlock(&chip->mutex);
182         return 0;
183 }
184
185 static int maya_vol_put(struct snd_kcontrol *kcontrol,
186                         struct snd_ctl_elem_value *ucontrol)
187 {
188         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
189         struct snd_wm8776 *wm =
190                 &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
191         unsigned int idx = kcontrol->private_value;
192         const struct maya_vol_info *vol = &vol_info[idx];
193         unsigned int val, data;
194         int ch, changed = 0;
195
196         mutex_lock(&chip->mutex);
197         for (ch = 0; ch < 2; ch++) {
198                 val = ucontrol->value.integer.value[ch];
199                 if (val > vol->maxval)
200                         val = vol->maxval;
201                 if (val == wm->volumes[idx][ch])
202                         continue;
203                 if (!val)
204                         data = vol->mute;
205                 else
206                         data = (val - 1) + vol->offset;
207                 data |= vol->update;
208                 changed |= wm8776_write_bits(chip->ice, wm, vol->regs[ch],
209                                              vol->mask | vol->update, data);
210                 if (vol->mux_bits[ch])
211                         wm8776_write_bits(chip->ice, wm, WM8776_REG_ADC_MUX,
212                                           vol->mux_bits[ch],
213                                           val ? 0 : vol->mux_bits[ch]);
214                 wm->volumes[idx][ch] = val;
215         }
216         mutex_unlock(&chip->mutex);
217         return changed;
218 }
219
220 /*
221  * WM8776 switch controls
222  */
223
224 #define COMPOSE_SW_VAL(idx, reg, mask)  ((idx) | ((reg) << 8) | ((mask) << 16))
225 #define GET_SW_VAL_IDX(val)     ((val) & 0xff)
226 #define GET_SW_VAL_REG(val)     (((val) >> 8) & 0xff)
227 #define GET_SW_VAL_MASK(val)    (((val) >> 16) & 0xff)
228
229 #define maya_sw_info    snd_ctl_boolean_mono_info
230
231 static int maya_sw_get(struct snd_kcontrol *kcontrol,
232                        struct snd_ctl_elem_value *ucontrol)
233 {
234         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
235         struct snd_wm8776 *wm =
236                 &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
237         unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
238
239         ucontrol->value.integer.value[0] = (wm->switch_bits >> idx) & 1;
240         return 0;
241 }
242
243 static int maya_sw_put(struct snd_kcontrol *kcontrol,
244                        struct snd_ctl_elem_value *ucontrol)
245 {
246         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
247         struct snd_wm8776 *wm =
248                 &chip->wm[snd_ctl_get_ioff(kcontrol, &ucontrol->id)];
249         unsigned int idx = GET_SW_VAL_IDX(kcontrol->private_value);
250         unsigned int mask, val;
251         int changed;
252
253         mutex_lock(&chip->mutex);
254         mask = 1 << idx;
255         wm->switch_bits &= ~mask;
256         val = ucontrol->value.integer.value[0];
257         if (val)
258                 wm->switch_bits |= mask;
259         mask = GET_SW_VAL_MASK(kcontrol->private_value);
260         changed = wm8776_write_bits(chip->ice, wm,
261                                     GET_SW_VAL_REG(kcontrol->private_value),
262                                     mask, val ? mask : 0);
263         mutex_unlock(&chip->mutex);
264         return changed;
265 }
266
267 /*
268  * GPIO pins (known ones for maya44)
269  */
270 #define GPIO_PHANTOM_OFF        2
271 #define GPIO_MIC_RELAY          4
272 #define GPIO_SPDIF_IN_INV       5
273 #define GPIO_MUST_BE_0          7
274
275 /*
276  * GPIO switch controls
277  */
278
279 #define COMPOSE_GPIO_VAL(shift, inv)    ((shift) | ((inv) << 8))
280 #define GET_GPIO_VAL_SHIFT(val)         ((val) & 0xff)
281 #define GET_GPIO_VAL_INV(val)           (((val) >> 8) & 1)
282
283 static int maya_set_gpio_bits(struct snd_ice1712 *ice, unsigned int mask,
284                               unsigned int bits)
285 {
286         unsigned int data;
287         data = snd_ice1712_gpio_read(ice);
288         if ((data & mask) == bits)
289                 return 0;
290         snd_ice1712_gpio_write(ice, (data & ~mask) | bits);
291         return 1;
292 }
293
294 #define maya_gpio_sw_info       snd_ctl_boolean_mono_info
295
296 static int maya_gpio_sw_get(struct snd_kcontrol *kcontrol,
297                             struct snd_ctl_elem_value *ucontrol)
298 {
299         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
300         unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
301         unsigned int val;
302
303         val = (snd_ice1712_gpio_read(chip->ice) >> shift) & 1;
304         if (GET_GPIO_VAL_INV(kcontrol->private_value))
305                 val = !val;
306         ucontrol->value.integer.value[0] = val;
307         return 0;
308 }
309
310 static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol,
311                             struct snd_ctl_elem_value *ucontrol)
312 {
313         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
314         unsigned int shift = GET_GPIO_VAL_SHIFT(kcontrol->private_value);
315         unsigned int val, mask;
316         int changed;
317
318         mutex_lock(&chip->mutex);
319         mask = 1 << shift;
320         val = ucontrol->value.integer.value[0];
321         if (GET_GPIO_VAL_INV(kcontrol->private_value))
322                 val = !val;
323         val = val ? mask : 0;
324         changed = maya_set_gpio_bits(chip->ice, mask, val);
325         mutex_unlock(&chip->mutex);
326         return changed;
327 }
328
329 /*
330  * capture source selection
331  */
332
333 /* known working input slots (0-4) */
334 #define MAYA_LINE_IN    1       /* in-2 */
335 #define MAYA_MIC_IN     3       /* in-4 */
336
337 static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line)
338 {
339         wm8776_write_bits(chip->ice, &chip->wm[idx], WM8776_REG_ADC_MUX,
340                           0x1f, 1 << line);
341 }
342
343 static int maya_rec_src_info(struct snd_kcontrol *kcontrol,
344                              struct snd_ctl_elem_info *uinfo)
345 {
346         static const char * const texts[] = { "Line", "Mic" };
347
348         return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
349 }
350
351 static int maya_rec_src_get(struct snd_kcontrol *kcontrol,
352                             struct snd_ctl_elem_value *ucontrol)
353 {
354         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
355         int sel;
356
357         if (snd_ice1712_gpio_read(chip->ice) & (1 << GPIO_MIC_RELAY))
358                 sel = 1;
359         else
360                 sel = 0;
361         ucontrol->value.enumerated.item[0] = sel;
362         return 0;
363 }
364
365 static int maya_rec_src_put(struct snd_kcontrol *kcontrol,
366                             struct snd_ctl_elem_value *ucontrol)
367 {
368         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
369         int sel = ucontrol->value.enumerated.item[0];
370         int changed;
371
372         mutex_lock(&chip->mutex);
373         changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY,
374                                      sel ? (1 << GPIO_MIC_RELAY) : 0);
375         wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN);
376         mutex_unlock(&chip->mutex);
377         return changed;
378 }
379
380 /*
381  * Maya44 routing switch settings have different meanings than the standard
382  * ice1724 switches as defined in snd_vt1724_pro_route_info (ice1724.c).
383  */
384 static int maya_pb_route_info(struct snd_kcontrol *kcontrol,
385                               struct snd_ctl_elem_info *uinfo)
386 {
387         static const char * const texts[] = {
388                 "PCM Out", /* 0 */
389                 "Input 1", "Input 2", "Input 3", "Input 4"
390         };
391
392         return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
393 }
394
395 static int maya_pb_route_shift(int idx)
396 {
397         static const unsigned char shift[10] =
398                 { 8, 20, 0, 3, 11, 23, 14, 26, 17, 29 };
399         return shift[idx % 10];
400 }
401
402 static int maya_pb_route_get(struct snd_kcontrol *kcontrol,
403                              struct snd_ctl_elem_value *ucontrol)
404 {
405         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
406         int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
407         ucontrol->value.enumerated.item[0] =
408                 snd_ice1724_get_route_val(chip->ice, maya_pb_route_shift(idx));
409         return 0;
410 }
411
412 static int maya_pb_route_put(struct snd_kcontrol *kcontrol,
413                              struct snd_ctl_elem_value *ucontrol)
414 {
415         struct snd_maya44 *chip = snd_kcontrol_chip(kcontrol);
416         int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
417         return snd_ice1724_put_route_val(chip->ice,
418                                          ucontrol->value.enumerated.item[0],
419                                          maya_pb_route_shift(idx));
420 }
421
422
423 /*
424  * controls to be added
425  */
426
427 static const struct snd_kcontrol_new maya_controls[] = {
428         {
429                 .name = "Crossmix Playback Volume",
430                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
431                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
432                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
433                 .info = maya_vol_info,
434                 .get = maya_vol_get,
435                 .put = maya_vol_put,
436                 .tlv = { .p = db_scale_hp },
437                 .private_value = WM_VOL_HP,
438                 .count = 2,
439         },
440         {
441                 .name = "PCM Playback Volume",
442                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
443                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
444                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
445                 .info = maya_vol_info,
446                 .get = maya_vol_get,
447                 .put = maya_vol_put,
448                 .tlv = { .p = db_scale_dac },
449                 .private_value = WM_VOL_DAC,
450                 .count = 2,
451         },
452         {
453                 .name = "Line Capture Volume",
454                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
455                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
456                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
457                 .info = maya_vol_info,
458                 .get = maya_vol_get,
459                 .put = maya_vol_put,
460                 .tlv = { .p = db_scale_adc },
461                 .private_value = WM_VOL_ADC,
462                 .count = 2,
463         },
464         {
465                 .name = "PCM Playback Switch",
466                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
467                 .info = maya_sw_info,
468                 .get = maya_sw_get,
469                 .put = maya_sw_put,
470                 .private_value = COMPOSE_SW_VAL(WM_SW_DAC,
471                                                 WM8776_REG_OUTPUT_MUX, 0x01),
472                 .count = 2,
473         },
474         {
475                 .name = "Bypass Playback Switch",
476                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
477                 .info = maya_sw_info,
478                 .get = maya_sw_get,
479                 .put = maya_sw_put,
480                 .private_value = COMPOSE_SW_VAL(WM_SW_BYPASS,
481                                                 WM8776_REG_OUTPUT_MUX, 0x04),
482                 .count = 2,
483         },
484         {
485                 .name = "Capture Source",
486                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
487                 .info = maya_rec_src_info,
488                 .get = maya_rec_src_get,
489                 .put = maya_rec_src_put,
490         },
491         {
492                 .name = "Mic Phantom Power Switch",
493                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
494                 .info = maya_gpio_sw_info,
495                 .get = maya_gpio_sw_get,
496                 .put = maya_gpio_sw_put,
497                 .private_value = COMPOSE_GPIO_VAL(GPIO_PHANTOM_OFF, 1),
498         },
499         {
500                 .name = "SPDIF Capture Switch",
501                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
502                 .info = maya_gpio_sw_info,
503                 .get = maya_gpio_sw_get,
504                 .put = maya_gpio_sw_put,
505                 .private_value = COMPOSE_GPIO_VAL(GPIO_SPDIF_IN_INV, 1),
506         },
507         {
508                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
509                 .name = "H/W Playback Route",
510                 .info = maya_pb_route_info,
511                 .get = maya_pb_route_get,
512                 .put = maya_pb_route_put,
513                 .count = 4,  /* FIXME: do controls 5-9 have any meaning? */
514         },
515 };
516
517 static int maya44_add_controls(struct snd_ice1712 *ice)
518 {
519         int err, i;
520
521         for (i = 0; i < ARRAY_SIZE(maya_controls); i++) {
522                 err = snd_ctl_add(ice->card, snd_ctl_new1(&maya_controls[i],
523                                                           ice->spec));
524                 if (err < 0)
525                         return err;
526         }
527         return 0;
528 }
529
530
531 /*
532  * initialize a wm8776 chip
533  */
534 static void wm8776_init(struct snd_ice1712 *ice,
535                         struct snd_wm8776 *wm, unsigned int addr)
536 {
537         static const unsigned short inits_wm8776[] = {
538                 0x02, 0x100, /* R2: headphone L+R muted + update */
539                 0x05, 0x100, /* R5: DAC output L+R muted + update */
540                 0x06, 0x000, /* R6: DAC output phase normal */
541                 0x07, 0x091, /* R7: DAC enable zero cross detection,
542                                 normal output */
543                 0x08, 0x000, /* R8: DAC soft mute off */
544                 0x09, 0x000, /* R9: no deemph, DAC zero detect disabled */
545                 0x0a, 0x022, /* R10: DAC I2C mode, std polarities, 24bit */
546                 0x0b, 0x022, /* R11: ADC I2C mode, std polarities, 24bit,
547                                 highpass filter enabled */
548                 0x0c, 0x042, /* R12: ADC+DAC slave, ADC+DAC 44,1kHz */
549                 0x0d, 0x000, /* R13: all power up */
550                 0x0e, 0x100, /* R14: ADC left muted,
551                                 enable zero cross detection */
552                 0x0f, 0x100, /* R15: ADC right muted,
553                                 enable zero cross detection */
554                              /* R16: ALC...*/
555                 0x11, 0x000, /* R17: disable ALC */
556                              /* R18: ALC...*/
557                              /* R19: noise gate...*/
558                 0x15, 0x000, /* R21: ADC input mux init, mute all inputs */
559                 0x16, 0x001, /* R22: output mux, select DAC */
560                 0xff, 0xff
561         };
562
563         const unsigned short *ptr;
564         unsigned char reg;
565         unsigned short data;
566
567         wm->addr = addr;
568         /* enable DAC output; mute bypass, aux & all inputs */
569         wm->switch_bits = (1 << WM_SW_DAC);
570
571         ptr = inits_wm8776;
572         while (*ptr != 0xff) {
573                 reg = *ptr++;
574                 data = *ptr++;
575                 wm8776_write(ice, wm, reg, data);
576         }
577 }
578
579
580 /*
581  * change the rate on the WM8776 codecs.
582  * this assumes that the VT17xx's rate is changed by the calling function.
583  * NOTE: even though the WM8776's are running in slave mode and rate
584  * selection is automatic, we need to call snd_wm8776_set_rate() here
585  * to make sure some flags are set correctly.
586  */
587 static void set_rate(struct snd_ice1712 *ice, unsigned int rate)
588 {
589         struct snd_maya44 *chip = ice->spec;
590         unsigned int ratio, adc_ratio, val;
591         int i;
592
593         switch (rate) {
594         case 192000:
595                 ratio = WM8776_CLOCK_RATIO_128FS;
596                 break;
597         case 176400:
598                 ratio = WM8776_CLOCK_RATIO_128FS;
599                 break;
600         case 96000:
601                 ratio = WM8776_CLOCK_RATIO_256FS;
602                 break;
603         case 88200:
604                 ratio = WM8776_CLOCK_RATIO_384FS;
605                 break;
606         case 48000:
607                 ratio = WM8776_CLOCK_RATIO_512FS;
608                 break;
609         case 44100:
610                 ratio = WM8776_CLOCK_RATIO_512FS;
611                 break;
612         case 32000:
613                 ratio = WM8776_CLOCK_RATIO_768FS;
614                 break;
615         case 0:
616                 /* no hint - S/PDIF input is master, simply return */
617                 return;
618         default:
619                 snd_BUG();
620                 return;
621         }
622
623         /*
624          * this currently sets the same rate for ADC and DAC, but limits
625          * ADC rate to 256X (96kHz). For 256X mode (96kHz), this sets ADC
626          * oversampling to 64x, as recommended by WM8776 datasheet.
627          * Setting the rate is not really necessary in slave mode.
628          */
629         adc_ratio = ratio;
630         if (adc_ratio < WM8776_CLOCK_RATIO_256FS)
631                 adc_ratio = WM8776_CLOCK_RATIO_256FS;
632
633         val = adc_ratio;
634         if (adc_ratio == WM8776_CLOCK_RATIO_256FS)
635                 val |= 8;
636         val |= ratio << 4;
637
638         mutex_lock(&chip->mutex);
639         for (i = 0; i < 2; i++)
640                 wm8776_write_bits(ice, &chip->wm[i],
641                                   WM8776_REG_MASTER_MODE_CONTROL,
642                                   0x180, val);
643         mutex_unlock(&chip->mutex);
644 }
645
646 /*
647  * supported sample rates (to override the default one)
648  */
649
650 static const unsigned int rates[] = {
651         32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000
652 };
653
654 /* playback rates: 32..192 kHz */
655 static const struct snd_pcm_hw_constraint_list dac_rates = {
656         .count = ARRAY_SIZE(rates),
657         .list = rates,
658         .mask = 0
659 };
660
661
662 /*
663  * chip addresses on I2C bus
664  */
665 static const unsigned char wm8776_addr[2] = {
666         0x34, 0x36, /* codec 0 & 1 */
667 };
668
669 /*
670  * initialize the chip
671  */
672 static int maya44_init(struct snd_ice1712 *ice)
673 {
674         int i;
675         struct snd_maya44 *chip;
676
677         chip = kzalloc(sizeof(*chip), GFP_KERNEL);
678         if (!chip)
679                 return -ENOMEM;
680         mutex_init(&chip->mutex);
681         chip->ice = ice;
682         ice->spec = chip;
683
684         /* initialise codecs */
685         ice->num_total_dacs = 4;
686         ice->num_total_adcs = 4;
687         ice->akm_codecs = 0;
688
689         for (i = 0; i < 2; i++) {
690                 wm8776_init(ice, &chip->wm[i], wm8776_addr[i]);
691                 wm8776_select_input(chip, i, MAYA_LINE_IN);
692         }
693
694         /* set card specific rates */
695         ice->hw_rates = &dac_rates;
696
697         /* register change rate notifier */
698         ice->gpio.set_pro_rate = set_rate;
699
700         /* RDMA1 (2nd input channel) is used for ADC by default */
701         ice->force_rdma1 = 1;
702
703         /* have an own routing control */
704         ice->own_routing = 1;
705
706         return 0;
707 }
708
709
710 /*
711  * Maya44 boards don't provide the EEPROM data except for the vendor IDs.
712  * hence the driver needs to sets up it properly.
713  */
714
715 static const unsigned char maya44_eeprom[] = {
716         [ICE_EEP2_SYSCONF]     = 0x45,
717                 /* clock xin1=49.152MHz, mpu401, 2 stereo ADCs+DACs */
718         [ICE_EEP2_ACLINK]      = 0x80,
719                 /* I2S */
720         [ICE_EEP2_I2S]         = 0xf8,
721                 /* vol, 96k, 24bit, 192k */
722         [ICE_EEP2_SPDIF]       = 0xc3,
723                 /* enable spdif out, spdif out supp, spdif-in, ext spdif out */
724         [ICE_EEP2_GPIO_DIR]    = 0xff,
725         [ICE_EEP2_GPIO_DIR1]   = 0xff,
726         [ICE_EEP2_GPIO_DIR2]   = 0xff,
727         [ICE_EEP2_GPIO_MASK]   = 0/*0x9f*/,
728         [ICE_EEP2_GPIO_MASK1]  = 0/*0xff*/,
729         [ICE_EEP2_GPIO_MASK2]  = 0/*0x7f*/,
730         [ICE_EEP2_GPIO_STATE]  = (1 << GPIO_PHANTOM_OFF) |
731                         (1 << GPIO_SPDIF_IN_INV),
732         [ICE_EEP2_GPIO_STATE1] = 0x00,
733         [ICE_EEP2_GPIO_STATE2] = 0x00,
734 };
735
736 /* entry point */
737 struct snd_ice1712_card_info snd_vt1724_maya44_cards[] = {
738         {
739                 .subvendor = VT1724_SUBDEVICE_MAYA44,
740                 .name = "ESI Maya44",
741                 .model = "maya44",
742                 .chip_init = maya44_init,
743                 .build_controls = maya44_add_controls,
744                 .eeprom_size = sizeof(maya44_eeprom),
745                 .eeprom_data = maya44_eeprom,
746         },
747         { } /* terminator */
748 };