1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 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> 6 */ 7 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> 14 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"); 18 19 #define TEA6330T_ADDR (0x80>>1) /* fixed address */ 20 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) */ 31 32 33 struct tea6330t { 34 struct snd_i2c_device *device; 35 struct snd_i2c_bus *bus; 36 int equalizer; 37 int fader; 38 unsigned char regs[8]; 39 unsigned char mleft, mright; 40 unsigned char bass, treble; 41 unsigned char max_bass, max_treble; 42 }; 43 44 45 int snd_tea6330t_detect(struct snd_i2c_bus *bus, int equalizer) 46 { 47 int res; 48 49 snd_i2c_lock(bus); 50 res = snd_i2c_probeaddr(bus, TEA6330T_ADDR); 51 snd_i2c_unlock(bus); 52 return res; 53 } 54 EXPORT_SYMBOL(snd_tea6330t_detect); 55 56 #if 0 57 static void snd_tea6330t_set(struct tea6330t *tea, 58 unsigned char addr, unsigned char value) 59 { 60 snd_i2c_write(tea->bus, TEA6330T_ADDR, addr, value, 1); 61 } 62 #endif 63 64 #define TEA6330T_MASTER_VOLUME(xname, xindex) \ 65 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 66 .info = snd_tea6330t_info_master_volume, \ 67 .get = snd_tea6330t_get_master_volume, .put = snd_tea6330t_put_master_volume } 68 69 static int snd_tea6330t_info_master_volume(struct snd_kcontrol *kcontrol, 70 struct snd_ctl_elem_info *uinfo) 71 { 72 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 73 uinfo->count = 2; 74 uinfo->value.integer.min = 0; 75 uinfo->value.integer.max = 43; 76 return 0; 77 } 78 79 static int snd_tea6330t_get_master_volume(struct snd_kcontrol *kcontrol, 80 struct snd_ctl_elem_value *ucontrol) 81 { 82 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 83 84 snd_i2c_lock(tea->bus); 85 ucontrol->value.integer.value[0] = tea->mleft - 0x14; 86 ucontrol->value.integer.value[1] = tea->mright - 0x14; 87 snd_i2c_unlock(tea->bus); 88 return 0; 89 } 90 91 static int snd_tea6330t_put_master_volume(struct snd_kcontrol *kcontrol, 92 struct snd_ctl_elem_value *ucontrol) 93 { 94 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 95 int change, count, err; 96 unsigned char bytes[3]; 97 unsigned char val1, val2; 98 99 val1 = (ucontrol->value.integer.value[0] % 44) + 0x14; 100 val2 = (ucontrol->value.integer.value[1] % 44) + 0x14; 101 snd_i2c_lock(tea->bus); 102 change = val1 != tea->mleft || val2 != tea->mright; 103 tea->mleft = val1; 104 tea->mright = val2; 105 count = 0; 106 if (tea->regs[TEA6330T_SADDR_VOLUME_LEFT] != 0) { 107 bytes[count++] = TEA6330T_SADDR_VOLUME_LEFT; 108 bytes[count++] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] = tea->mleft; 109 } 110 if (tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] != 0) { 111 if (count == 0) 112 bytes[count++] = TEA6330T_SADDR_VOLUME_RIGHT; 113 bytes[count++] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = tea->mright; 114 } 115 if (count > 0) { 116 err = snd_i2c_sendbytes(tea->device, bytes, count); 117 if (err < 0) 118 change = err; 119 } 120 snd_i2c_unlock(tea->bus); 121 return change; 122 } 123 124 #define TEA6330T_MASTER_SWITCH(xname, xindex) \ 125 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 126 .info = snd_tea6330t_info_master_switch, \ 127 .get = snd_tea6330t_get_master_switch, .put = snd_tea6330t_put_master_switch } 128 129 #define snd_tea6330t_info_master_switch snd_ctl_boolean_stereo_info 130 131 static int snd_tea6330t_get_master_switch(struct snd_kcontrol *kcontrol, 132 struct snd_ctl_elem_value *ucontrol) 133 { 134 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 135 136 snd_i2c_lock(tea->bus); 137 ucontrol->value.integer.value[0] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] == 0 ? 0 : 1; 138 ucontrol->value.integer.value[1] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] == 0 ? 0 : 1; 139 snd_i2c_unlock(tea->bus); 140 return 0; 141 } 142 143 static int snd_tea6330t_put_master_switch(struct snd_kcontrol *kcontrol, 144 struct snd_ctl_elem_value *ucontrol) 145 { 146 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 147 int change, err; 148 unsigned char bytes[3]; 149 unsigned char oval1, oval2, val1, val2; 150 151 val1 = ucontrol->value.integer.value[0] & 1; 152 val2 = ucontrol->value.integer.value[1] & 1; 153 snd_i2c_lock(tea->bus); 154 oval1 = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] == 0 ? 0 : 1; 155 oval2 = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] == 0 ? 0 : 1; 156 change = val1 != oval1 || val2 != oval2; 157 tea->regs[TEA6330T_SADDR_VOLUME_LEFT] = val1 ? tea->mleft : 0; 158 tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = val2 ? tea->mright : 0; 159 bytes[0] = TEA6330T_SADDR_VOLUME_LEFT; 160 bytes[1] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT]; 161 bytes[2] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT]; 162 err = snd_i2c_sendbytes(tea->device, bytes, 3); 163 if (err < 0) 164 change = err; 165 snd_i2c_unlock(tea->bus); 166 return change; 167 } 168 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 } 173 174 static int snd_tea6330t_info_bass(struct snd_kcontrol *kcontrol, 175 struct snd_ctl_elem_info *uinfo) 176 { 177 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 178 179 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 180 uinfo->count = 1; 181 uinfo->value.integer.min = 0; 182 uinfo->value.integer.max = tea->max_bass; 183 return 0; 184 } 185 186 static int snd_tea6330t_get_bass(struct snd_kcontrol *kcontrol, 187 struct snd_ctl_elem_value *ucontrol) 188 { 189 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 190 191 ucontrol->value.integer.value[0] = tea->bass; 192 return 0; 193 } 194 195 static int snd_tea6330t_put_bass(struct snd_kcontrol *kcontrol, 196 struct snd_ctl_elem_value *ucontrol) 197 { 198 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 199 int change, err; 200 unsigned char bytes[2]; 201 unsigned char val1; 202 203 val1 = ucontrol->value.integer.value[0] % (tea->max_bass + 1); 204 snd_i2c_lock(tea->bus); 205 tea->bass = val1; 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 err = snd_i2c_sendbytes(tea->device, bytes, 2); 211 if (err < 0) 212 change = err; 213 snd_i2c_unlock(tea->bus); 214 return change; 215 } 216 217 #define TEA6330T_TREBLE(xname, xindex) \ 218 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 219 .info = snd_tea6330t_info_treble, \ 220 .get = snd_tea6330t_get_treble, .put = snd_tea6330t_put_treble } 221 222 static int snd_tea6330t_info_treble(struct snd_kcontrol *kcontrol, 223 struct snd_ctl_elem_info *uinfo) 224 { 225 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 226 227 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 228 uinfo->count = 1; 229 uinfo->value.integer.min = 0; 230 uinfo->value.integer.max = tea->max_treble; 231 return 0; 232 } 233 234 static int snd_tea6330t_get_treble(struct snd_kcontrol *kcontrol, 235 struct snd_ctl_elem_value *ucontrol) 236 { 237 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 238 239 ucontrol->value.integer.value[0] = tea->treble; 240 return 0; 241 } 242 243 static int snd_tea6330t_put_treble(struct snd_kcontrol *kcontrol, 244 struct snd_ctl_elem_value *ucontrol) 245 { 246 struct tea6330t *tea = snd_kcontrol_chip(kcontrol); 247 int change, err; 248 unsigned char bytes[2]; 249 unsigned char val1; 250 251 val1 = ucontrol->value.integer.value[0] % (tea->max_treble + 1); 252 snd_i2c_lock(tea->bus); 253 tea->treble = val1; 254 val1 += 3; 255 change = tea->regs[TEA6330T_SADDR_TREBLE] != val1; 256 bytes[0] = TEA6330T_SADDR_TREBLE; 257 bytes[1] = tea->regs[TEA6330T_SADDR_TREBLE] = val1; 258 err = snd_i2c_sendbytes(tea->device, bytes, 2); 259 if (err < 0) 260 change = err; 261 snd_i2c_unlock(tea->bus); 262 return change; 263 } 264 265 static const struct snd_kcontrol_new snd_tea6330t_controls[] = { 266 TEA6330T_MASTER_SWITCH("Master Playback Switch", 0), 267 TEA6330T_MASTER_VOLUME("Master Playback Volume", 0), 268 TEA6330T_BASS("Tone Control - Bass", 0), 269 TEA6330T_TREBLE("Tone Control - Treble", 0) 270 }; 271 272 static void snd_tea6330_free(struct snd_i2c_device *device) 273 { 274 kfree(device->private_data); 275 } 276 277 int snd_tea6330t_update_mixer(struct snd_card *card, 278 struct snd_i2c_bus *bus, 279 int equalizer, int fader) 280 { 281 struct snd_i2c_device *device; 282 struct tea6330t *tea; 283 const struct snd_kcontrol_new *knew; 284 unsigned int idx; 285 int err; 286 u8 default_treble, default_bass; 287 unsigned char bytes[7]; 288 289 tea = kzalloc_obj(*tea); 290 if (tea == NULL) 291 return -ENOMEM; 292 err = snd_i2c_device_create(bus, "TEA6330T", TEA6330T_ADDR, &device); 293 if (err < 0) { 294 kfree(tea); 295 return err; 296 } 297 tea->device = device; 298 tea->bus = bus; 299 tea->equalizer = equalizer; 300 tea->fader = fader; 301 device->private_data = tea; 302 device->private_free = snd_tea6330_free; 303 304 snd_i2c_lock(bus); 305 306 /* turn fader off and handle equalizer */ 307 tea->regs[TEA6330T_SADDR_FADER] = 0x3f; 308 tea->regs[TEA6330T_SADDR_AUDIO_SWITCH] = equalizer ? 0 : TEA6330T_EQN; 309 /* initialize mixer */ 310 if (!tea->equalizer) { 311 tea->max_bass = 9; 312 tea->max_treble = 8; 313 default_bass = 3 + 4; 314 tea->bass = 4; 315 default_treble = 3 + 4; 316 tea->treble = 4; 317 } else { 318 tea->max_bass = 5; 319 tea->max_treble = 0; 320 default_bass = 7 + 4; 321 tea->bass = 4; 322 default_treble = 3; 323 tea->treble = 0; 324 } 325 tea->mleft = tea->mright = 0x14; 326 tea->regs[TEA6330T_SADDR_BASS] = default_bass; 327 tea->regs[TEA6330T_SADDR_TREBLE] = default_treble; 328 329 /* compose I2C message and put the hardware to initial state */ 330 bytes[0] = TEA6330T_SADDR_VOLUME_LEFT; 331 for (idx = 0; idx < 6; idx++) 332 bytes[idx+1] = tea->regs[idx]; 333 err = snd_i2c_sendbytes(device, bytes, 7); 334 if (err < 0) 335 goto __error; 336 337 strcat(card->mixername, ",TEA6330T"); 338 err = snd_component_add(card, "TEA6330T"); 339 if (err < 0) 340 goto __error; 341 342 for (idx = 0; idx < ARRAY_SIZE(snd_tea6330t_controls); idx++) { 343 knew = &snd_tea6330t_controls[idx]; 344 if (tea->treble == 0 && !strcmp(knew->name, "Tone Control - Treble")) 345 continue; 346 err = snd_ctl_add(card, snd_ctl_new1(knew, tea)); 347 if (err < 0) 348 goto __error; 349 } 350 351 snd_i2c_unlock(bus); 352 return 0; 353 354 __error: 355 snd_i2c_unlock(bus); 356 snd_i2c_device_free(device); 357 return err; 358 } 359 EXPORT_SYMBOL(snd_tea6330t_update_mixer); 360 361 int snd_tea6330t_restore_mixer(struct snd_i2c_bus *bus) 362 { 363 struct snd_i2c_device *device; 364 struct tea6330t *tea; 365 unsigned char bytes[7]; 366 unsigned int idx; 367 int err; 368 369 if (!bus) 370 return -EINVAL; 371 372 snd_i2c_lock(bus); 373 list_for_each_entry(device, &bus->devices, list) { 374 if (device->addr != TEA6330T_ADDR) 375 continue; 376 377 tea = device->private_data; 378 if (!tea) { 379 err = -EINVAL; 380 goto unlock; 381 } 382 383 bytes[0] = TEA6330T_SADDR_VOLUME_LEFT; 384 for (idx = 0; idx < 6; idx++) 385 bytes[idx + 1] = tea->regs[idx]; 386 err = snd_i2c_sendbytes(device, bytes, 7); 387 err = err < 0 ? err : 0; 388 goto unlock; 389 } 390 391 err = -ENODEV; 392 393 unlock: 394 snd_i2c_unlock(bus); 395 return err; 396 } 397 EXPORT_SYMBOL(snd_tea6330t_restore_mixer); 398