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 if ((err
= snd_i2c_sendbytes(tea
->device
, bytes
, count
)) < 0)
121 snd_i2c_unlock(tea
->bus
);
125 #define TEA6330T_MASTER_SWITCH(xname, xindex) \
126 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
127 .info = snd_tea6330t_info_master_switch, \
128 .get = snd_tea6330t_get_master_switch, .put = snd_tea6330t_put_master_switch }
130 #define snd_tea6330t_info_master_switch snd_ctl_boolean_stereo_info
132 static int snd_tea6330t_get_master_switch(struct snd_kcontrol
*kcontrol
,
133 struct snd_ctl_elem_value
*ucontrol
)
135 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
137 snd_i2c_lock(tea
->bus
);
138 ucontrol
->value
.integer
.value
[0] = tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] == 0 ? 0 : 1;
139 ucontrol
->value
.integer
.value
[1] = tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] == 0 ? 0 : 1;
140 snd_i2c_unlock(tea
->bus
);
144 static int snd_tea6330t_put_master_switch(struct snd_kcontrol
*kcontrol
,
145 struct snd_ctl_elem_value
*ucontrol
)
147 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
149 unsigned char bytes
[3];
150 unsigned char oval1
, oval2
, val1
, val2
;
152 val1
= ucontrol
->value
.integer
.value
[0] & 1;
153 val2
= ucontrol
->value
.integer
.value
[1] & 1;
154 snd_i2c_lock(tea
->bus
);
155 oval1
= tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] == 0 ? 0 : 1;
156 oval2
= tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] == 0 ? 0 : 1;
157 change
= val1
!= oval1
|| val2
!= oval2
;
158 tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
] = val1
? tea
->mleft
: 0;
159 tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
] = val2
? tea
->mright
: 0;
160 bytes
[0] = TEA6330T_SADDR_VOLUME_LEFT
;
161 bytes
[1] = tea
->regs
[TEA6330T_SADDR_VOLUME_LEFT
];
162 bytes
[2] = tea
->regs
[TEA6330T_SADDR_VOLUME_RIGHT
];
163 if ((err
= snd_i2c_sendbytes(tea
->device
, bytes
, 3)) < 0)
165 snd_i2c_unlock(tea
->bus
);
169 #define TEA6330T_BASS(xname, xindex) \
170 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
171 .info = snd_tea6330t_info_bass, \
172 .get = snd_tea6330t_get_bass, .put = snd_tea6330t_put_bass }
174 static int snd_tea6330t_info_bass(struct snd_kcontrol
*kcontrol
,
175 struct snd_ctl_elem_info
*uinfo
)
177 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
179 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
181 uinfo
->value
.integer
.min
= 0;
182 uinfo
->value
.integer
.max
= tea
->max_bass
;
186 static int snd_tea6330t_get_bass(struct snd_kcontrol
*kcontrol
,
187 struct snd_ctl_elem_value
*ucontrol
)
189 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
191 ucontrol
->value
.integer
.value
[0] = tea
->bass
;
195 static int snd_tea6330t_put_bass(struct snd_kcontrol
*kcontrol
,
196 struct snd_ctl_elem_value
*ucontrol
)
198 struct tea6330t
*tea
= snd_kcontrol_chip(kcontrol
);
200 unsigned char bytes
[2];
203 val1
= ucontrol
->value
.integer
.value
[0] % (tea
->max_bass
+ 1);
204 snd_i2c_lock(tea
->bus
);
206 val1
+= tea
->equalizer
? 7 : 3;
207 change
= tea
->regs
[TEA6330T_SADDR_BASS
] != val1
;
208 bytes
[0] = TEA6330T_SADDR_BASS
;
209 bytes
[1] = tea
->regs
[TEA6330T_SADDR_BASS
] = val1
;
210 if ((err
= snd_i2c_sendbytes(tea
->device
, bytes
, 2)) < 0)
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 if ((err
= snd_i2c_sendbytes(tea
->device
, bytes
, 2)) < 0)
259 snd_i2c_unlock(tea
->bus
);
263 static const struct snd_kcontrol_new snd_tea6330t_controls
[] = {
264 TEA6330T_MASTER_SWITCH("Master Playback Switch", 0),
265 TEA6330T_MASTER_VOLUME("Master Playback Volume", 0),
266 TEA6330T_BASS("Tone Control - Bass", 0),
267 TEA6330T_TREBLE("Tone Control - Treble", 0)
270 static void snd_tea6330_free(struct snd_i2c_device
*device
)
272 kfree(device
->private_data
);
275 int snd_tea6330t_update_mixer(struct snd_card
*card
,
276 struct snd_i2c_bus
*bus
,
277 int equalizer
, int fader
)
279 struct snd_i2c_device
*device
;
280 struct tea6330t
*tea
;
281 const struct snd_kcontrol_new
*knew
;
284 u8 default_treble
, default_bass
;
285 unsigned char bytes
[7];
287 tea
= kzalloc(sizeof(*tea
), GFP_KERNEL
);
290 if ((err
= snd_i2c_device_create(bus
, "TEA6330T", TEA6330T_ADDR
, &device
)) < 0) {
294 tea
->device
= device
;
296 tea
->equalizer
= equalizer
;
298 device
->private_data
= tea
;
299 device
->private_free
= snd_tea6330_free
;
303 /* turn fader off and handle equalizer */
304 tea
->regs
[TEA6330T_SADDR_FADER
] = 0x3f;
305 tea
->regs
[TEA6330T_SADDR_AUDIO_SWITCH
] = equalizer
? 0 : TEA6330T_EQN
;
306 /* initialize mixer */
307 if (!tea
->equalizer
) {
310 default_bass
= 3 + 4;
312 default_treble
= 3 + 4;
317 default_bass
= 7 + 4;
322 tea
->mleft
= tea
->mright
= 0x14;
323 tea
->regs
[TEA6330T_SADDR_BASS
] = default_bass
;
324 tea
->regs
[TEA6330T_SADDR_TREBLE
] = default_treble
;
326 /* compose I2C message and put the hardware to initial state */
327 bytes
[0] = TEA6330T_SADDR_VOLUME_LEFT
;
328 for (idx
= 0; idx
< 6; idx
++)
329 bytes
[idx
+1] = tea
->regs
[idx
];
330 if ((err
= snd_i2c_sendbytes(device
, bytes
, 7)) < 0)
333 strcat(card
->mixername
, ",TEA6330T");
334 if ((err
= snd_component_add(card
, "TEA6330T")) < 0)
337 for (idx
= 0; idx
< ARRAY_SIZE(snd_tea6330t_controls
); idx
++) {
338 knew
= &snd_tea6330t_controls
[idx
];
339 if (tea
->treble
== 0 && !strcmp(knew
->name
, "Tone Control - Treble"))
341 if ((err
= snd_ctl_add(card
, snd_ctl_new1(knew
, tea
))) < 0)
350 snd_i2c_device_free(device
);
354 EXPORT_SYMBOL(snd_tea6330t_detect
);
355 EXPORT_SYMBOL(snd_tea6330t_update_mixer
);