1/* 2 * For the STS-Thompson TDA7432 audio processor chip 3 * 4 * Handles audio functions: volume, balance, tone, loudness 5 * This driver will not complain if used with any 6 * other i2c device with the same address. 7 * 8 * Muting and tone control by Jonathan Isom <jisom@ematic.com> 9 * 10 * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com> 11 * This code is placed under the terms of the GNU General Public License 12 * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) 13 * Which was based on tda8425.c by Greg Alexander (c) 1998 14 * 15 * OPTIONS: 16 * debug - set to 1 if you'd like to see debug messages 17 * set to 2 if you'd like to be inundated with debug messages 18 * 19 * loudness - set between 0 and 15 for varying degrees of loudness effect 20 * 21 * maxvol - set maximium volume to +20db (1), default is 0db(0) 22 * 23 * 24 * Revision: 0.7 - maxvol module parm to set maximium volume 0db or +20db 25 * store if muted so we can return it 26 * change balance only if flaged to 27 * Revision: 0.6 - added tone controls 28 * Revision: 0.5 - Fixed odd balance problem 29 * Revision: 0.4 - added muting 30 * Revision: 0.3 - Fixed silly reversed volume controls. :) 31 * Revision: 0.2 - Cleaned up #defines 32 * fixed volume control 33 * Added I2C_DRIVERID_TDA7432 34 * added loudness insmod control 35 * Revision: 0.1 - initial version 36 */ 37 38#include <linux/module.h> 39#include <linux/init.h> 40#include <linux/kernel.h> 41#include <linux/string.h> 42#include <linux/timer.h> 43#include <linux/delay.h> 44#include <linux/errno.h> 45#include <linux/slab.h> 46#include <linux/videodev.h> 47#include <linux/i2c.h> 48 49#include <media/v4l2-common.h> 50#include <media/i2c-addr.h> 51 52#ifndef VIDEO_AUDIO_BALANCE 53# define VIDEO_AUDIO_BALANCE 32 54#endif 55 56MODULE_AUTHOR("Eric Sandeen <eric_sandeen@bigfoot.com>"); 57MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip"); 58MODULE_LICENSE("GPL"); 59 60static int maxvol; 61static int loudness; /* disable loudness by default */ 62static int debug; /* insmod parameter */ 63module_param(debug, int, S_IRUGO | S_IWUSR); 64module_param(loudness, int, S_IRUGO); 65MODULE_PARM_DESC(maxvol,"Set maximium volume to +20db (0), default is 0db(1)"); 66module_param(maxvol, int, S_IRUGO | S_IWUSR); 67 68 69/* Address to scan (I2C address of this chip) */ 70static unsigned short normal_i2c[] = { 71 I2C_ADDR_TDA7432 >> 1, 72 I2C_CLIENT_END, 73}; 74I2C_CLIENT_INSMOD; 75 76/* Structure of address and subaddresses for the tda7432 */ 77 78struct tda7432 { 79 int addr; 80 int input; 81 int volume; 82 int muted; 83 int bass, treble; 84 int lf, lr, rf, rr; 85 int loud; 86 struct i2c_client c; 87}; 88static struct i2c_driver driver; 89static struct i2c_client client_template; 90 91/* The TDA7432 is made by STS-Thompson 92 * http://www.st.com 93 * http://us.st.com/stonline/books/pdf/docs/4056.pdf 94 * 95 * TDA7432: I2C-bus controlled basic audio processor 96 * 97 * The TDA7432 controls basic audio functions like volume, balance, 98 * and tone control (including loudness). It also has four channel 99 * output (for front and rear). Since most vidcap cards probably 100 * don't have 4 channel output, this driver will set front & rear 101 * together (no independent control). 102 */ 103 104 /* Subaddresses for TDA7432 */ 105 106#define TDA7432_IN 0x00 /* Input select */ 107#define TDA7432_VL 0x01 /* Volume */ 108#define TDA7432_TN 0x02 /* Bass, Treble (Tone) */ 109#define TDA7432_LF 0x03 /* Attenuation LF (Left Front) */ 110#define TDA7432_LR 0x04 /* Attenuation LR (Left Rear) */ 111#define TDA7432_RF 0x05 /* Attenuation RF (Right Front) */ 112#define TDA7432_RR 0x06 /* Attenuation RR (Right Rear) */ 113#define TDA7432_LD 0x07 /* Loudness */ 114 115 116 /* Masks for bits in TDA7432 subaddresses */ 117 118/* Many of these not used - just for documentation */ 119 120/* Subaddress 0x00 - Input selection and bass control */ 121 122/* Bits 0,1,2 control input: 123 * 0x00 - Stereo input 124 * 0x02 - Mono input 125 * 0x03 - Mute (Using Attenuators Plays better with modules) 126 * Mono probably isn't used - I'm guessing only the stereo 127 * input is connected on most cards, so we'll set it to stereo. 128 * 129 * Bit 3 controls bass cut: 0/1 is non-symmetric/symmetric bass cut 130 * Bit 4 controls bass range: 0/1 is extended/standard bass range 131 * 132 * Highest 3 bits not used 133 */ 134 135#define TDA7432_STEREO_IN 0 136#define TDA7432_MONO_IN 2 /* Probably won't be used */ 137#define TDA7432_BASS_SYM 1 << 3 138#define TDA7432_BASS_NORM 1 << 4 139 140/* Subaddress 0x01 - Volume */ 141 142/* Lower 7 bits control volume from -79dB to +32dB in 1dB steps 143 * Recommended maximum is +20 dB 144 * 145 * +32dB: 0x00 146 * +20dB: 0x0c 147 * 0dB: 0x20 148 * -79dB: 0x6f 149 * 150 * MSB (bit 7) controls loudness: 1/0 is loudness on/off 151 */ 152 153#define TDA7432_VOL_0DB 0x20 154#define TDA7432_LD_ON 1 << 7 155 156 157/* Subaddress 0x02 - Tone control */ 158 159/* Bits 0,1,2 control absolute treble gain from 0dB to 14dB 160 * 0x0 is 14dB, 0x7 is 0dB 161 * 162 * Bit 3 controls treble attenuation/gain (sign) 163 * 1 = gain (+) 164 * 0 = attenuation (-) 165 * 166 * Bits 4,5,6 control absolute bass gain from 0dB to 14dB 167 * (This is only true for normal base range, set in 0x00) 168 * 0x0 << 4 is 14dB, 0x7 is 0dB 169 * 170 * Bit 7 controls bass attenuation/gain (sign) 171 * 1 << 7 = gain (+) 172 * 0 << 7 = attenuation (-) 173 * 174 * Example: 175 * 1 1 0 1 0 1 0 1 is +4dB bass, -4dB treble 176 */ 177 178#define TDA7432_TREBLE_0DB 0xf 179#define TDA7432_TREBLE 7 180#define TDA7432_TREBLE_GAIN 1 << 3 181#define TDA7432_BASS_0DB 0xf 182#define TDA7432_BASS 7 << 4 183#define TDA7432_BASS_GAIN 1 << 7 184 185 186/* Subaddress 0x03 - Left Front attenuation */ 187/* Subaddress 0x04 - Left Rear attenuation */ 188/* Subaddress 0x05 - Right Front attenuation */ 189/* Subaddress 0x06 - Right Rear attenuation */ 190 191/* Bits 0,1,2,3,4 control attenuation from 0dB to -37.5dB 192 * in 1.5dB steps. 193 * 194 * 0x00 is 0dB 195 * 0x1f is -37.5dB 196 * 197 * Bit 5 mutes that channel when set (1 = mute, 0 = unmute) 198 * We'll use the mute on the input, though (above) 199 * Bits 6,7 unused 200 */ 201 202#define TDA7432_ATTEN_0DB 0x00 203#define TDA7432_MUTE 0x1 << 5 204 205 206/* Subaddress 0x07 - Loudness Control */ 207 208/* Bits 0,1,2,3 control loudness from 0dB to -15dB in 1dB steps 209 * when bit 4 is NOT set 210 * 211 * 0x0 is 0dB 212 * 0xf is -15dB 213 * 214 * If bit 4 is set, then there is a flat attenuation according to 215 * the lower 4 bits, as above. 216 * 217 * Bits 5,6,7 unused 218 */ 219 220 221 222/* Begin code */ 223 224static int tda7432_write(struct i2c_client *client, int subaddr, int val) 225{ 226 unsigned char buffer[2]; 227 v4l_dbg(2, debug,client,"In tda7432_write\n"); 228 v4l_dbg(1, debug,client,"Writing %d 0x%x\n", subaddr, val); 229 buffer[0] = subaddr; 230 buffer[1] = val; 231 if (2 != i2c_master_send(client,buffer,2)) { 232 v4l_err(client,"I/O error, trying (write %d 0x%x)\n", 233 subaddr, val); 234 return -1; 235 } 236 return 0; 237} 238 239/* I don't think we ever actually _read_ the chip... */ 240 241static int tda7432_set(struct i2c_client *client) 242{ 243 struct tda7432 *t = i2c_get_clientdata(client); 244 unsigned char buf[16]; 245 v4l_dbg(2, debug,client,"In tda7432_set\n"); 246 247 v4l_dbg(1, debug,client, 248 "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", 249 t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud); 250 buf[0] = TDA7432_IN; 251 buf[1] = t->input; 252 buf[2] = t->volume; 253 buf[3] = t->bass; 254 buf[4] = t->treble; 255 buf[5] = t->lf; 256 buf[6] = t->lr; 257 buf[7] = t->rf; 258 buf[8] = t->rr; 259 buf[9] = t->loud; 260 if (10 != i2c_master_send(client,buf,10)) { 261 v4l_err(client,"I/O error, trying tda7432_set\n"); 262 return -1; 263 } 264 265 return 0; 266} 267 268static void do_tda7432_init(struct i2c_client *client) 269{ 270 struct tda7432 *t = i2c_get_clientdata(client); 271 v4l_dbg(2, debug,client,"In tda7432_init\n"); 272 273 t->input = TDA7432_STEREO_IN | /* Main (stereo) input */ 274 TDA7432_BASS_SYM | /* Symmetric bass cut */ 275 TDA7432_BASS_NORM; /* Normal bass range */ 276 t->volume = 0x3b ; /* -27dB Volume */ 277 if (loudness) /* Turn loudness on? */ 278 t->volume |= TDA7432_LD_ON; 279 t->muted = VIDEO_AUDIO_MUTE; 280 t->treble = TDA7432_TREBLE_0DB; /* 0dB Treble */ 281 t->bass = TDA7432_BASS_0DB; /* 0dB Bass */ 282 t->lf = TDA7432_ATTEN_0DB; /* 0dB attenuation */ 283 t->lr = TDA7432_ATTEN_0DB; /* 0dB attenuation */ 284 t->rf = TDA7432_ATTEN_0DB; /* 0dB attenuation */ 285 t->rr = TDA7432_ATTEN_0DB; /* 0dB attenuation */ 286 t->loud = loudness; /* insmod parameter */ 287 288 tda7432_set(client); 289} 290 291/* *********************** * 292 * i2c interface functions * 293 * *********************** */ 294 295static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) 296{ 297 struct tda7432 *t; 298 struct i2c_client *client; 299 300 t = kzalloc(sizeof *t,GFP_KERNEL); 301 if (!t) 302 return -ENOMEM; 303 304 client = &t->c; 305 memcpy(client,&client_template,sizeof(struct i2c_client)); 306 client->adapter = adap; 307 client->addr = addr; 308 i2c_set_clientdata(client, t); 309 310 do_tda7432_init(client); 311 i2c_attach_client(client); 312 313 v4l_info(client, "chip found @ 0x%x (%s)\n", addr << 1, adap->name); 314 return 0; 315} 316 317static int tda7432_probe(struct i2c_adapter *adap) 318{ 319 if (adap->class & I2C_CLASS_TV_ANALOG) 320 return i2c_probe(adap, &addr_data, tda7432_attach); 321 return 0; 322} 323 324static int tda7432_detach(struct i2c_client *client) 325{ 326 struct tda7432 *t = i2c_get_clientdata(client); 327 328 do_tda7432_init(client); 329 i2c_detach_client(client); 330 331 kfree(t); 332 return 0; 333} 334 335static int tda7432_command(struct i2c_client *client, 336 unsigned int cmd, void *arg) 337{ 338 struct tda7432 *t = i2c_get_clientdata(client); 339 v4l_dbg(2, debug,client,"In tda7432_command\n"); 340 if (debug>1) 341 v4l_i2c_print_ioctl(client,cmd); 342 343 switch (cmd) { 344 /* --- v4l ioctls --- */ 345 /* take care: bttv does userspace copying, we'll get a 346 kernel pointer here... */ 347 348 /* Query card - scale from TDA7432 settings to V4L settings */ 349 case VIDIOCGAUDIO: 350 { 351 struct video_audio *va = arg; 352 353 va->flags |= VIDEO_AUDIO_VOLUME | 354 VIDEO_AUDIO_BASS | 355 VIDEO_AUDIO_TREBLE | 356 VIDEO_AUDIO_MUTABLE; 357 if (t->muted) 358 va->flags |= VIDEO_AUDIO_MUTE; 359 va->mode |= VIDEO_SOUND_STEREO; 360 /* Master volume control 361 * V4L volume is min 0, max 65535 362 * TDA7432 Volume: 363 * Min (-79dB) is 0x6f 364 * Max (+20dB) is 0x07 (630) 365 * Max (0dB) is 0x20 (829) 366 * (Mask out bit 7 of vol - it's for the loudness setting) 367 */ 368 if (!maxvol){ /* max +20db */ 369 va->volume = ( 0x6f - (t->volume & 0x7F) ) * 630; 370 } else { /* max 0db */ 371 va->volume = ( 0x6f - (t->volume & 0x7F) ) * 829; 372 } 373 374 /* Balance depends on L,R attenuation 375 * V4L balance is 0 to 65535, middle is 32768 376 * TDA7432 attenuation: min (0dB) is 0, max (-37.5dB) is 0x1f 377 * to scale up to V4L numbers, mult by 1057 378 * attenuation exists for lf, lr, rf, rr 379 * we use only lf and rf (front channels) 380 */ 381 382 if ( (t->lf) < (t->rf) ) 383 /* right is attenuated, balance shifted left */ 384 va->balance = (32768 - 1057*(t->rf)); 385 else 386 /* left is attenuated, balance shifted right */ 387 va->balance = (32768 + 1057*(t->lf)); 388 389 /* Bass/treble 4 bits each */ 390 va->bass=t->bass; 391 if(va->bass >= 0x8) 392 va->bass = ~(va->bass - 0x8) & 0xf; 393 va->bass = (va->bass << 12)+(va->bass << 8)+(va->bass << 4)+(va->bass); 394 va->treble=t->treble; 395 if(va->treble >= 0x8) 396 va->treble = ~(va->treble - 0x8) & 0xf; 397 va->treble = (va->treble << 12)+(va->treble << 8)+(va->treble << 4)+(va->treble); 398 399 break; /* VIDIOCGAUDIO case */ 400 } 401 402 /* Set card - scale from V4L settings to TDA7432 settings */ 403 case VIDIOCSAUDIO: 404 { 405 struct video_audio *va = arg; 406 407 if(va->flags & VIDEO_AUDIO_VOLUME){ 408 if(!maxvol){ /* max +20db */ 409 t->volume = 0x6f - ((va->volume)/630); 410 } else { /* max 0db */ 411 t->volume = 0x6f - ((va->volume)/829); 412 } 413 414 if (loudness) /* Turn on the loudness bit */ 415 t->volume |= TDA7432_LD_ON; 416 417 tda7432_write(client,TDA7432_VL, t->volume); 418 } 419 420 if(va->flags & VIDEO_AUDIO_BASS) 421 { 422 t->bass = va->bass >> 12; 423 if(t->bass>= 0x8) 424 t->bass = (~t->bass & 0xf) + 0x8 ; 425 } 426 if(va->flags & VIDEO_AUDIO_TREBLE) 427 { 428 t->treble= va->treble >> 12; 429 if(t->treble>= 0x8) 430 t->treble = (~t->treble & 0xf) + 0x8 ; 431 } 432 if(va->flags & (VIDEO_AUDIO_TREBLE| VIDEO_AUDIO_BASS)) 433 tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble ); 434 435 if(va->flags & VIDEO_AUDIO_BALANCE) { 436 if (va->balance < 32768) 437 { 438 /* shifted to left, attenuate right */ 439 t->rr = (32768 - va->balance)/1057; 440 t->rf = t->rr; 441 t->lr = TDA7432_ATTEN_0DB; 442 t->lf = TDA7432_ATTEN_0DB; 443 } 444 else if(va->balance > 32769) 445 { 446 /* shifted to right, attenuate left */ 447 t->lf = (va->balance - 32768)/1057; 448 t->lr = t->lf; 449 t->rr = TDA7432_ATTEN_0DB; 450 t->rf = TDA7432_ATTEN_0DB; 451 } 452 else 453 { 454 /* centered */ 455 t->rr = TDA7432_ATTEN_0DB; 456 t->rf = TDA7432_ATTEN_0DB; 457 t->lf = TDA7432_ATTEN_0DB; 458 t->lr = TDA7432_ATTEN_0DB; 459 } 460 } 461 462 t->muted=(va->flags & VIDEO_AUDIO_MUTE); 463 if (t->muted) 464 { 465 /* Mute & update balance*/ 466 tda7432_write(client,TDA7432_LF, t->lf | TDA7432_MUTE); 467 tda7432_write(client,TDA7432_LR, t->lr | TDA7432_MUTE); 468 tda7432_write(client,TDA7432_RF, t->rf | TDA7432_MUTE); 469 tda7432_write(client,TDA7432_RR, t->rr | TDA7432_MUTE); 470 } else { 471 tda7432_write(client,TDA7432_LF, t->lf); 472 tda7432_write(client,TDA7432_LR, t->lr); 473 tda7432_write(client,TDA7432_RF, t->rf); 474 tda7432_write(client,TDA7432_RR, t->rr); 475 } 476 477 break; 478 479 } /* end of VIDEOCSAUDIO case */ 480 481 } /* end of (cmd) switch */ 482 483 return 0; 484} 485 486static struct i2c_driver driver = { 487 .driver = { 488 .name = "tda7432", 489 }, 490 .id = I2C_DRIVERID_TDA7432, 491 .attach_adapter = tda7432_probe, 492 .detach_client = tda7432_detach, 493 .command = tda7432_command, 494}; 495 496static struct i2c_client client_template = 497{ 498 .name = "tda7432", 499 .driver = &driver, 500}; 501 502static int __init tda7432_init(void) 503{ 504 if ( (loudness < 0) || (loudness > 15) ) { 505 printk(KERN_ERR "loudness parameter must be between 0 and 15\n"); 506 return -EINVAL; 507 } 508 509 return i2c_add_driver(&driver); 510} 511 512static void __exit tda7432_fini(void) 513{ 514 i2c_del_driver(&driver); 515} 516 517module_init(tda7432_init); 518module_exit(tda7432_fini); 519 520/* 521 * Local variables: 522 * c-basic-offset: 8 523 * End: 524 */ 525