1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Support for Digigram Lola PCI-e boards
5 * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/vmalloc.h>
12 #include <sound/core.h>
13 #include <sound/control.h>
14 #include <sound/pcm.h>
15 #include <sound/tlv.h>
18 static int lola_init_pin(struct lola
*chip
, struct lola_pin
*pin
,
25 err
= lola_read_param(chip
, nid
, LOLA_PAR_AUDIO_WIDGET_CAP
, &val
);
27 dev_err(chip
->card
->dev
, "Can't read wcaps for 0x%x\n", nid
);
30 val
&= 0x00f00fff; /* test TYPE and bits 0..11 */
31 if (val
== 0x00400200) /* Type = 4, Digital = 1 */
32 pin
->is_analog
= false;
33 else if (val
== 0x0040000a && dir
== CAPT
) /* Dig=0, InAmp/ovrd */
34 pin
->is_analog
= true;
35 else if (val
== 0x0040000c && dir
== PLAY
) /* Dig=0, OutAmp/ovrd */
36 pin
->is_analog
= true;
38 dev_err(chip
->card
->dev
, "Invalid wcaps 0x%x for 0x%x\n", val
, nid
);
42 /* analog parameters only following, so continue in case of Digital pin
48 err
= lola_read_param(chip
, nid
, LOLA_PAR_AMP_OUT_CAP
, &val
);
50 err
= lola_read_param(chip
, nid
, LOLA_PAR_AMP_IN_CAP
, &val
);
52 dev_err(chip
->card
->dev
, "Can't read AMP-caps for 0x%x\n", nid
);
56 pin
->amp_mute
= LOLA_AMP_MUTE_CAPABLE(val
);
57 pin
->amp_step_size
= LOLA_AMP_STEP_SIZE(val
);
58 pin
->amp_num_steps
= LOLA_AMP_NUM_STEPS(val
);
59 if (pin
->amp_num_steps
) {
60 /* zero as mute state */
64 pin
->amp_offset
= LOLA_AMP_OFFSET(val
);
66 err
= lola_codec_read(chip
, nid
, LOLA_VERB_GET_MAX_LEVEL
, 0, 0, &val
,
69 dev_err(chip
->card
->dev
, "Can't get MAX_LEVEL 0x%x\n", nid
);
72 pin
->max_level
= val
& 0x3ff; /* 10 bits */
74 pin
->config_default_reg
= 0;
75 pin
->fixed_gain_list_len
= 0;
76 pin
->cur_gain_step
= 0;
81 int lola_init_pins(struct lola
*chip
, int dir
, int *nidp
)
85 for (i
= 0; i
< chip
->pin
[dir
].num_pins
; i
++, nid
++) {
86 err
= lola_init_pin(chip
, &chip
->pin
[dir
].pins
[i
], dir
, nid
);
89 if (chip
->pin
[dir
].pins
[i
].is_analog
)
90 chip
->pin
[dir
].num_analog_pins
++;
96 void lola_free_mixer(struct lola
*chip
)
98 vfree(chip
->mixer
.array_saved
);
101 int lola_init_mixer_widget(struct lola
*chip
, int nid
)
106 err
= lola_read_param(chip
, nid
, LOLA_PAR_AUDIO_WIDGET_CAP
, &val
);
108 dev_err(chip
->card
->dev
, "Can't read wcaps for 0x%x\n", nid
);
112 if ((val
& 0xfff00000) != 0x02f00000) { /* test SubType and Type */
113 dev_dbg(chip
->card
->dev
, "No valid mixer widget\n");
117 chip
->mixer
.nid
= nid
;
118 chip
->mixer
.caps
= val
;
119 chip
->mixer
.array
= (struct lola_mixer_array __iomem
*)
120 (chip
->bar
[BAR1
].remap_addr
+ LOLA_BAR1_SOURCE_GAIN_ENABLE
);
122 /* reserve memory to copy mixer data for sleep mode transitions */
123 chip
->mixer
.array_saved
= vmalloc(sizeof(struct lola_mixer_array
));
124 if (!chip
->mixer
.array_saved
)
127 /* mixer matrix sources are physical input data and play streams */
128 chip
->mixer
.src_stream_outs
= chip
->pcm
[PLAY
].num_streams
;
129 chip
->mixer
.src_phys_ins
= chip
->pin
[CAPT
].num_pins
;
131 /* mixer matrix destinations are record streams and physical output */
132 chip
->mixer
.dest_stream_ins
= chip
->pcm
[CAPT
].num_streams
;
133 chip
->mixer
.dest_phys_outs
= chip
->pin
[PLAY
].num_pins
;
135 /* mixer matrix may have unused areas between PhysIn and
136 * Play or Record and PhysOut zones
138 chip
->mixer
.src_stream_out_ofs
= chip
->mixer
.src_phys_ins
+
139 LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val
);
140 chip
->mixer
.dest_phys_out_ofs
= chip
->mixer
.dest_stream_ins
+
141 LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val
);
143 /* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
144 * +-+ 0-------8------16-------8------16
146 * |s| | INPUT | | INPUT | |
147 * | |->| -> |unused | -> |unused |
148 * |r| |CAPTURE| | OUTPUT| |
149 * | | | MIX | | MIX | |
150 * |c| 8--------------------------------
153 * |g| |unused |unused |unused |unused |
156 * | | 16-------------------------------
158 * | | | PLAYBK| | PLAYBK| |
159 * |n|->| -> |unused | -> |unused |
160 * | | |CAPTURE| | OUTPUT| |
161 * | | | MIX | | MIX | |
162 * |a| 8--------------------------------
165 * |a| |unused |unused |unused |unused |
168 * +++ 16--|---------------|------------
169 * +---V---------------V-----------+
170 * | dest_mix_gain_enable array |
171 * +-------------------------------+
173 /* example : MixerMatrix of LoLa280
176 * |s| | INPUT | | INPUT
178 * |c| |CAPTURE| | <- OUTPUT
182 * |i| | PLAYBK| | PLAYBACK
184 * | | |CAPTURE| | <- OUTPUT
187 * |r| +---V----V-------------------+
188 * |a| | dest_mix_gain_enable array |
189 * |y| +----------------------------+
191 if (chip
->mixer
.src_stream_out_ofs
> MAX_AUDIO_INOUT_COUNT
||
192 chip
->mixer
.dest_phys_out_ofs
> MAX_STREAM_IN_COUNT
) {
193 dev_err(chip
->card
->dev
, "Invalid mixer widget size\n");
197 chip
->mixer
.src_mask
= ((1U << chip
->mixer
.src_phys_ins
) - 1) |
198 (((1U << chip
->mixer
.src_stream_outs
) - 1)
199 << chip
->mixer
.src_stream_out_ofs
);
200 chip
->mixer
.dest_mask
= ((1U << chip
->mixer
.dest_stream_ins
) - 1) |
201 (((1U << chip
->mixer
.dest_phys_outs
) - 1)
202 << chip
->mixer
.dest_phys_out_ofs
);
204 dev_dbg(chip
->card
->dev
, "Mixer src_mask=%x, dest_mask=%x\n",
205 chip
->mixer
.src_mask
, chip
->mixer
.dest_mask
);
210 static int lola_mixer_set_src_gain(struct lola
*chip
, unsigned int id
,
211 unsigned short gain
, bool on
)
213 unsigned int oldval
, val
;
215 if (!(chip
->mixer
.src_mask
& (1 << id
)))
217 oldval
= val
= readl(&chip
->mixer
.array
->src_gain_enable
);
222 /* test if values unchanged */
223 if ((val
== oldval
) &&
224 (gain
== readw(&chip
->mixer
.array
->src_gain
[id
])))
227 dev_dbg(chip
->card
->dev
,
228 "lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
230 writew(gain
, &chip
->mixer
.array
->src_gain
[id
]);
231 writel(val
, &chip
->mixer
.array
->src_gain_enable
);
232 lola_codec_flush(chip
);
233 /* inform micro-controller about the new source gain */
234 return lola_codec_write(chip
, chip
->mixer
.nid
,
235 LOLA_VERB_SET_SOURCE_GAIN
, id
, 0);
239 static int lola_mixer_set_src_gains(struct lola
*chip
, unsigned int mask
,
240 unsigned short *gains
)
244 if ((chip
->mixer
.src_mask
& mask
) != mask
)
246 for (i
= 0; i
< LOLA_MIXER_DIM
; i
++) {
247 if (mask
& (1 << i
)) {
248 writew(*gains
, &chip
->mixer
.array
->src_gain
[i
]);
252 writel(mask
, &chip
->mixer
.array
->src_gain_enable
);
253 lola_codec_flush(chip
);
254 if (chip
->mixer
.caps
& LOLA_PEAK_METER_CAN_AGC_MASK
) {
255 /* update for all srcs at once */
256 return lola_codec_write(chip
, chip
->mixer
.nid
,
257 LOLA_VERB_SET_SOURCE_GAIN
, 0x80, 0);
259 /* update manually */
260 for (i
= 0; i
< LOLA_MIXER_DIM
; i
++) {
261 if (mask
& (1 << i
)) {
262 lola_codec_write(chip
, chip
->mixer
.nid
,
263 LOLA_VERB_SET_SOURCE_GAIN
, i
, 0);
268 #endif /* not used */
270 static int lola_mixer_set_mapping_gain(struct lola
*chip
,
271 unsigned int src
, unsigned int dest
,
272 unsigned short gain
, bool on
)
276 if (!(chip
->mixer
.src_mask
& (1 << src
)) ||
277 !(chip
->mixer
.dest_mask
& (1 << dest
)))
280 writew(gain
, &chip
->mixer
.array
->dest_mix_gain
[dest
][src
]);
281 val
= readl(&chip
->mixer
.array
->dest_mix_gain_enable
[dest
]);
286 writel(val
, &chip
->mixer
.array
->dest_mix_gain_enable
[dest
]);
287 lola_codec_flush(chip
);
288 return lola_codec_write(chip
, chip
->mixer
.nid
, LOLA_VERB_SET_MIX_GAIN
,
293 static int lola_mixer_set_dest_gains(struct lola
*chip
, unsigned int id
,
294 unsigned int mask
, unsigned short *gains
)
298 if (!(chip
->mixer
.dest_mask
& (1 << id
)) ||
299 (chip
->mixer
.src_mask
& mask
) != mask
)
301 for (i
= 0; i
< LOLA_MIXER_DIM
; i
++) {
302 if (mask
& (1 << i
)) {
303 writew(*gains
, &chip
->mixer
.array
->dest_mix_gain
[id
][i
]);
307 writel(mask
, &chip
->mixer
.array
->dest_mix_gain_enable
[id
]);
308 lola_codec_flush(chip
);
309 /* update for all dests at once */
310 return lola_codec_write(chip
, chip
->mixer
.nid
,
311 LOLA_VERB_SET_DESTINATION_GAIN
, id
, 0);
313 #endif /* not used */
318 static int set_analog_volume(struct lola
*chip
, int dir
,
319 unsigned int idx
, unsigned int val
,
322 int lola_setup_all_analog_gains(struct lola
*chip
, int dir
, bool mute
)
324 struct lola_pin
*pin
;
327 pin
= chip
->pin
[dir
].pins
;
328 max_idx
= chip
->pin
[dir
].num_pins
;
329 for (idx
= 0; idx
< max_idx
; idx
++) {
330 if (pin
[idx
].is_analog
) {
331 unsigned int val
= mute
? 0 : pin
[idx
].cur_gain_step
;
332 /* set volume and do not save the value */
333 set_analog_volume(chip
, dir
, idx
, val
, false);
336 return lola_codec_flush(chip
);
339 void lola_save_mixer(struct lola
*chip
)
341 /* mute analog output */
342 if (chip
->mixer
.array_saved
) {
343 /* store contents of mixer array */
344 memcpy_fromio(chip
->mixer
.array_saved
, chip
->mixer
.array
,
345 sizeof(*chip
->mixer
.array
));
347 lola_setup_all_analog_gains(chip
, PLAY
, true); /* output mute */
350 void lola_restore_mixer(struct lola
*chip
)
354 /*lola_reset_setups(chip);*/
355 if (chip
->mixer
.array_saved
) {
356 /* restore contents of mixer array */
357 memcpy_toio(chip
->mixer
.array
, chip
->mixer
.array_saved
,
358 sizeof(*chip
->mixer
.array
));
359 /* inform micro-controller about all restored values
360 * and ignore return values
362 for (i
= 0; i
< chip
->mixer
.src_phys_ins
; i
++)
363 lola_codec_write(chip
, chip
->mixer
.nid
,
364 LOLA_VERB_SET_SOURCE_GAIN
,
366 for (i
= 0; i
< chip
->mixer
.src_stream_outs
; i
++)
367 lola_codec_write(chip
, chip
->mixer
.nid
,
368 LOLA_VERB_SET_SOURCE_GAIN
,
369 chip
->mixer
.src_stream_out_ofs
+ i
, 0);
370 for (i
= 0; i
< chip
->mixer
.dest_stream_ins
; i
++)
371 lola_codec_write(chip
, chip
->mixer
.nid
,
372 LOLA_VERB_SET_DESTINATION_GAIN
,
374 for (i
= 0; i
< chip
->mixer
.dest_phys_outs
; i
++)
375 lola_codec_write(chip
, chip
->mixer
.nid
,
376 LOLA_VERB_SET_DESTINATION_GAIN
,
377 chip
->mixer
.dest_phys_out_ofs
+ i
, 0);
378 lola_codec_flush(chip
);
385 static int set_analog_volume(struct lola
*chip
, int dir
,
386 unsigned int idx
, unsigned int val
,
389 struct lola_pin
*pin
;
392 if (idx
>= chip
->pin
[dir
].num_pins
)
394 pin
= &chip
->pin
[dir
].pins
[idx
];
395 if (!pin
->is_analog
|| pin
->amp_num_steps
<= val
)
397 if (external_call
&& pin
->cur_gain_step
== val
)
400 lola_codec_flush(chip
);
401 dev_dbg(chip
->card
->dev
,
402 "set_analog_volume (dir=%d idx=%d, volume=%d)\n",
404 err
= lola_codec_write(chip
, pin
->nid
,
405 LOLA_VERB_SET_AMP_GAIN_MUTE
, val
, 0);
409 pin
->cur_gain_step
= val
;
413 int lola_set_src_config(struct lola
*chip
, unsigned int src_mask
, bool update
)
419 /* SRC can be activated and the dwInputSRCMask is valid? */
420 if ((chip
->input_src_caps_mask
& src_mask
) != src_mask
)
422 /* handle all even Inputs - SRC is a stereo setting !!! */
423 for (n
= 0; n
< chip
->pin
[CAPT
].num_pins
; n
+= 2) {
424 unsigned int mask
= 3U << n
; /* handle the stereo case */
425 unsigned int new_src
, src_state
;
426 if (!(chip
->input_src_caps_mask
& mask
))
428 /* if one IO needs SRC, both stereo IO will get SRC */
429 new_src
= (src_mask
& mask
) != 0;
431 src_state
= (chip
->input_src_mask
& mask
) != 0;
432 if (src_state
== new_src
)
433 continue; /* nothing to change for this IO */
435 err
= lola_codec_write(chip
, chip
->pcm
[CAPT
].streams
[n
].nid
,
436 LOLA_VERB_SET_SRC
, new_src
, 0);
443 ret
= lola_codec_flush(chip
);
445 chip
->input_src_mask
= src_mask
;
451 static int init_mixer_values(struct lola
*chip
)
455 /* all sample rate converters on */
456 lola_set_src_config(chip
, (1 << chip
->pin
[CAPT
].num_pins
) - 1, false);
458 /* clear all mixer matrix settings */
459 memset_io(chip
->mixer
.array
, 0, sizeof(*chip
->mixer
.array
));
460 /* inform firmware about all updated matrix columns - capture part */
461 for (i
= 0; i
< chip
->mixer
.dest_stream_ins
; i
++)
462 lola_codec_write(chip
, chip
->mixer
.nid
,
463 LOLA_VERB_SET_DESTINATION_GAIN
,
465 /* inform firmware about all updated matrix columns - output part */
466 for (i
= 0; i
< chip
->mixer
.dest_phys_outs
; i
++)
467 lola_codec_write(chip
, chip
->mixer
.nid
,
468 LOLA_VERB_SET_DESTINATION_GAIN
,
469 chip
->mixer
.dest_phys_out_ofs
+ i
, 0);
471 /* set all digital input source (master) gains to 0dB */
472 for (i
= 0; i
< chip
->mixer
.src_phys_ins
; i
++)
473 lola_mixer_set_src_gain(chip
, i
, 336, true); /* 0dB */
475 /* set all digital playback source (master) gains to 0dB */
476 for (i
= 0; i
< chip
->mixer
.src_stream_outs
; i
++)
477 lola_mixer_set_src_gain(chip
,
478 i
+ chip
->mixer
.src_stream_out_ofs
,
479 336, true); /* 0dB */
480 /* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
481 for (i
= 0; i
< chip
->mixer
.dest_stream_ins
; i
++) {
482 int src
= i
% chip
->mixer
.src_phys_ins
;
483 lola_mixer_set_mapping_gain(chip
, src
, i
, 336, true);
485 /* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
486 * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
487 * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
489 for (i
= 0; i
< chip
->mixer
.src_stream_outs
; i
++) {
490 int src
= chip
->mixer
.src_stream_out_ofs
+ i
;
491 int dst
= chip
->mixer
.dest_phys_out_ofs
+
492 i
% chip
->mixer
.dest_phys_outs
;
493 lola_mixer_set_mapping_gain(chip
, src
, dst
, 336, true);
499 * analog mixer control element
501 static int lola_analog_vol_info(struct snd_kcontrol
*kcontrol
,
502 struct snd_ctl_elem_info
*uinfo
)
504 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
505 int dir
= kcontrol
->private_value
;
507 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
508 uinfo
->count
= chip
->pin
[dir
].num_pins
;
509 uinfo
->value
.integer
.min
= 0;
510 uinfo
->value
.integer
.max
= chip
->pin
[dir
].pins
[0].amp_num_steps
;
514 static int lola_analog_vol_get(struct snd_kcontrol
*kcontrol
,
515 struct snd_ctl_elem_value
*ucontrol
)
517 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
518 int dir
= kcontrol
->private_value
;
521 for (i
= 0; i
< chip
->pin
[dir
].num_pins
; i
++)
522 ucontrol
->value
.integer
.value
[i
] =
523 chip
->pin
[dir
].pins
[i
].cur_gain_step
;
527 static int lola_analog_vol_put(struct snd_kcontrol
*kcontrol
,
528 struct snd_ctl_elem_value
*ucontrol
)
530 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
531 int dir
= kcontrol
->private_value
;
534 for (i
= 0; i
< chip
->pin
[dir
].num_pins
; i
++) {
535 err
= set_analog_volume(chip
, dir
, i
,
536 ucontrol
->value
.integer
.value
[i
],
544 static int lola_analog_vol_tlv(struct snd_kcontrol
*kcontrol
, int op_flag
,
545 unsigned int size
, unsigned int __user
*tlv
)
547 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
548 int dir
= kcontrol
->private_value
;
549 unsigned int val1
, val2
;
550 struct lola_pin
*pin
;
552 if (size
< 4 * sizeof(unsigned int))
554 pin
= &chip
->pin
[dir
].pins
[0];
556 val2
= pin
->amp_step_size
* 25;
557 val1
= -1 * (int)pin
->amp_offset
* (int)val2
;
558 #ifdef TLV_DB_SCALE_MUTE
559 val2
|= TLV_DB_SCALE_MUTE
;
561 if (put_user(SNDRV_CTL_TLVT_DB_SCALE
, tlv
))
563 if (put_user(2 * sizeof(unsigned int), tlv
+ 1))
565 if (put_user(val1
, tlv
+ 2))
567 if (put_user(val2
, tlv
+ 3))
572 static struct snd_kcontrol_new lola_analog_mixer
= {
573 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
574 .access
= (SNDRV_CTL_ELEM_ACCESS_READWRITE
|
575 SNDRV_CTL_ELEM_ACCESS_TLV_READ
|
576 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK
),
577 .info
= lola_analog_vol_info
,
578 .get
= lola_analog_vol_get
,
579 .put
= lola_analog_vol_put
,
580 .tlv
.c
= lola_analog_vol_tlv
,
583 static int create_analog_mixer(struct lola
*chip
, int dir
, char *name
)
585 if (!chip
->pin
[dir
].num_pins
)
587 /* no analog volumes on digital only adapters */
588 if (chip
->pin
[dir
].num_pins
!= chip
->pin
[dir
].num_analog_pins
)
590 lola_analog_mixer
.name
= name
;
591 lola_analog_mixer
.private_value
= dir
;
592 return snd_ctl_add(chip
->card
,
593 snd_ctl_new1(&lola_analog_mixer
, chip
));
597 * Hardware sample rate converter on digital input
599 static int lola_input_src_info(struct snd_kcontrol
*kcontrol
,
600 struct snd_ctl_elem_info
*uinfo
)
602 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
604 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
605 uinfo
->count
= chip
->pin
[CAPT
].num_pins
;
606 uinfo
->value
.integer
.min
= 0;
607 uinfo
->value
.integer
.max
= 1;
611 static int lola_input_src_get(struct snd_kcontrol
*kcontrol
,
612 struct snd_ctl_elem_value
*ucontrol
)
614 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
617 for (i
= 0; i
< chip
->pin
[CAPT
].num_pins
; i
++)
618 ucontrol
->value
.integer
.value
[i
] =
619 !!(chip
->input_src_mask
& (1 << i
));
623 static int lola_input_src_put(struct snd_kcontrol
*kcontrol
,
624 struct snd_ctl_elem_value
*ucontrol
)
626 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
631 for (i
= 0; i
< chip
->pin
[CAPT
].num_pins
; i
++)
632 if (ucontrol
->value
.integer
.value
[i
])
634 return lola_set_src_config(chip
, mask
, true);
637 static const struct snd_kcontrol_new lola_input_src_mixer
= {
638 .name
= "Digital SRC Capture Switch",
639 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
640 .info
= lola_input_src_info
,
641 .get
= lola_input_src_get
,
642 .put
= lola_input_src_put
,
646 * Lola16161 or Lola881 can have Hardware sample rate converters
647 * on its digital input pins
649 static int create_input_src_mixer(struct lola
*chip
)
651 if (!chip
->input_src_caps_mask
)
654 return snd_ctl_add(chip
->card
,
655 snd_ctl_new1(&lola_input_src_mixer
, chip
));
661 static int lola_src_gain_info(struct snd_kcontrol
*kcontrol
,
662 struct snd_ctl_elem_info
*uinfo
)
664 unsigned int count
= (kcontrol
->private_value
>> 8) & 0xff;
666 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
667 uinfo
->count
= count
;
668 uinfo
->value
.integer
.min
= 0;
669 uinfo
->value
.integer
.max
= 409;
673 static int lola_src_gain_get(struct snd_kcontrol
*kcontrol
,
674 struct snd_ctl_elem_value
*ucontrol
)
676 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
677 unsigned int ofs
= kcontrol
->private_value
& 0xff;
678 unsigned int count
= (kcontrol
->private_value
>> 8) & 0xff;
679 unsigned int mask
, i
;
681 mask
= readl(&chip
->mixer
.array
->src_gain_enable
);
682 for (i
= 0; i
< count
; i
++) {
683 unsigned int idx
= ofs
+ i
;
685 if (!(chip
->mixer
.src_mask
& (1 << idx
)))
687 if (mask
& (1 << idx
))
688 val
= readw(&chip
->mixer
.array
->src_gain
[idx
]) + 1;
691 ucontrol
->value
.integer
.value
[i
] = val
;
696 static int lola_src_gain_put(struct snd_kcontrol
*kcontrol
,
697 struct snd_ctl_elem_value
*ucontrol
)
699 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
700 unsigned int ofs
= kcontrol
->private_value
& 0xff;
701 unsigned int count
= (kcontrol
->private_value
>> 8) & 0xff;
704 for (i
= 0; i
< count
; i
++) {
705 unsigned int idx
= ofs
+ i
;
706 unsigned short val
= ucontrol
->value
.integer
.value
[i
];
709 err
= lola_mixer_set_src_gain(chip
, idx
, val
, !!val
);
716 /* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
717 static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv
, -8425, 25, 1);
719 static struct snd_kcontrol_new lola_src_gain_mixer
= {
720 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
721 .access
= (SNDRV_CTL_ELEM_ACCESS_READWRITE
|
722 SNDRV_CTL_ELEM_ACCESS_TLV_READ
),
723 .info
= lola_src_gain_info
,
724 .get
= lola_src_gain_get
,
725 .put
= lola_src_gain_put
,
726 .tlv
.p
= lola_src_gain_tlv
,
729 static int create_src_gain_mixer(struct lola
*chip
,
730 int num
, int ofs
, char *name
)
732 lola_src_gain_mixer
.name
= name
;
733 lola_src_gain_mixer
.private_value
= ofs
+ (num
<< 8);
734 return snd_ctl_add(chip
->card
,
735 snd_ctl_new1(&lola_src_gain_mixer
, chip
));
740 * destination gain (matrix-like) mixer
742 static int lola_dest_gain_info(struct snd_kcontrol
*kcontrol
,
743 struct snd_ctl_elem_info
*uinfo
)
745 unsigned int src_num
= (kcontrol
->private_value
>> 8) & 0xff;
747 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
748 uinfo
->count
= src_num
;
749 uinfo
->value
.integer
.min
= 0;
750 uinfo
->value
.integer
.max
= 433;
754 static int lola_dest_gain_get(struct snd_kcontrol
*kcontrol
,
755 struct snd_ctl_elem_value
*ucontrol
)
757 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
758 unsigned int src_ofs
= kcontrol
->private_value
& 0xff;
759 unsigned int src_num
= (kcontrol
->private_value
>> 8) & 0xff;
760 unsigned int dst_ofs
= (kcontrol
->private_value
>> 16) & 0xff;
761 unsigned int dst
, mask
, i
;
763 dst
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + dst_ofs
;
764 mask
= readl(&chip
->mixer
.array
->dest_mix_gain_enable
[dst
]);
765 for (i
= 0; i
< src_num
; i
++) {
766 unsigned int src
= src_ofs
+ i
;
768 if (!(chip
->mixer
.src_mask
& (1 << src
)))
770 if (mask
& (1 << dst
))
771 val
= readw(&chip
->mixer
.array
->dest_mix_gain
[dst
][src
]) + 1;
774 ucontrol
->value
.integer
.value
[i
] = val
;
779 static int lola_dest_gain_put(struct snd_kcontrol
*kcontrol
,
780 struct snd_ctl_elem_value
*ucontrol
)
782 struct lola
*chip
= snd_kcontrol_chip(kcontrol
);
783 unsigned int src_ofs
= kcontrol
->private_value
& 0xff;
784 unsigned int src_num
= (kcontrol
->private_value
>> 8) & 0xff;
785 unsigned int dst_ofs
= (kcontrol
->private_value
>> 16) & 0xff;
786 unsigned int dst
, mask
;
787 unsigned short gains
[MAX_STREAM_COUNT
];
792 for (i
= 0; i
< src_num
; i
++) {
793 unsigned short val
= ucontrol
->value
.integer
.value
[i
];
795 gains
[num
++] = val
- 1;
800 dst
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
) + dst_ofs
;
801 return lola_mixer_set_dest_gains(chip
, dst
, mask
, gains
);
804 static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv
, -8425, 25, 1);
806 static struct snd_kcontrol_new lola_dest_gain_mixer
= {
807 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
808 .access
= (SNDRV_CTL_ELEM_ACCESS_READWRITE
|
809 SNDRV_CTL_ELEM_ACCESS_TLV_READ
),
810 .info
= lola_dest_gain_info
,
811 .get
= lola_dest_gain_get
,
812 .put
= lola_dest_gain_put
,
813 .tlv
.p
= lola_dest_gain_tlv
,
816 static int create_dest_gain_mixer(struct lola
*chip
,
817 int src_num
, int src_ofs
,
818 int num
, int ofs
, char *name
)
820 lola_dest_gain_mixer
.count
= num
;
821 lola_dest_gain_mixer
.name
= name
;
822 lola_dest_gain_mixer
.private_value
=
823 src_ofs
+ (src_num
<< 8) + (ofs
<< 16) + (num
<< 24);
824 return snd_ctl_add(chip
->card
,
825 snd_ctl_new1(&lola_dest_gain_mixer
, chip
));
827 #endif /* not used */
831 int lola_create_mixer(struct lola
*chip
)
835 err
= create_analog_mixer(chip
, PLAY
, "Analog Playback Volume");
838 err
= create_analog_mixer(chip
, CAPT
, "Analog Capture Volume");
841 err
= create_input_src_mixer(chip
);
844 err
= create_src_gain_mixer(chip
, chip
->mixer
.src_phys_ins
, 0,
845 "Digital Capture Volume");
848 err
= create_src_gain_mixer(chip
, chip
->mixer
.src_stream_outs
,
849 chip
->mixer
.src_stream_out_ofs
,
850 "Digital Playback Volume");
854 /* FIXME: buggy mixer matrix handling */
855 err
= create_dest_gain_mixer(chip
,
856 chip
->mixer
.src_phys_ins
, 0,
857 chip
->mixer
.dest_stream_ins
, 0,
858 "Line Capture Volume");
861 err
= create_dest_gain_mixer(chip
,
862 chip
->mixer
.src_stream_outs
,
863 chip
->mixer
.src_stream_out_ofs
,
864 chip
->mixer
.dest_stream_ins
, 0,
865 "Stream-Loopback Capture Volume");
868 err
= create_dest_gain_mixer(chip
,
869 chip
->mixer
.src_phys_ins
, 0,
870 chip
->mixer
.dest_phys_outs
,
871 chip
->mixer
.dest_phys_out_ofs
,
872 "Line-Loopback Playback Volume");
875 err
= create_dest_gain_mixer(chip
,
876 chip
->mixer
.src_stream_outs
,
877 chip
->mixer
.src_stream_out_ofs
,
878 chip
->mixer
.dest_phys_outs
,
879 chip
->mixer
.dest_phys_out_ofs
,
880 "Stream Playback Volume");
884 return init_mixer_values(chip
);