1/* 2 * For the TDA9875 chip 3 * (The TDA9875 is used on the Diamond DTV2000 french version 4 * Other cards probably use these chips as well.) 5 * This driver will not complain if used with any 6 * other i2c device with the same address. 7 * 8 * Copyright (c) 2000 Guillaume Delvit based on Gerd Knorr source and 9 * Eric Sandeen 10 * This code is placed under the terms of the GNU General Public License 11 * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) 12 * Which was based on tda8425.c by Greg Alexander (c) 1998 13 * 14 * OPTIONS: 15 * debug - set to 1 if you'd like to see debug messages 16 * 17 * Revision: 0.1 - original version 18 */ 19 20#include <linux/module.h> 21#include <linux/kernel.h> 22#include <linux/string.h> 23#include <linux/timer.h> 24#include <linux/delay.h> 25#include <linux/errno.h> 26#include <linux/slab.h> 27#include <linux/videodev.h> 28#include <media/v4l2-common.h> 29#include <linux/i2c.h> 30#include <linux/init.h> 31 32 33#include <media/i2c-addr.h> 34 35static int debug; /* insmod parameter */ 36module_param(debug, int, S_IRUGO | S_IWUSR); 37MODULE_LICENSE("GPL"); 38 39/* Addresses to scan */ 40static unsigned short normal_i2c[] = { 41 I2C_ADDR_TDA9875 >> 1, 42 I2C_CLIENT_END 43}; 44I2C_CLIENT_INSMOD; 45 46/* This is a superset of the TDA9875 */ 47struct tda9875 { 48 int rvol, lvol; 49 int bass, treble; 50 struct i2c_client c; 51}; 52 53static struct i2c_driver driver; 54static struct i2c_client client_template; 55 56#define dprintk if (debug) printk 57 58/* The TDA9875 is made by Philips Semiconductor 59 * http://www.semiconductors.philips.com 60 * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator 61 * 62 */ 63 64 /* subaddresses for TDA9875 */ 65#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/ 66#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */ 67#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/ 68#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/ 69 70#define TDA9875_CH1V 0x0c /*Channel 1 volume (mute)*/ 71#define TDA9875_CH2V 0x0d /*Channel 2 volume (mute)*/ 72#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/ 73#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/ 74 75#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/ 76#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/ 77#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/ 78#define TDA9875_MVL 0x1a /* Main volume gauche */ 79#define TDA9875_MVR 0x1b /* Main volume droite */ 80#define TDA9875_MBA 0x1d /* Main Basse */ 81#define TDA9875_MTR 0x1e /* Main treble */ 82#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/ 83#define TDA9875_AVL 0x20 /* Auxilary volume gauche */ 84#define TDA9875_AVR 0x21 /* Auxilary volume droite */ 85#define TDA9875_ABA 0x22 /* Auxilary Basse */ 86#define TDA9875_ATR 0x23 /* Auxilary treble */ 87 88#define TDA9875_MSR 0x02 /* Monitor select register */ 89#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */ 90#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */ 91#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */ 92#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */ 93#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */ 94#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */ 95#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/ 96#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/ 97#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/ 98 99/* values */ 100#define TDA9875_MUTE_ON 0xff /* general mute */ 101#define TDA9875_MUTE_OFF 0xcc /* general no mute */ 102 103 104 105/* Begin code */ 106 107static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char val) 108{ 109 unsigned char buffer[2]; 110 dprintk("In tda9875_write\n"); 111 dprintk("Writing %d 0x%x\n", subaddr, val); 112 buffer[0] = subaddr; 113 buffer[1] = val; 114 if (2 != i2c_master_send(client,buffer,2)) { 115 printk(KERN_WARNING "tda9875: I/O error, trying (write %d 0x%x)\n", 116 subaddr, val); 117 return -1; 118 } 119 return 0; 120} 121 122 123static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg) 124{ 125 unsigned char write[1]; 126 unsigned char read[1]; 127 struct i2c_msg msgs[2] = { 128 { addr, 0, 1, write }, 129 { addr, I2C_M_RD, 1, read } 130 }; 131 write[0] = reg; 132 133 if (2 != i2c_transfer(adap,msgs,2)) { 134 printk(KERN_WARNING "tda9875: I/O error (read2)\n"); 135 return -1; 136 } 137 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]); 138 return read[0]; 139} 140 141static void tda9875_set(struct i2c_client *client) 142{ 143 struct tda9875 *tda = i2c_get_clientdata(client); 144 unsigned char a; 145 146 dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n", 147 tda->lvol,tda->rvol,tda->bass,tda->treble); 148 149 150 a = tda->lvol & 0xff; 151 tda9875_write(client, TDA9875_MVL, a); 152 a =tda->rvol & 0xff; 153 tda9875_write(client, TDA9875_MVR, a); 154 a =tda->bass & 0xff; 155 tda9875_write(client, TDA9875_MBA, a); 156 a =tda->treble & 0xff; 157 tda9875_write(client, TDA9875_MTR, a); 158} 159 160static void do_tda9875_init(struct i2c_client *client) 161{ 162 struct tda9875 *t = i2c_get_clientdata(client); 163 dprintk("In tda9875_init\n"); 164 tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/ 165 tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/ 166 tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/ 167 tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/ 168 tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/ 169 tda9875_write(client, TDA9875_C2MSB, 0x00 ); /*Car2(NICAM) MSB XMHz*/ 170 tda9875_write(client, TDA9875_C2MIB, 0x00 ); /*Car2(NICAM) MIB XMHz*/ 171 tda9875_write(client, TDA9875_C2LSB, 0x00 ); /*Car2(NICAM) LSB XMHz*/ 172 tda9875_write(client, TDA9875_DCR, 0x00 ); /*Demod config 0x00*/ 173 tda9875_write(client, TDA9875_DEEM, 0x44 ); /*DE-Emph 0b0100 0100*/ 174 tda9875_write(client, TDA9875_FMAT, 0x00 ); /*FM Matrix reg 0x00*/ 175 tda9875_write(client, TDA9875_SC1, 0x00 ); /* SCART 1 (SC1)*/ 176 tda9875_write(client, TDA9875_SC2, 0x01 ); /* SCART 2 (sc2)*/ 177 178 tda9875_write(client, TDA9875_CH1V, 0x10 ); /* Channel volume 1 mute*/ 179 tda9875_write(client, TDA9875_CH2V, 0x10 ); /* Channel volume 2 mute */ 180 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/ 181 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/ 182 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/ 183 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */ 184 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */ 185 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */ 186 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/ 187 tda9875_write(client, TDA9875_MBA, 0x00 ); /* Main Bass Main 0dB*/ 188 tda9875_write(client, TDA9875_MTR, 0x00 ); /* Main Treble Main 0dB*/ 189 tda9875_write(client, TDA9875_ACS, 0x44 ); /* Aux chan select (dac)*/ 190 tda9875_write(client, TDA9875_AVL, 0x00 ); /* Vol Aux left 0dB*/ 191 tda9875_write(client, TDA9875_AVR, 0x00 ); /* Vol Aux right 0dB*/ 192 tda9875_write(client, TDA9875_ABA, 0x00 ); /* Aux Bass Main 0dB*/ 193 tda9875_write(client, TDA9875_ATR, 0x00 ); /* Aux Aigus Main 0dB*/ 194 195 tda9875_write(client, TDA9875_MUT, 0xcc ); /* General mute */ 196 197 t->lvol=t->rvol =0; /* 0dB */ 198 t->bass=0; /* 0dB */ 199 t->treble=0; /* 0dB */ 200 tda9875_set(client); 201 202} 203 204 205/* *********************** * 206 * i2c interface functions * 207 * *********************** */ 208 209static int tda9875_checkit(struct i2c_adapter *adap, int addr) 210{ 211 int dic,rev; 212 213 dic=i2c_read_register(adap,addr,254); 214 rev=i2c_read_register(adap,addr,255); 215 216 if(dic==0 || dic==2) { // tda9875 and tda9875A 217 printk("tda9875: TDA9875%s Rev.%d detected at 0x%x\n", 218 dic==0?"":"A", rev,addr<<1); 219 return 1; 220 } 221 printk("tda9875: no such chip at 0x%x (dic=0x%x rev=0x%x)\n",addr<<1,dic,rev); 222 return(0); 223} 224 225static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind) 226{ 227 struct tda9875 *t; 228 struct i2c_client *client; 229 dprintk("In tda9875_attach\n"); 230 231 t = kzalloc(sizeof *t,GFP_KERNEL); 232 if (!t) 233 return -ENOMEM; 234 235 client = &t->c; 236 memcpy(client,&client_template,sizeof(struct i2c_client)); 237 client->adapter = adap; 238 client->addr = addr; 239 i2c_set_clientdata(client, t); 240 241 if(!tda9875_checkit(adap,addr)) { 242 kfree(t); 243 return 1; 244 } 245 246 do_tda9875_init(client); 247 printk(KERN_INFO "tda9875: init\n"); 248 249 i2c_attach_client(client); 250 return 0; 251} 252 253static int tda9875_probe(struct i2c_adapter *adap) 254{ 255 if (adap->class & I2C_CLASS_TV_ANALOG) 256 return i2c_probe(adap, &addr_data, tda9875_attach); 257 return 0; 258} 259 260static int tda9875_detach(struct i2c_client *client) 261{ 262 struct tda9875 *t = i2c_get_clientdata(client); 263 264 do_tda9875_init(client); 265 i2c_detach_client(client); 266 267 kfree(t); 268 return 0; 269} 270 271static int tda9875_command(struct i2c_client *client, 272 unsigned int cmd, void *arg) 273{ 274 struct tda9875 *t = i2c_get_clientdata(client); 275 276 dprintk("In tda9875_command...\n"); 277 278 switch (cmd) { 279 /* --- v4l ioctls --- */ 280 /* take care: bttv does userspace copying, we'll get a 281 kernel pointer here... */ 282 case VIDIOCGAUDIO: 283 { 284 struct video_audio *va = arg; 285 int left,right; 286 287 dprintk("VIDIOCGAUDIO\n"); 288 289 va->flags |= VIDEO_AUDIO_VOLUME | 290 VIDEO_AUDIO_BASS | 291 VIDEO_AUDIO_TREBLE; 292 293 /* min is -84 max is 24 */ 294 left = (t->lvol+84)*606; 295 right = (t->rvol+84)*606; 296 va->volume=max(left,right); 297 va->balance=(32768*min(left,right))/ 298 (va->volume ? va->volume : 1); 299 va->balance=(left<right)? 300 (65535-va->balance) : va->balance; 301 va->bass = (t->bass+12)*2427; /* min -12 max +15 */ 302 va->treble = (t->treble+12)*2730;/* min -12 max +12 */ 303 va->mode |= VIDEO_SOUND_MONO; 304 305 break; /* VIDIOCGAUDIO case */ 306 } 307 308 case VIDIOCSAUDIO: 309 { 310 struct video_audio *va = arg; 311 int left,right; 312 313 dprintk("VIDEOCSAUDIO...\n"); 314 left = (min(65536 - va->balance,32768) * 315 va->volume) / 32768; 316 right = (min(va->balance,(__u16)32768) * 317 va->volume) / 32768; 318 t->lvol = ((left/606)-84) & 0xff; 319 if (t->lvol > 24) 320 t->lvol = 24; 321 if (t->lvol < -84) 322 t->lvol = -84 & 0xff; 323 324 t->rvol = ((right/606)-84) & 0xff; 325 if (t->rvol > 24) 326 t->rvol = 24; 327 if (t->rvol < -84) 328 t->rvol = -84 & 0xff; 329 330 t->bass = ((va->bass/2400)-12) & 0xff; 331 if (t->bass > 15) 332 t->bass = 15; 333 if (t->bass < -12) 334 t->bass = -12 & 0xff; 335 336 t->treble = ((va->treble/2700)-12) & 0xff; 337 if (t->treble > 12) 338 t->treble = 12; 339 if (t->treble < -12) 340 t->treble = -12 & 0xff; 341 342 343 344//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble); 345 346 347 tda9875_set(client); 348 349 break; 350 351 } /* end of VIDEOCSAUDIO case */ 352 353 default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */ 354 355 /* nothing */ 356 dprintk("Default\n"); 357 358 } /* end of (cmd) switch */ 359 360 return 0; 361} 362 363 364static struct i2c_driver driver = { 365 .driver = { 366 .name = "tda9875", 367 }, 368 .id = I2C_DRIVERID_TDA9875, 369 .attach_adapter = tda9875_probe, 370 .detach_client = tda9875_detach, 371 .command = tda9875_command, 372}; 373 374static struct i2c_client client_template = 375{ 376 .name = "tda9875", 377 .driver = &driver, 378}; 379 380static int __init tda9875_init(void) 381{ 382 return i2c_add_driver(&driver); 383} 384 385static void __exit tda9875_fini(void) 386{ 387 i2c_del_driver(&driver); 388} 389 390module_init(tda9875_init); 391module_exit(tda9875_fini); 392 393/* 394 * Local variables: 395 * c-basic-offset: 8 396 * End: 397 */ 398