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