Linux Audio

Check our new training course

Loading...
  1/*
  2 *  Routines for control of the TEA6330T circuit via i2c bus
  3 *  Sound fader control circuit for car radios by Philips Semiconductors
  4 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  5 *
  6 *
  7 *   This program is free software; you can redistribute it and/or modify
  8 *   it under the terms of the GNU General Public License as published by
  9 *   the Free Software Foundation; either version 2 of the License, or
 10 *   (at your option) any later version.
 11 *
 12 *   This program is distributed in the hope that it will be useful,
 13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15 *   GNU General Public License for more details.
 16 *
 17 *   You should have received a copy of the GNU General Public License
 18 *   along with this program; if not, write to the Free Software
 19 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 20 *
 21 */
 22
 23#include <linux/init.h>
 24#include <linux/slab.h>
 25#include <linux/module.h>
 26#include <sound/core.h>
 27#include <sound/control.h>
 28#include <sound/tea6330t.h>
 29
 30MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 31MODULE_DESCRIPTION("Routines for control of the TEA6330T circuit via i2c bus");
 32MODULE_LICENSE("GPL");
 33
 34#define TEA6330T_ADDR			(0x80>>1) /* fixed address */
 35
 36#define TEA6330T_SADDR_VOLUME_LEFT	0x00	/* volume left */
 37#define TEA6330T_SADDR_VOLUME_RIGHT	0x01	/* volume right */
 38#define TEA6330T_SADDR_BASS		0x02	/* bass control */
 39#define TEA6330T_SADDR_TREBLE		0x03	/* treble control */
 40#define TEA6330T_SADDR_FADER		0x04	/* fader control */
 41#define   TEA6330T_MFN			0x20	/* mute control for selected channels */
 42#define   TEA6330T_FCH			0x10	/* select fader channels - front or rear */
 43#define TEA6330T_SADDR_AUDIO_SWITCH	0x05	/* audio switch */
 44#define   TEA6330T_GMU			0x80	/* mute control, general mute */
 45#define   TEA6330T_EQN			0x40	/* equalizer switchover (0=equalizer-on) */
 46
 47
 48struct tea6330t {
 49	struct snd_i2c_device *device;
 50	struct snd_i2c_bus *bus;
 51	int equalizer;
 52	int fader;
 53	unsigned char regs[8];
 54	unsigned char mleft, mright;
 55	unsigned char bass, treble;
 56	unsigned char max_bass, max_treble;
 57};
 58
 59
 60int snd_tea6330t_detect(struct snd_i2c_bus *bus, int equalizer)
 61{
 62	int res;
 63
 64	snd_i2c_lock(bus);
 65	res = snd_i2c_probeaddr(bus, TEA6330T_ADDR);
 66	snd_i2c_unlock(bus);
 67	return res;
 68}
 69
 70#if 0
 71static void snd_tea6330t_set(struct tea6330t *tea,
 72			     unsigned char addr, unsigned char value)
 73{
 74#if 0
 75	printk(KERN_DEBUG "set - 0x%x/0x%x\n", addr, value);
 76#endif
 77	snd_i2c_write(tea->bus, TEA6330T_ADDR, addr, value, 1);
 78}
 79#endif
 80
 81#define TEA6330T_MASTER_VOLUME(xname, xindex) \
 82{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
 83  .info = snd_tea6330t_info_master_volume, \
 84  .get = snd_tea6330t_get_master_volume, .put = snd_tea6330t_put_master_volume }
 85
 86static int snd_tea6330t_info_master_volume(struct snd_kcontrol *kcontrol,
 87					   struct snd_ctl_elem_info *uinfo)
 88{
 89	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 90	uinfo->count = 2;
 91	uinfo->value.integer.min = 0;
 92	uinfo->value.integer.max = 43;
 93	return 0;
 94}
 95
 96static int snd_tea6330t_get_master_volume(struct snd_kcontrol *kcontrol,
 97					  struct snd_ctl_elem_value *ucontrol)
 98{
 99	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
100	
101	snd_i2c_lock(tea->bus);
102	ucontrol->value.integer.value[0] = tea->mleft - 0x14;
103	ucontrol->value.integer.value[1] = tea->mright - 0x14;
104	snd_i2c_unlock(tea->bus);
105	return 0;
106}
107
108static int snd_tea6330t_put_master_volume(struct snd_kcontrol *kcontrol,
109					  struct snd_ctl_elem_value *ucontrol)
110{
111	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
112	int change, count, err;
113	unsigned char bytes[3];
114	unsigned char val1, val2;
115	
116	val1 = (ucontrol->value.integer.value[0] % 44) + 0x14;
117	val2 = (ucontrol->value.integer.value[1] % 44) + 0x14;
118	snd_i2c_lock(tea->bus);
119	change = val1 != tea->mleft || val2 != tea->mright;
120	tea->mleft = val1;
121	tea->mright = val2;
122	count = 0;
123	if (tea->regs[TEA6330T_SADDR_VOLUME_LEFT] != 0) {
124		bytes[count++] = TEA6330T_SADDR_VOLUME_LEFT;
125		bytes[count++] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] = tea->mleft;
126	}
127	if (tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] != 0) {
128		if (count == 0)
129			bytes[count++] = TEA6330T_SADDR_VOLUME_RIGHT;
130		bytes[count++] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = tea->mright;
131	}
132	if (count > 0) {
133		if ((err = snd_i2c_sendbytes(tea->device, bytes, count)) < 0)
134			change = err;
135	}
136	snd_i2c_unlock(tea->bus);
137	return change;
138}
139
140#define TEA6330T_MASTER_SWITCH(xname, xindex) \
141{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
142  .info = snd_tea6330t_info_master_switch, \
143  .get = snd_tea6330t_get_master_switch, .put = snd_tea6330t_put_master_switch }
144
145#define snd_tea6330t_info_master_switch		snd_ctl_boolean_stereo_info
146
147static int snd_tea6330t_get_master_switch(struct snd_kcontrol *kcontrol,
148					  struct snd_ctl_elem_value *ucontrol)
149{
150	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
151	
152	snd_i2c_lock(tea->bus);
153	ucontrol->value.integer.value[0] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] == 0 ? 0 : 1;
154	ucontrol->value.integer.value[1] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] == 0 ? 0 : 1;
155	snd_i2c_unlock(tea->bus);
156	return 0;
157}
158
159static int snd_tea6330t_put_master_switch(struct snd_kcontrol *kcontrol,
160					  struct snd_ctl_elem_value *ucontrol)
161{
162	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
163	int change, err;
164	unsigned char bytes[3];
165	unsigned char oval1, oval2, val1, val2;
166	
167	val1 = ucontrol->value.integer.value[0] & 1;
168	val2 = ucontrol->value.integer.value[1] & 1;
169	snd_i2c_lock(tea->bus);
170	oval1 = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] == 0 ? 0 : 1;
171	oval2 = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] == 0 ? 0 : 1;
172	change = val1 != oval1 || val2 != oval2;
173	tea->regs[TEA6330T_SADDR_VOLUME_LEFT] = val1 ? tea->mleft : 0;
174	tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = val2 ? tea->mright : 0;
175	bytes[0] = TEA6330T_SADDR_VOLUME_LEFT;
176	bytes[1] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT];
177	bytes[2] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT];
178	if ((err = snd_i2c_sendbytes(tea->device, bytes, 3)) < 0)
179		change = err;
180	snd_i2c_unlock(tea->bus);
181	return change;
182}
183
184#define TEA6330T_BASS(xname, xindex) \
185{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
186  .info = snd_tea6330t_info_bass, \
187  .get = snd_tea6330t_get_bass, .put = snd_tea6330t_put_bass }
188
189static int snd_tea6330t_info_bass(struct snd_kcontrol *kcontrol,
190				  struct snd_ctl_elem_info *uinfo)
191{
192	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
193
194	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
195	uinfo->count = 1;
196	uinfo->value.integer.min = 0;
197	uinfo->value.integer.max = tea->max_bass;
198	return 0;
199}
200
201static int snd_tea6330t_get_bass(struct snd_kcontrol *kcontrol,
202				 struct snd_ctl_elem_value *ucontrol)
203{
204	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
205	
206	ucontrol->value.integer.value[0] = tea->bass;
207	return 0;
208}
209
210static int snd_tea6330t_put_bass(struct snd_kcontrol *kcontrol,
211				 struct snd_ctl_elem_value *ucontrol)
212{
213	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
214	int change, err;
215	unsigned char bytes[2];
216	unsigned char val1;
217	
218	val1 = ucontrol->value.integer.value[0] % (tea->max_bass + 1);
219	snd_i2c_lock(tea->bus);
220	tea->bass = val1;
221	val1 += tea->equalizer ? 7 : 3;
222	change = tea->regs[TEA6330T_SADDR_BASS] != val1;
223	bytes[0] = TEA6330T_SADDR_BASS;
224	bytes[1] = tea->regs[TEA6330T_SADDR_BASS] = val1;
225	if ((err = snd_i2c_sendbytes(tea->device, bytes, 2)) < 0)
226		change = err;
227	snd_i2c_unlock(tea->bus);
228	return change;
229}
230
231#define TEA6330T_TREBLE(xname, xindex) \
232{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
233  .info = snd_tea6330t_info_treble, \
234  .get = snd_tea6330t_get_treble, .put = snd_tea6330t_put_treble }
235
236static int snd_tea6330t_info_treble(struct snd_kcontrol *kcontrol,
237				    struct snd_ctl_elem_info *uinfo)
238{
239	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
240
241	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
242	uinfo->count = 1;
243	uinfo->value.integer.min = 0;
244	uinfo->value.integer.max = tea->max_treble;
245	return 0;
246}
247
248static int snd_tea6330t_get_treble(struct snd_kcontrol *kcontrol,
249				   struct snd_ctl_elem_value *ucontrol)
250{
251	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
252	
253	ucontrol->value.integer.value[0] = tea->treble;
254	return 0;
255}
256
257static int snd_tea6330t_put_treble(struct snd_kcontrol *kcontrol,
258				   struct snd_ctl_elem_value *ucontrol)
259{
260	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
261	int change, err;
262	unsigned char bytes[2];
263	unsigned char val1;
264	
265	val1 = ucontrol->value.integer.value[0] % (tea->max_treble + 1);
266	snd_i2c_lock(tea->bus);
267	tea->treble = val1;
268	val1 += 3;
269	change = tea->regs[TEA6330T_SADDR_TREBLE] != val1;
270	bytes[0] = TEA6330T_SADDR_TREBLE;
271	bytes[1] = tea->regs[TEA6330T_SADDR_TREBLE] = val1;
272	if ((err = snd_i2c_sendbytes(tea->device, bytes, 2)) < 0)
273		change = err;
274	snd_i2c_unlock(tea->bus);
275	return change;
276}
277
278static struct snd_kcontrol_new snd_tea6330t_controls[] = {
279TEA6330T_MASTER_SWITCH("Master Playback Switch", 0),
280TEA6330T_MASTER_VOLUME("Master Playback Volume", 0),
281TEA6330T_BASS("Tone Control - Bass", 0),
282TEA6330T_TREBLE("Tone Control - Treble", 0)
283};
284
285static void snd_tea6330_free(struct snd_i2c_device *device)
286{
287	kfree(device->private_data);
288}
289                                        
290int snd_tea6330t_update_mixer(struct snd_card *card,
291			      struct snd_i2c_bus *bus,
292			      int equalizer, int fader)
293{
294	struct snd_i2c_device *device;
295	struct tea6330t *tea;
296	struct snd_kcontrol_new *knew;
297	unsigned int idx;
298	int err = -ENOMEM;
299	u8 default_treble, default_bass;
300	unsigned char bytes[7];
301
302	tea = kzalloc(sizeof(*tea), GFP_KERNEL);
303	if (tea == NULL)
304		return -ENOMEM;
305	if ((err = snd_i2c_device_create(bus, "TEA6330T", TEA6330T_ADDR, &device)) < 0) {
306		kfree(tea);
307		return err;
308	}
309	tea->device = device;
310	tea->bus = bus;
311	tea->equalizer = equalizer;
312	tea->fader = fader;
313	device->private_data = tea;
314	device->private_free = snd_tea6330_free;
315
316	snd_i2c_lock(bus);
317
318	/* turn fader off and handle equalizer */
319	tea->regs[TEA6330T_SADDR_FADER] = 0x3f;
320	tea->regs[TEA6330T_SADDR_AUDIO_SWITCH] = equalizer ? 0 : TEA6330T_EQN;
321	/* initialize mixer */
322	if (!tea->equalizer) {
323		tea->max_bass = 9;
324		tea->max_treble = 8;
325		default_bass = 3 + 4;
326		tea->bass = 4;
327		default_treble = 3 + 4;
328		tea->treble = 4;
329	} else {
330		tea->max_bass = 5;
331		tea->max_treble = 0;
332		default_bass = 7 + 4;
333		tea->bass = 4;
334		default_treble = 3;
335		tea->treble = 0;
336	}
337	tea->mleft = tea->mright = 0x14;
338	tea->regs[TEA6330T_SADDR_BASS] = default_bass;
339	tea->regs[TEA6330T_SADDR_TREBLE] = default_treble;
340
341	/* compose I2C message and put the hardware to initial state */
342	bytes[0] = TEA6330T_SADDR_VOLUME_LEFT;
343	for (idx = 0; idx < 6; idx++)
344		bytes[idx+1] = tea->regs[idx];
345	if ((err = snd_i2c_sendbytes(device, bytes, 7)) < 0)
346		goto __error;
347
348	strcat(card->mixername, ",TEA6330T");
349	if ((err = snd_component_add(card, "TEA6330T")) < 0)
350		goto __error;
351
352	for (idx = 0; idx < ARRAY_SIZE(snd_tea6330t_controls); idx++) {
353		knew = &snd_tea6330t_controls[idx];
354		if (tea->treble == 0 && !strcmp(knew->name, "Tone Control - Treble"))
355			continue;
356		if ((err = snd_ctl_add(card, snd_ctl_new1(knew, tea))) < 0)
357			goto __error;
358	}
359
360	snd_i2c_unlock(bus);
361	return 0;
362	
363      __error:
364      	snd_i2c_unlock(bus);
365      	snd_i2c_device_free(device);
366      	return err;
367}
368
369EXPORT_SYMBOL(snd_tea6330t_detect);
370EXPORT_SYMBOL(snd_tea6330t_update_mixer);
371
372/*
373 *  INIT part
374 */
375
376static int __init alsa_tea6330t_init(void)
377{
378	return 0;
379}
380
381static void __exit alsa_tea6330t_exit(void)
382{
383}
384
385module_init(alsa_tea6330t_init)
386module_exit(alsa_tea6330t_exit)