xref: /kernel/linux/linux-5.10/sound/pci/ice1712/wtm.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 *	ALSA driver for ICEnsemble VT1724 (Envy24HT)
4 *
5 *	Lowlevel functions for Ego Sys Waveterminal 192M
6 *
7 *		Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com>
8 *		Some functions are taken from the Prodigy192 driver
9 *		source
10 */
11
12
13
14#include <linux/delay.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <sound/core.h>
18#include <sound/tlv.h>
19#include <linux/slab.h>
20
21#include "ice1712.h"
22#include "envy24ht.h"
23#include "wtm.h"
24#include "stac946x.h"
25
26struct wtm_spec {
27	/* rate change needs atomic mute/unmute of all dacs*/
28	struct mutex mute_mutex;
29};
30
31
32/*
33 *	2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
34 */
35static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
36						unsigned char val)
37{
38	snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val);
39}
40
41static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
42{
43	return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg);
44}
45
46/*
47 *	2*ADC 2*DAC no2 ringbuffer r/w on i2c bus
48 */
49static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg,
50						unsigned char val)
51{
52	snd_vt1724_write_i2c(ice, STAC9460_2_I2C_ADDR, reg, val);
53}
54
55static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
56{
57	return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg);
58}
59
60
61/*
62 *	DAC mute control
63 */
64static void stac9460_dac_mute_all(struct snd_ice1712 *ice, unsigned char mute,
65				unsigned short int *change_mask)
66{
67	unsigned char new, old;
68	int id, idx, change;
69
70	/*stac9460 1*/
71	for (id = 0; id < 7; id++) {
72		if (*change_mask & (0x01 << id)) {
73			if (id == 0)
74				idx = STAC946X_MASTER_VOLUME;
75			else
76				idx = STAC946X_LF_VOLUME - 1 + id;
77			old = stac9460_get(ice, idx);
78			new = (~mute << 7 & 0x80) | (old & ~0x80);
79			change = (new != old);
80			if (change) {
81				stac9460_put(ice, idx, new);
82				*change_mask = *change_mask | (0x01 << id);
83			} else {
84				*change_mask = *change_mask & ~(0x01 << id);
85			}
86		}
87	}
88
89	/*stac9460 2*/
90	for (id = 0; id < 3; id++) {
91		if (*change_mask & (0x01 << (id + 7))) {
92			if (id == 0)
93				idx = STAC946X_MASTER_VOLUME;
94			else
95				idx = STAC946X_LF_VOLUME - 1 + id;
96			old = stac9460_2_get(ice, idx);
97			new = (~mute << 7 & 0x80) | (old & ~0x80);
98			change = (new != old);
99			if (change) {
100				stac9460_2_put(ice, idx, new);
101				*change_mask = *change_mask | (0x01 << id);
102			} else {
103				*change_mask = *change_mask & ~(0x01 << id);
104			}
105		}
106	}
107}
108
109
110
111#define stac9460_dac_mute_info		snd_ctl_boolean_mono_info
112
113static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
114				struct snd_ctl_elem_value *ucontrol)
115{
116	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
117	struct wtm_spec *spec = ice->spec;
118	unsigned char val;
119	int idx, id;
120
121	mutex_lock(&spec->mute_mutex);
122
123	if (kcontrol->private_value) {
124		idx = STAC946X_MASTER_VOLUME;
125		id = 0;
126	} else {
127		id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
128		idx = id + STAC946X_LF_VOLUME;
129	}
130	if (id < 6)
131		val = stac9460_get(ice, idx);
132	else
133		val = stac9460_2_get(ice, idx - 6);
134	ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
135
136	mutex_unlock(&spec->mute_mutex);
137	return 0;
138}
139
140static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
141				struct snd_ctl_elem_value *ucontrol)
142{
143	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
144	unsigned char new, old;
145	int id, idx;
146	int change;
147
148	if (kcontrol->private_value) {
149		idx = STAC946X_MASTER_VOLUME;
150		old = stac9460_get(ice, idx);
151		new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
152							(old & ~0x80);
153		change = (new != old);
154		if (change) {
155			stac9460_put(ice, idx, new);
156			stac9460_2_put(ice, idx, new);
157		}
158	} else {
159		id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
160		idx = id + STAC946X_LF_VOLUME;
161		if (id < 6)
162			old = stac9460_get(ice, idx);
163		else
164			old = stac9460_2_get(ice, idx - 6);
165		new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
166							(old & ~0x80);
167		change = (new != old);
168		if (change) {
169			if (id < 6)
170				stac9460_put(ice, idx, new);
171			else
172				stac9460_2_put(ice, idx - 6, new);
173		}
174	}
175	return change;
176}
177
178/*
179 * 	DAC volume attenuation mixer control
180 */
181static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
182				struct snd_ctl_elem_info *uinfo)
183{
184	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
185	uinfo->count = 1;
186	uinfo->value.integer.min = 0;			/* mute */
187	uinfo->value.integer.max = 0x7f;		/* 0dB */
188	return 0;
189}
190
191static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
192				struct snd_ctl_elem_value *ucontrol)
193{
194	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
195	int idx, id;
196	unsigned char vol;
197
198	if (kcontrol->private_value) {
199		idx = STAC946X_MASTER_VOLUME;
200		id = 0;
201	} else {
202		id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
203		idx = id + STAC946X_LF_VOLUME;
204	}
205	if (id < 6)
206		vol = stac9460_get(ice, idx) & 0x7f;
207	else
208		vol = stac9460_2_get(ice, idx - 6) & 0x7f;
209	ucontrol->value.integer.value[0] = 0x7f - vol;
210	return 0;
211}
212
213static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
214				struct snd_ctl_elem_value *ucontrol)
215{
216	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
217	int idx, id;
218	unsigned char tmp, ovol, nvol;
219	int change;
220
221	if (kcontrol->private_value) {
222		idx = STAC946X_MASTER_VOLUME;
223		nvol = ucontrol->value.integer.value[0] & 0x7f;
224		tmp = stac9460_get(ice, idx);
225		ovol = 0x7f - (tmp & 0x7f);
226		change = (ovol != nvol);
227		if (change) {
228			stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
229			stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
230		}
231	} else {
232		id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
233		idx = id + STAC946X_LF_VOLUME;
234		nvol = ucontrol->value.integer.value[0] & 0x7f;
235		if (id < 6)
236			tmp = stac9460_get(ice, idx);
237		else
238			tmp = stac9460_2_get(ice, idx - 6);
239		ovol = 0x7f - (tmp & 0x7f);
240		change = (ovol != nvol);
241		if (change) {
242			if (id < 6)
243				stac9460_put(ice, idx, (0x7f - nvol) |
244							(tmp & 0x80));
245			else
246				stac9460_2_put(ice, idx-6, (0x7f - nvol) |
247							(tmp & 0x80));
248		}
249	}
250	return change;
251}
252
253/*
254 * ADC mute control
255 */
256#define stac9460_adc_mute_info		snd_ctl_boolean_stereo_info
257
258static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
259				struct snd_ctl_elem_value *ucontrol)
260{
261	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
262	unsigned char val;
263	int i, id;
264
265	id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
266	if (id == 0) {
267		for (i = 0; i < 2; ++i) {
268			val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
269			ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
270		}
271	} else {
272		for (i = 0; i < 2; ++i) {
273			val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i);
274			ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
275		}
276	}
277	return 0;
278}
279
280static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
281				struct snd_ctl_elem_value *ucontrol)
282{
283	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
284	unsigned char new, old;
285	int i, reg, id;
286	int change;
287
288	id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
289	if (id == 0) {
290		for (i = 0; i < 2; ++i) {
291			reg = STAC946X_MIC_L_VOLUME + i;
292			old = stac9460_get(ice, reg);
293			new = (~ucontrol->value.integer.value[i]<<7&0x80) |
294								(old&~0x80);
295			change = (new != old);
296			if (change)
297				stac9460_put(ice, reg, new);
298		}
299	} else {
300		for (i = 0; i < 2; ++i) {
301			reg = STAC946X_MIC_L_VOLUME + i;
302			old = stac9460_2_get(ice, reg);
303			new = (~ucontrol->value.integer.value[i]<<7&0x80) |
304								(old&~0x80);
305			change = (new != old);
306			if (change)
307				stac9460_2_put(ice, reg, new);
308		}
309	}
310	return change;
311}
312
313/*
314 *ADC gain mixer control
315 */
316static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
317				struct snd_ctl_elem_info *uinfo)
318{
319	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
320	uinfo->count = 2;
321	uinfo->value.integer.min = 0;		/* 0dB */
322	uinfo->value.integer.max = 0x0f;	/* 22.5dB */
323	return 0;
324}
325
326static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
327				struct snd_ctl_elem_value *ucontrol)
328{
329	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
330	int i, reg, id;
331	unsigned char vol;
332
333	id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
334	if (id == 0) {
335		for (i = 0; i < 2; ++i) {
336			reg = STAC946X_MIC_L_VOLUME + i;
337			vol = stac9460_get(ice, reg) & 0x0f;
338			ucontrol->value.integer.value[i] = 0x0f - vol;
339		}
340	} else {
341		for (i = 0; i < 2; ++i) {
342			reg = STAC946X_MIC_L_VOLUME + i;
343			vol = stac9460_2_get(ice, reg) & 0x0f;
344			ucontrol->value.integer.value[i] = 0x0f - vol;
345		}
346	}
347	return 0;
348}
349
350static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
351				struct snd_ctl_elem_value *ucontrol)
352{
353	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
354	int i, reg, id;
355	unsigned char ovol, nvol;
356	int change;
357
358	id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
359	if (id == 0) {
360		for (i = 0; i < 2; ++i) {
361			reg = STAC946X_MIC_L_VOLUME + i;
362			nvol = ucontrol->value.integer.value[i] & 0x0f;
363			ovol = 0x0f - stac9460_get(ice, reg);
364			change = ((ovol & 0x0f) != nvol);
365			if (change)
366				stac9460_put(ice, reg, (0x0f - nvol) |
367							(ovol & ~0x0f));
368		}
369	} else {
370		for (i = 0; i < 2; ++i) {
371			reg = STAC946X_MIC_L_VOLUME + i;
372			nvol = ucontrol->value.integer.value[i] & 0x0f;
373			ovol = 0x0f - stac9460_2_get(ice, reg);
374			change = ((ovol & 0x0f) != nvol);
375			if (change)
376				stac9460_2_put(ice, reg, (0x0f - nvol) |
377							(ovol & ~0x0f));
378		}
379	}
380	return change;
381}
382
383/*
384 * MIC / LINE switch fonction
385 */
386static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
387				struct snd_ctl_elem_info *uinfo)
388{
389	static const char * const texts[2] = { "Line In", "Mic" };
390
391	return snd_ctl_enum_info(uinfo, 1, 2, texts);
392}
393
394
395static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
396				struct snd_ctl_elem_value *ucontrol)
397{
398	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
399	unsigned char val;
400	int id;
401
402	id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
403	if (id == 0)
404		val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
405	else
406		val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
407	ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1;
408	return 0;
409}
410
411static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
412				struct snd_ctl_elem_value *ucontrol)
413{
414	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
415	unsigned char new, old;
416	int change, id;
417
418	id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
419	if (id == 0)
420		old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
421	else
422		old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
423	new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
424	change = (new != old);
425	if (change) {
426		if (id == 0)
427			stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
428		else
429			stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
430	}
431	return change;
432}
433
434
435/*
436 * Handler for setting correct codec rate - called when rate change is detected
437 */
438static void stac9460_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
439{
440	unsigned char old, new;
441	unsigned short int changed;
442	struct wtm_spec *spec = ice->spec;
443
444	if (rate == 0)  /* no hint - S/PDIF input is master, simply return */
445		return;
446	else if (rate <= 48000)
447		new = 0x08;     /* 256x, base rate mode */
448	else if (rate <= 96000)
449		new = 0x11;     /* 256x, mid rate mode */
450	else
451		new = 0x12;     /* 128x, high rate mode */
452
453	old = stac9460_get(ice, STAC946X_MASTER_CLOCKING);
454	if (old == new)
455		return;
456	/* change detected, setting master clock, muting first */
457	/* due to possible conflicts with mute controls - mutexing */
458	mutex_lock(&spec->mute_mutex);
459	/* we have to remember current mute status for each DAC */
460	changed = 0xFFFF;
461	stac9460_dac_mute_all(ice, 0, &changed);
462	/*printk(KERN_DEBUG "Rate change: %d, new MC: 0x%02x\n", rate, new);*/
463	stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);
464	stac9460_2_put(ice, STAC946X_MASTER_CLOCKING, new);
465	udelay(10);
466	/* unmuting - only originally unmuted dacs -
467	* i.e. those changed when muting */
468	stac9460_dac_mute_all(ice, 1, &changed);
469	mutex_unlock(&spec->mute_mutex);
470}
471
472
473/*Limits value in dB for fader*/
474static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
475static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
476
477/*
478 * Control tabs
479 */
480static const struct snd_kcontrol_new stac9640_controls[] = {
481	{
482		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
483		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
484			    SNDRV_CTL_ELEM_ACCESS_TLV_READ),
485		.name = "Master Playback Switch",
486		.info = stac9460_dac_mute_info,
487		.get = stac9460_dac_mute_get,
488		.put = stac9460_dac_mute_put,
489		.private_value = 1,
490		.tlv = { .p = db_scale_dac }
491	},
492	{
493		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
494		.name = "Master Playback Volume",
495		.info = stac9460_dac_vol_info,
496		.get = stac9460_dac_vol_get,
497		.put = stac9460_dac_vol_put,
498		.private_value = 1,
499	},
500	{
501		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
502		.name = "MIC/Line Input Enum",
503		.count = 2,
504		.info = stac9460_mic_sw_info,
505		.get = stac9460_mic_sw_get,
506		.put = stac9460_mic_sw_put,
507
508	},
509	{
510		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
511		.name = "DAC Switch",
512		.count = 8,
513		.info = stac9460_dac_mute_info,
514		.get = stac9460_dac_mute_get,
515		.put = stac9460_dac_mute_put,
516	},
517	{
518		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
519		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
520			    SNDRV_CTL_ELEM_ACCESS_TLV_READ),
521
522		.name = "DAC Volume",
523		.count = 8,
524		.info = stac9460_dac_vol_info,
525		.get = stac9460_dac_vol_get,
526		.put = stac9460_dac_vol_put,
527		.tlv = { .p = db_scale_dac }
528	},
529	{
530		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
531		.name = "ADC Switch",
532		.count = 2,
533		.info = stac9460_adc_mute_info,
534		.get = stac9460_adc_mute_get,
535		.put = stac9460_adc_mute_put,
536	},
537	{
538		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
539		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
540			    SNDRV_CTL_ELEM_ACCESS_TLV_READ),
541
542		.name = "ADC Volume",
543		.count = 2,
544		.info = stac9460_adc_vol_info,
545		.get = stac9460_adc_vol_get,
546		.put = stac9460_adc_vol_put,
547		.tlv = { .p = db_scale_adc }
548	}
549};
550
551
552
553/*INIT*/
554static int wtm_add_controls(struct snd_ice1712 *ice)
555{
556	unsigned int i;
557	int err;
558
559	for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) {
560		err = snd_ctl_add(ice->card,
561				snd_ctl_new1(&stac9640_controls[i], ice));
562		if (err < 0)
563			return err;
564	}
565	return 0;
566}
567
568static int wtm_init(struct snd_ice1712 *ice)
569{
570	static const unsigned short stac_inits_wtm[] = {
571		STAC946X_RESET, 0,
572		STAC946X_MASTER_CLOCKING, 0x11,
573		(unsigned short)-1
574	};
575	const unsigned short *p;
576	struct wtm_spec *spec;
577
578	/*WTM 192M*/
579	ice->num_total_dacs = 8;
580	ice->num_total_adcs = 4;
581	ice->force_rdma1 = 1;
582
583	/*init mutex for dac mute conflict*/
584	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
585	if (!spec)
586		return -ENOMEM;
587	ice->spec = spec;
588	mutex_init(&spec->mute_mutex);
589
590
591	/*initialize codec*/
592	p = stac_inits_wtm;
593	for (; *p != (unsigned short)-1; p += 2) {
594		stac9460_put(ice, p[0], p[1]);
595		stac9460_2_put(ice, p[0], p[1]);
596	}
597	ice->gpio.set_pro_rate = stac9460_set_rate_val;
598	return 0;
599}
600
601
602static const unsigned char wtm_eeprom[] = {
603	[ICE_EEP2_SYSCONF]      = 0x67, /*SYSCONF: clock 192KHz, mpu401,
604							4ADC, 8DAC */
605	[ICE_EEP2_ACLINK]       = 0x80, /* ACLINK : I2S */
606	[ICE_EEP2_I2S]          = 0xf8, /* I2S: vol; 96k, 24bit, 192k */
607	[ICE_EEP2_SPDIF]        = 0xc1, /*SPDIF: out-en, spidf ext out*/
608	[ICE_EEP2_GPIO_DIR]     = 0x9f,
609	[ICE_EEP2_GPIO_DIR1]    = 0xff,
610	[ICE_EEP2_GPIO_DIR2]    = 0x7f,
611	[ICE_EEP2_GPIO_MASK]    = 0x9f,
612	[ICE_EEP2_GPIO_MASK1]   = 0xff,
613	[ICE_EEP2_GPIO_MASK2]   = 0x7f,
614	[ICE_EEP2_GPIO_STATE]   = 0x16,
615	[ICE_EEP2_GPIO_STATE1]  = 0x80,
616	[ICE_EEP2_GPIO_STATE2]  = 0x00,
617};
618
619
620/*entry point*/
621struct snd_ice1712_card_info snd_vt1724_wtm_cards[] = {
622	{
623		.subvendor = VT1724_SUBDEVICE_WTM,
624		.name = "ESI Waveterminal 192M",
625		.model = "WT192M",
626		.chip_init = wtm_init,
627		.build_controls = wtm_add_controls,
628		.eeprom_size = sizeof(wtm_eeprom),
629		.eeprom_data = wtm_eeprom,
630	},
631	{} /*terminator*/
632};
633