1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Routines for control of the TEA6330T circuit via i2c bus
4 * Sound fader control circuit for car radios by Philips Semiconductors
5 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
8 #include <linux/init.h>
9 #include <linux/slab.h>
10 #include <linux/module.h>
11 #include <sound/core.h>
12 #include <sound/control.h>
13 #include <sound/tea6330t.h>
15 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
16 MODULE_DESCRIPTION("Routines for control of the TEA6330T circuit via i2c bus");
17 MODULE_LICENSE("GPL");
19 #define TEA6330T_ADDR (0x80>>1) /* fixed address */
21 #define TEA6330T_SADDR_VOLUME_LEFT 0x00 /* volume left */
22 #define TEA6330T_SADDR_VOLUME_RIGHT 0x01 /* volume right */
23 #define TEA6330T_SADDR_BASS 0x02 /* bass control */
24 #define TEA6330T_SADDR_TREBLE 0x03 /* treble control */
25 #define TEA6330T_SADDR_FADER 0x04 /* fader control */
26 #define TEA6330T_MFN 0x20 /* mute control for selected channels */
27 #define TEA6330T_FCH 0x10 /* select fader channels - front or rear */
28 #define TEA6330T_SADDR_AUDIO_SWITCH 0x05 /* audio switch */
29 #define TEA6330T_GMU 0x80 /* mute control, general mute */
30 #define TEA6330T_EQN 0x40 /* equalizer switchover (0=equalizer-on) */
34 struct snd_i2c_device
*device
;
35 struct snd_i2c_bus
*bus
;
38 unsigned char regs
[8];
39 unsigned char mleft
, mright
;
40 unsigned char bass
, treble
;
41 unsigned char max_bass
, max_treble
;
45 int snd_tea6330t_detect(struct snd_i2c_bus
*bus
, int equalizer
)
50 res
= snd_i2c_probeaddr(bus
, TEA6330T_ADDR
);
56 static void snd_tea6330t_set(struct tea6330t
*tea
,
57 unsigned char addr
, unsigned char value
)
59 snd_i2c_write(tea
->bus
, TEA6330T_ADDR
, addr
, value
, 1);
63 #define TEA6330T_MASTER_VOLUME(xname, xindex) \
64 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
65 .info = snd_tea6330t_info_master_volume, \
66 .get = snd_tea6330t_get_master_volume, .put = snd_tea6330t_put_master_volume }
68 static int snd_tea6330t_info_master_volume(struct snd_kcontrol
*kcontrol
,
69 struct snd_ctl_elem_info
*uinfo
)
71 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
73 uinfo
->value
.integer
.min
= 0;
74 uinfo
->value
.integer
.max
= 43;
78 static int snd_tea6330t_get_master_volume(struct snd_kcontrol
*kcontrol
,
79 struct snd_ctl_elem_value
*ucontrol
)
81 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
83 snd_i2c_lock(tea
->bus
);
84 ucontrol
->value
.integer
.value
[0] = tea
->mleft
- 0x14;
85 ucontrol
->value
.integer
.value
[1] = tea
->mright
- 0x14;
86 snd_i2c_unlock(tea
->bus
);
90 static int snd_tea6330t_put_master_volume(struct snd_kcontrol
*kcontrol
,
91 struct snd_ctl_elem_value
*ucontrol
)
93 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
94 int change
, count
, err
;
95 unsigned char bytes
[3];
96 unsigned char val1
, val2
;
98 val1
= (ucontrol
->value
.integer
.value
[0] % 44) + 0x14;
99 val2
= (ucontrol
->value
.integer
.value
[1] % 44) + 0x14;
100 snd_i2c_lock(tea
->bus
);
101 change
= val1
!= tea
->mleft
|| val2
!= tea
->mright
;
105 if (tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] != 0) {
106 bytes
[count
++] = TEA6330T_SADDR_VOLUME_LEFT
;
107 bytes
[count
++] = tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] = tea
->mleft
;
109 if (tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] != 0) {
111 bytes
[count
++] = TEA6330T_SADDR_VOLUME_RIGHT
;
112 bytes
[count
++] = tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] = tea
->mright
;
115 err
= snd_i2c_sendbytes(tea
->device
, bytes
, count
);
119 snd_i2c_unlock(tea
->bus
);
123 #define TEA6330T_MASTER_SWITCH(xname, xindex) \
124 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
125 .info = snd_tea6330t_info_master_switch, \
126 .get = snd_tea6330t_get_master_switch, .put = snd_tea6330t_put_master_switch }
128 #define snd_tea6330t_info_master_switch snd_ctl_boolean_stereo_info
130 static int snd_tea6330t_get_master_switch(struct snd_kcontrol
*kcontrol
,
131 struct snd_ctl_elem_value
*ucontrol
)
133 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
135 snd_i2c_lock(tea
->bus
);
136 ucontrol
->value
.integer
.value
[0] = tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] == 0 ? 0 : 1;
137 ucontrol
->value
.integer
.value
[1] = tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] == 0 ? 0 : 1;
138 snd_i2c_unlock(tea
->bus
);
142 static int snd_tea6330t_put_master_switch(struct snd_kcontrol
*kcontrol
,
143 struct snd_ctl_elem_value
*ucontrol
)
145 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
147 unsigned char bytes
[3];
148 unsigned char oval1
, oval2
, val1
, val2
;
150 val1
= ucontrol
->value
.integer
.value
[0] & 1;
151 val2
= ucontrol
->value
.integer
.value
[1] & 1;
152 snd_i2c_lock(tea
->bus
);
153 oval1
= tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] == 0 ? 0 : 1;
154 oval2
= tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] == 0 ? 0 : 1;
155 change
= val1
!= oval1
|| val2
!= oval2
;
156 tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] = val1
? tea
->mleft
: 0;
157 tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] = val2
? tea
->mright
: 0;
158 bytes
[0] = TEA6330T_SADDR_VOLUME_LEFT
;
159 bytes
[1] = tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
];
160 bytes
[2] = tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
];
161 err
= snd_i2c_sendbytes(tea
->device
, bytes
, 3);
164 snd_i2c_unlock(tea
->bus
);
168 #define TEA6330T_BASS(xname, xindex) \
169 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
170 .info = snd_tea6330t_info_bass, \
171 .get = snd_tea6330t_get_bass, .put = snd_tea6330t_put_bass }
173 static int snd_tea6330t_info_bass(struct snd_kcontrol
*kcontrol
,
174 struct snd_ctl_elem_info
*uinfo
)
176 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
178 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
180 uinfo
->value
.integer
.min
= 0;
181 uinfo
->value
.integer
.max
= tea
->max_bass
;
185 static int snd_tea6330t_get_bass(struct snd_kcontrol
*kcontrol
,
186 struct snd_ctl_elem_value
*ucontrol
)
188 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
190 ucontrol
->value
.integer
.value
[0] = tea
->bass
;
194 static int snd_tea6330t_put_bass(struct snd_kcontrol
*kcontrol
,
195 struct snd_ctl_elem_value
*ucontrol
)
197 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
199 unsigned char bytes
[2];
202 val1
= ucontrol
->value
.integer
.value
[0] % (tea
->max_bass
+ 1);
203 snd_i2c_lock(tea
->bus
);
205 val1
+= tea
->equalizer
? 7 : 3;
206 change
= tea
->regs
[TEA6330T_SADDR_BASS
] != val1
;
207 bytes
[0] = TEA6330T_SADDR_BASS
;
208 bytes
[1] = tea
->regs
[TEA6330T_SADDR_BASS
] = val1
;
209 err
= snd_i2c_sendbytes(tea
->device
, bytes
, 2);
212 snd_i2c_unlock(tea
->bus
);
216 #define TEA6330T_TREBLE(xname, xindex) \
217 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
218 .info = snd_tea6330t_info_treble, \
219 .get = snd_tea6330t_get_treble, .put = snd_tea6330t_put_treble }
221 static int snd_tea6330t_info_treble(struct snd_kcontrol
*kcontrol
,
222 struct snd_ctl_elem_info
*uinfo
)
224 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
226 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
228 uinfo
->value
.integer
.min
= 0;
229 uinfo
->value
.integer
.max
= tea
->max_treble
;
233 static int snd_tea6330t_get_treble(struct snd_kcontrol
*kcontrol
,
234 struct snd_ctl_elem_value
*ucontrol
)
236 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
238 ucontrol
->value
.integer
.value
[0] = tea
->treble
;
242 static int snd_tea6330t_put_treble(struct snd_kcontrol
*kcontrol
,
243 struct snd_ctl_elem_value
*ucontrol
)
245 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
247 unsigned char bytes
[2];
250 val1
= ucontrol
->value
.integer
.value
[0] % (tea
->max_treble
+ 1);
251 snd_i2c_lock(tea
->bus
);
254 change
= tea
->regs
[TEA6330T_SADDR_TREBLE
] != val1
;
255 bytes
[0] = TEA6330T_SADDR_TREBLE
;
256 bytes
[1] = tea
->regs
[TEA6330T_SADDR_TREBLE
] = val1
;
257 err
= snd_i2c_sendbytes(tea
->device
, bytes
, 2);
260 snd_i2c_unlock(tea
->bus
);
264 static const struct snd_kcontrol_new snd_tea6330t_controls
[] = {
265 TEA6330T_MASTER_SWITCH("Master Playback Switch", 0),
266 TEA6330T_MASTER_VOLUME("Master Playback Volume", 0),
267 TEA6330T_BASS("Tone Control - Bass", 0),
268 TEA6330T_TREBLE("Tone Control - Treble", 0)
271 static void snd_tea6330_free(struct snd_i2c_device
*device
)
273 kfree(device
->private_data
);
276 int snd_tea6330t_update_mixer(struct snd_card
*card
,
277 struct snd_i2c_bus
*bus
,
278 int equalizer
, int fader
)
280 struct snd_i2c_device
*device
;
281 struct tea6330t
*tea
;
282 const struct snd_kcontrol_new
*knew
;
285 u8 default_treble
, default_bass
;
286 unsigned char bytes
[7];
288 tea
= kzalloc(sizeof(*tea
), GFP_KERNEL
);
291 err
= snd_i2c_device_create(bus
, "TEA6330T", TEA6330T_ADDR
, &device
);
296 tea
->device
= device
;
298 tea
->equalizer
= equalizer
;
300 device
->private_data
= tea
;
301 device
->private_free
= snd_tea6330_free
;
305 /* turn fader off and handle equalizer */
306 tea
->regs
[TEA6330T_SADDR_FADER
] = 0x3f;
307 tea
->regs
[TEA6330T_SADDR_AUDIO_SWITCH
] = equalizer
? 0 : TEA6330T_EQN
;
308 /* initialize mixer */
309 if (!tea
->equalizer
) {
312 default_bass
= 3 + 4;
314 default_treble
= 3 + 4;
319 default_bass
= 7 + 4;
324 tea
->mleft
= tea
->mright
= 0x14;
325 tea
->regs
[TEA6330T_SADDR_BASS
] = default_bass
;
326 tea
->regs
[TEA6330T_SADDR_TREBLE
] = default_treble
;
328 /* compose I2C message and put the hardware to initial state */
329 bytes
[0] = TEA6330T_SADDR_VOLUME_LEFT
;
330 for (idx
= 0; idx
< 6; idx
++)
331 bytes
[idx
+1] = tea
->regs
[idx
];
332 err
= snd_i2c_sendbytes(device
, bytes
, 7);
336 strcat(card
->mixername
, ",TEA6330T");
337 err
= snd_component_add(card
, "TEA6330T");
341 for (idx
= 0; idx
< ARRAY_SIZE(snd_tea6330t_controls
); idx
++) {
342 knew
= &snd_tea6330t_controls
[idx
];
343 if (tea
->treble
== 0 && !strcmp(knew
->name
, "Tone Control - Treble"))
345 err
= snd_ctl_add(card
, snd_ctl_new1(knew
, tea
));
355 snd_i2c_device_free(device
);
359 EXPORT_SYMBOL(snd_tea6330t_detect
);
360 EXPORT_SYMBOL(snd_tea6330t_update_mixer
);