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
)
60 printk(KERN_DEBUG
"set - 0x%x/0x%x\n", addr
, value
);
62 snd_i2c_write(tea
->bus
, TEA6330T_ADDR
, addr
, value
, 1);
66 #define TEA6330T_MASTER_VOLUME(xname, xindex) \
67 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
68 .info = snd_tea6330t_info_master_volume, \
69 .get = snd_tea6330t_get_master_volume, .put = snd_tea6330t_put_master_volume }
71 static int snd_tea6330t_info_master_volume(struct snd_kcontrol
*kcontrol
,
72 struct snd_ctl_elem_info
*uinfo
)
74 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
76 uinfo
->value
.integer
.min
= 0;
77 uinfo
->value
.integer
.max
= 43;
81 static int snd_tea6330t_get_master_volume(struct snd_kcontrol
*kcontrol
,
82 struct snd_ctl_elem_value
*ucontrol
)
84 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
86 snd_i2c_lock(tea
->bus
);
87 ucontrol
->value
.integer
.value
[0] = tea
->mleft
- 0x14;
88 ucontrol
->value
.integer
.value
[1] = tea
->mright
- 0x14;
89 snd_i2c_unlock(tea
->bus
);
93 static int snd_tea6330t_put_master_volume(struct snd_kcontrol
*kcontrol
,
94 struct snd_ctl_elem_value
*ucontrol
)
96 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
97 int change
, count
, err
;
98 unsigned char bytes
[3];
99 unsigned char val1
, val2
;
101 val1
= (ucontrol
->value
.integer
.value
[0] % 44) + 0x14;
102 val2
= (ucontrol
->value
.integer
.value
[1] % 44) + 0x14;
103 snd_i2c_lock(tea
->bus
);
104 change
= val1
!= tea
->mleft
|| val2
!= tea
->mright
;
108 if (tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] != 0) {
109 bytes
[count
++] = TEA6330T_SADDR_VOLUME_LEFT
;
110 bytes
[count
++] = tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] = tea
->mleft
;
112 if (tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] != 0) {
114 bytes
[count
++] = TEA6330T_SADDR_VOLUME_RIGHT
;
115 bytes
[count
++] = tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] = tea
->mright
;
118 err
= snd_i2c_sendbytes(tea
->device
, bytes
, count
);
122 snd_i2c_unlock(tea
->bus
);
126 #define TEA6330T_MASTER_SWITCH(xname, xindex) \
127 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
128 .info = snd_tea6330t_info_master_switch, \
129 .get = snd_tea6330t_get_master_switch, .put = snd_tea6330t_put_master_switch }
131 #define snd_tea6330t_info_master_switch snd_ctl_boolean_stereo_info
133 static int snd_tea6330t_get_master_switch(struct snd_kcontrol
*kcontrol
,
134 struct snd_ctl_elem_value
*ucontrol
)
136 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
138 snd_i2c_lock(tea
->bus
);
139 ucontrol
->value
.integer
.value
[0] = tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] == 0 ? 0 : 1;
140 ucontrol
->value
.integer
.value
[1] = tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] == 0 ? 0 : 1;
141 snd_i2c_unlock(tea
->bus
);
145 static int snd_tea6330t_put_master_switch(struct snd_kcontrol
*kcontrol
,
146 struct snd_ctl_elem_value
*ucontrol
)
148 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
150 unsigned char bytes
[3];
151 unsigned char oval1
, oval2
, val1
, val2
;
153 val1
= ucontrol
->value
.integer
.value
[0] & 1;
154 val2
= ucontrol
->value
.integer
.value
[1] & 1;
155 snd_i2c_lock(tea
->bus
);
156 oval1
= tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] == 0 ? 0 : 1;
157 oval2
= tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] == 0 ? 0 : 1;
158 change
= val1
!= oval1
|| val2
!= oval2
;
159 tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] = val1
? tea
->mleft
: 0;
160 tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] = val2
? tea
->mright
: 0;
161 bytes
[0] = TEA6330T_SADDR_VOLUME_LEFT
;
162 bytes
[1] = tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
];
163 bytes
[2] = tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
];
164 err
= snd_i2c_sendbytes(tea
->device
, bytes
, 3);
167 snd_i2c_unlock(tea
->bus
);
171 #define TEA6330T_BASS(xname, xindex) \
172 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
173 .info = snd_tea6330t_info_bass, \
174 .get = snd_tea6330t_get_bass, .put = snd_tea6330t_put_bass }
176 static int snd_tea6330t_info_bass(struct snd_kcontrol
*kcontrol
,
177 struct snd_ctl_elem_info
*uinfo
)
179 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
181 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
183 uinfo
->value
.integer
.min
= 0;
184 uinfo
->value
.integer
.max
= tea
->max_bass
;
188 static int snd_tea6330t_get_bass(struct snd_kcontrol
*kcontrol
,
189 struct snd_ctl_elem_value
*ucontrol
)
191 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
193 ucontrol
->value
.integer
.value
[0] = tea
->bass
;
197 static int snd_tea6330t_put_bass(struct snd_kcontrol
*kcontrol
,
198 struct snd_ctl_elem_value
*ucontrol
)
200 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
202 unsigned char bytes
[2];
205 val1
= ucontrol
->value
.integer
.value
[0] % (tea
->max_bass
+ 1);
206 snd_i2c_lock(tea
->bus
);
208 val1
+= tea
->equalizer
? 7 : 3;
209 change
= tea
->regs
[TEA6330T_SADDR_BASS
] != val1
;
210 bytes
[0] = TEA6330T_SADDR_BASS
;
211 bytes
[1] = tea
->regs
[TEA6330T_SADDR_BASS
] = val1
;
212 err
= snd_i2c_sendbytes(tea
->device
, bytes
, 2);
215 snd_i2c_unlock(tea
->bus
);
219 #define TEA6330T_TREBLE(xname, xindex) \
220 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
221 .info = snd_tea6330t_info_treble, \
222 .get = snd_tea6330t_get_treble, .put = snd_tea6330t_put_treble }
224 static int snd_tea6330t_info_treble(struct snd_kcontrol
*kcontrol
,
225 struct snd_ctl_elem_info
*uinfo
)
227 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
229 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
231 uinfo
->value
.integer
.min
= 0;
232 uinfo
->value
.integer
.max
= tea
->max_treble
;
236 static int snd_tea6330t_get_treble(struct snd_kcontrol
*kcontrol
,
237 struct snd_ctl_elem_value
*ucontrol
)
239 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
241 ucontrol
->value
.integer
.value
[0] = tea
->treble
;
245 static int snd_tea6330t_put_treble(struct snd_kcontrol
*kcontrol
,
246 struct snd_ctl_elem_value
*ucontrol
)
248 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
250 unsigned char bytes
[2];
253 val1
= ucontrol
->value
.integer
.value
[0] % (tea
->max_treble
+ 1);
254 snd_i2c_lock(tea
->bus
);
257 change
= tea
->regs
[TEA6330T_SADDR_TREBLE
] != val1
;
258 bytes
[0] = TEA6330T_SADDR_TREBLE
;
259 bytes
[1] = tea
->regs
[TEA6330T_SADDR_TREBLE
] = val1
;
260 err
= snd_i2c_sendbytes(tea
->device
, bytes
, 2);
263 snd_i2c_unlock(tea
->bus
);
267 static const struct snd_kcontrol_new snd_tea6330t_controls
[] = {
268 TEA6330T_MASTER_SWITCH("Master Playback Switch", 0),
269 TEA6330T_MASTER_VOLUME("Master Playback Volume", 0),
270 TEA6330T_BASS("Tone Control - Bass", 0),
271 TEA6330T_TREBLE("Tone Control - Treble", 0)
274 static void snd_tea6330_free(struct snd_i2c_device
*device
)
276 kfree(device
->private_data
);
279 int snd_tea6330t_update_mixer(struct snd_card
*card
,
280 struct snd_i2c_bus
*bus
,
281 int equalizer
, int fader
)
283 struct snd_i2c_device
*device
;
284 struct tea6330t
*tea
;
285 const struct snd_kcontrol_new
*knew
;
288 u8 default_treble
, default_bass
;
289 unsigned char bytes
[7];
291 tea
= kzalloc(sizeof(*tea
), GFP_KERNEL
);
294 err
= snd_i2c_device_create(bus
, "TEA6330T", TEA6330T_ADDR
, &device
);
299 tea
->device
= device
;
301 tea
->equalizer
= equalizer
;
303 device
->private_data
= tea
;
304 device
->private_free
= snd_tea6330_free
;
308 /* turn fader off and handle equalizer */
309 tea
->regs
[TEA6330T_SADDR_FADER
] = 0x3f;
310 tea
->regs
[TEA6330T_SADDR_AUDIO_SWITCH
] = equalizer
? 0 : TEA6330T_EQN
;
311 /* initialize mixer */
312 if (!tea
->equalizer
) {
315 default_bass
= 3 + 4;
317 default_treble
= 3 + 4;
322 default_bass
= 7 + 4;
327 tea
->mleft
= tea
->mright
= 0x14;
328 tea
->regs
[TEA6330T_SADDR_BASS
] = default_bass
;
329 tea
->regs
[TEA6330T_SADDR_TREBLE
] = default_treble
;
331 /* compose I2C message and put the hardware to initial state */
332 bytes
[0] = TEA6330T_SADDR_VOLUME_LEFT
;
333 for (idx
= 0; idx
< 6; idx
++)
334 bytes
[idx
+1] = tea
->regs
[idx
];
335 err
= snd_i2c_sendbytes(device
, bytes
, 7);
339 strcat(card
->mixername
, ",TEA6330T");
340 err
= snd_component_add(card
, "TEA6330T");
344 for (idx
= 0; idx
< ARRAY_SIZE(snd_tea6330t_controls
); idx
++) {
345 knew
= &snd_tea6330t_controls
[idx
];
346 if (tea
->treble
== 0 && !strcmp(knew
->name
, "Tone Control - Treble"))
348 err
= snd_ctl_add(card
, snd_ctl_new1(knew
, tea
));
358 snd_i2c_device_free(device
);
362 EXPORT_SYMBOL(snd_tea6330t_detect
);
363 EXPORT_SYMBOL(snd_tea6330t_update_mixer
);