linux/drivers/media/video/tda9875.c
<<
>>
Prefs
   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 * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
  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 *
  18 *  Revision: 0.1 - original version
  19 */
  20
  21#include <linux/module.h>
  22#include <linux/kernel.h>
  23#include <linux/string.h>
  24#include <linux/timer.h>
  25#include <linux/delay.h>
  26#include <linux/errno.h>
  27#include <linux/slab.h>
  28#include <linux/i2c.h>
  29#include <linux/videodev2.h>
  30#include <media/v4l2-device.h>
  31#include <media/v4l2-i2c-drv.h>
  32#include <media/i2c-addr.h>
  33
  34static int debug; /* insmod parameter */
  35module_param(debug, int, S_IRUGO | S_IWUSR);
  36MODULE_LICENSE("GPL");
  37
  38
  39/* This is a superset of the TDA9875 */
  40struct tda9875 {
  41        struct v4l2_subdev sd;
  42        int rvol, lvol;
  43        int bass, treble;
  44};
  45
  46static inline struct tda9875 *to_state(struct v4l2_subdev *sd)
  47{
  48        return container_of(sd, struct tda9875, sd);
  49}
  50
  51#define dprintk  if (debug) printk
  52
  53/* The TDA9875 is made by Philips Semiconductor
  54 * http://www.semiconductors.philips.com
  55 * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
  56 *
  57 */
  58
  59                /* subaddresses for TDA9875 */
  60#define TDA9875_MUT         0x12  /*General mute  (value --> 0b11001100*/
  61#define TDA9875_CFG         0x01  /* Config register (value --> 0b00000000 */
  62#define TDA9875_DACOS       0x13  /*DAC i/o select (ADC) 0b0000100*/
  63#define TDA9875_LOSR        0x16  /*Line output select regirter 0b0100 0001*/
  64
  65#define TDA9875_CH1V        0x0c  /*Channel 1 volume (mute)*/
  66#define TDA9875_CH2V        0x0d  /*Channel 2 volume (mute)*/
  67#define TDA9875_SC1         0x14  /*SCART 1 in (mono)*/
  68#define TDA9875_SC2         0x15  /*SCART 2 in (mono)*/
  69
  70#define TDA9875_ADCIS       0x17  /*ADC input select (mono) 0b0110 000*/
  71#define TDA9875_AER         0x19  /*Audio effect (AVL+Pseudo) 0b0000 0110*/
  72#define TDA9875_MCS         0x18  /*Main channel select (DAC) 0b0000100*/
  73#define TDA9875_MVL         0x1a  /* Main volume gauche */
  74#define TDA9875_MVR         0x1b  /* Main volume droite */
  75#define TDA9875_MBA         0x1d  /* Main Basse */
  76#define TDA9875_MTR         0x1e  /* Main treble */
  77#define TDA9875_ACS         0x1f  /* Auxilary channel select (FM) 0b0000000*/
  78#define TDA9875_AVL         0x20  /* Auxilary volume gauche */
  79#define TDA9875_AVR         0x21  /* Auxilary volume droite */
  80#define TDA9875_ABA         0x22  /* Auxilary Basse */
  81#define TDA9875_ATR         0x23  /* Auxilary treble */
  82
  83#define TDA9875_MSR         0x02  /* Monitor select register */
  84#define TDA9875_C1MSB       0x03  /* Carrier 1 (FM) frequency register MSB */
  85#define TDA9875_C1MIB       0x04  /* Carrier 1 (FM) frequency register (16-8]b */
  86#define TDA9875_C1LSB       0x05  /* Carrier 1 (FM) frequency register LSB */
  87#define TDA9875_C2MSB       0x06  /* Carrier 2 (nicam) frequency register MSB */
  88#define TDA9875_C2MIB       0x07  /* Carrier 2 (nicam) frequency register (16-8]b */
  89#define TDA9875_C2LSB       0x08  /* Carrier 2 (nicam) frequency register LSB */
  90#define TDA9875_DCR         0x09  /* Demodulateur configuration regirter*/
  91#define TDA9875_DEEM        0x0a  /* FM de-emphasis regirter*/
  92#define TDA9875_FMAT        0x0b  /* FM Matrix regirter*/
  93
  94/* values */
  95#define TDA9875_MUTE_ON     0xff /* general mute */
  96#define TDA9875_MUTE_OFF    0xcc /* general no mute */
  97
  98
  99
 100/* Begin code */
 101
 102static int tda9875_write(struct v4l2_subdev *sd, int subaddr, unsigned char val)
 103{
 104        struct i2c_client *client = v4l2_get_subdevdata(sd);
 105        unsigned char buffer[2];
 106
 107        v4l2_dbg(1, debug, sd, "Writing %d 0x%x\n", subaddr, val);
 108        buffer[0] = subaddr;
 109        buffer[1] = val;
 110        if (2 != i2c_master_send(client, buffer, 2)) {
 111                v4l2_warn(sd, "I/O error, trying (write %d 0x%x)\n",
 112                       subaddr, val);
 113                return -1;
 114        }
 115        return 0;
 116}
 117
 118
 119static int i2c_read_register(struct i2c_client *client, int addr, int reg)
 120{
 121        unsigned char write[1];
 122        unsigned char read[1];
 123        struct i2c_msg msgs[2] = {
 124                { addr, 0,        1, write },
 125                { addr, I2C_M_RD, 1, read  }
 126        };
 127
 128        write[0] = reg;
 129
 130        if (2 != i2c_transfer(client->adapter, msgs, 2)) {
 131                v4l_warn(client, "I/O error (read2)\n");
 132                return -1;
 133        }
 134        v4l_dbg(1, debug, client, "chip_read2: reg%d=0x%x\n", reg, read[0]);
 135        return read[0];
 136}
 137
 138static void tda9875_set(struct v4l2_subdev *sd)
 139{
 140        struct tda9875 *tda = to_state(sd);
 141        unsigned char a;
 142
 143        v4l2_dbg(1, debug, sd, "tda9875_set(%04x,%04x,%04x,%04x)\n",
 144                tda->lvol, tda->rvol, tda->bass, tda->treble);
 145
 146        a = tda->lvol & 0xff;
 147        tda9875_write(sd, TDA9875_MVL, a);
 148        a =tda->rvol & 0xff;
 149        tda9875_write(sd, TDA9875_MVR, a);
 150        a =tda->bass & 0xff;
 151        tda9875_write(sd, TDA9875_MBA, a);
 152        a =tda->treble  & 0xff;
 153        tda9875_write(sd, TDA9875_MTR, a);
 154}
 155
 156static void do_tda9875_init(struct v4l2_subdev *sd)
 157{
 158        struct tda9875 *t = to_state(sd);
 159
 160        v4l2_dbg(1, debug, sd, "In tda9875_init\n");
 161        tda9875_write(sd, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/
 162        tda9875_write(sd, TDA9875_MSR, 0x03);    /* Monitor 0b00000XXX*/
 163        tda9875_write(sd, TDA9875_C1MSB, 0x00);  /*Car1(FM) MSB XMHz*/
 164        tda9875_write(sd, TDA9875_C1MIB, 0x00);  /*Car1(FM) MIB XMHz*/
 165        tda9875_write(sd, TDA9875_C1LSB, 0x00);  /*Car1(FM) LSB XMHz*/
 166        tda9875_write(sd, TDA9875_C2MSB, 0x00);  /*Car2(NICAM) MSB XMHz*/
 167        tda9875_write(sd, TDA9875_C2MIB, 0x00);  /*Car2(NICAM) MIB XMHz*/
 168        tda9875_write(sd, TDA9875_C2LSB, 0x00);  /*Car2(NICAM) LSB XMHz*/
 169        tda9875_write(sd, TDA9875_DCR, 0x00);    /*Demod config 0x00*/
 170        tda9875_write(sd, TDA9875_DEEM, 0x44);   /*DE-Emph 0b0100 0100*/
 171        tda9875_write(sd, TDA9875_FMAT, 0x00);   /*FM Matrix reg 0x00*/
 172        tda9875_write(sd, TDA9875_SC1, 0x00);    /* SCART 1 (SC1)*/
 173        tda9875_write(sd, TDA9875_SC2, 0x01);    /* SCART 2 (sc2)*/
 174
 175        tda9875_write(sd, TDA9875_CH1V, 0x10);  /* Channel volume 1 mute*/
 176        tda9875_write(sd, TDA9875_CH2V, 0x10);  /* Channel volume 2 mute */
 177        tda9875_write(sd, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/
 178        tda9875_write(sd, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/
 179        tda9875_write(sd, TDA9875_LOSR, 0x00);  /* line out (in:mono)*/
 180        tda9875_write(sd, TDA9875_AER, 0x00);   /*06 Effect (AVL+PSEUDO) */
 181        tda9875_write(sd, TDA9875_MCS, 0x44);   /* Main ch select (DAC) */
 182        tda9875_write(sd, TDA9875_MVL, 0x03);   /* Vol Main left 10dB */
 183        tda9875_write(sd, TDA9875_MVR, 0x03);   /* Vol Main right 10dB*/
 184        tda9875_write(sd, TDA9875_MBA, 0x00);   /* Main Bass Main 0dB*/
 185        tda9875_write(sd, TDA9875_MTR, 0x00);   /* Main Treble Main 0dB*/
 186        tda9875_write(sd, TDA9875_ACS, 0x44);   /* Aux chan select (dac)*/
 187        tda9875_write(sd, TDA9875_AVL, 0x00);   /* Vol Aux left 0dB*/
 188        tda9875_write(sd, TDA9875_AVR, 0x00);   /* Vol Aux right 0dB*/
 189        tda9875_write(sd, TDA9875_ABA, 0x00);   /* Aux Bass Main 0dB*/
 190        tda9875_write(sd, TDA9875_ATR, 0x00);   /* Aux Aigus Main 0dB*/
 191
 192        tda9875_write(sd, TDA9875_MUT, 0xcc);   /* General mute  */
 193
 194        t->lvol = t->rvol = 0;          /* 0dB */
 195        t->bass = 0;                    /* 0dB */
 196        t->treble = 0;                  /* 0dB */
 197        tda9875_set(sd);
 198}
 199
 200
 201static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 202{
 203        struct tda9875 *t = to_state(sd);
 204
 205        switch (ctrl->id) {
 206        case V4L2_CID_AUDIO_VOLUME:
 207        {
 208                int left = (t->lvol+84)*606;
 209                int right = (t->rvol+84)*606;
 210
 211                ctrl->value=max(left,right);
 212                return 0;
 213        }
 214        case V4L2_CID_AUDIO_BALANCE:
 215        {
 216                int left = (t->lvol+84)*606;
 217                int right = (t->rvol+84)*606;
 218                int volume = max(left,right);
 219                int balance = (32768*min(left,right))/
 220                              (volume ? volume : 1);
 221                ctrl->value=(left<right)?
 222                        (65535-balance) : balance;
 223                return 0;
 224        }
 225        case V4L2_CID_AUDIO_BASS:
 226                ctrl->value = (t->bass+12)*2427;    /* min -12 max +15 */
 227                return 0;
 228        case V4L2_CID_AUDIO_TREBLE:
 229                ctrl->value = (t->treble+12)*2730;/* min -12 max +12 */
 230                return 0;
 231        }
 232        return -EINVAL;
 233}
 234
 235static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 236{
 237        struct tda9875 *t = to_state(sd);
 238        int chvol = 0, volume = 0, balance = 0, left, right;
 239
 240        switch (ctrl->id) {
 241        case V4L2_CID_AUDIO_VOLUME:
 242                left = (t->lvol+84)*606;
 243                right = (t->rvol+84)*606;
 244
 245                volume = max(left,right);
 246                balance = (32768*min(left,right))/
 247                              (volume ? volume : 1);
 248                balance =(left<right)?
 249                        (65535-balance) : balance;
 250
 251                volume = ctrl->value;
 252
 253                chvol=1;
 254                break;
 255        case V4L2_CID_AUDIO_BALANCE:
 256                left = (t->lvol+84)*606;
 257                right = (t->rvol+84)*606;
 258
 259                volume=max(left,right);
 260
 261                balance = ctrl->value;
 262
 263                chvol=1;
 264                break;
 265        case V4L2_CID_AUDIO_BASS:
 266                t->bass = ((ctrl->value/2400)-12) & 0xff;
 267                if (t->bass > 15)
 268                        t->bass = 15;
 269                if (t->bass < -12)
 270                        t->bass = -12 & 0xff;
 271                break;
 272        case V4L2_CID_AUDIO_TREBLE:
 273                t->treble = ((ctrl->value/2700)-12) & 0xff;
 274                if (t->treble > 12)
 275                        t->treble = 12;
 276                if (t->treble < -12)
 277                        t->treble = -12 & 0xff;
 278                break;
 279        default:
 280                return -EINVAL;
 281        }
 282
 283        if (chvol) {
 284                left = (min(65536 - balance,32768) *
 285                        volume) / 32768;
 286                right = (min(balance,32768) *
 287                                volume) / 32768;
 288                t->lvol = ((left/606)-84) & 0xff;
 289                if (t->lvol > 24)
 290                        t->lvol = 24;
 291                if (t->lvol < -84)
 292                        t->lvol = -84 & 0xff;
 293
 294                t->rvol = ((right/606)-84) & 0xff;
 295                if (t->rvol > 24)
 296                        t->rvol = 24;
 297                if (t->rvol < -84)
 298                        t->rvol = -84 & 0xff;
 299        }
 300
 301        tda9875_set(sd);
 302        return 0;
 303}
 304
 305static int tda9875_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
 306{
 307        switch (qc->id) {
 308        case V4L2_CID_AUDIO_VOLUME:
 309                return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
 310        case V4L2_CID_AUDIO_BASS:
 311        case V4L2_CID_AUDIO_TREBLE:
 312                return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
 313        }
 314        return -EINVAL;
 315}
 316
 317/* ----------------------------------------------------------------------- */
 318
 319static const struct v4l2_subdev_core_ops tda9875_core_ops = {
 320        .queryctrl = tda9875_queryctrl,
 321        .g_ctrl = tda9875_g_ctrl,
 322        .s_ctrl = tda9875_s_ctrl,
 323};
 324
 325static const struct v4l2_subdev_ops tda9875_ops = {
 326        .core = &tda9875_core_ops,
 327};
 328
 329/* ----------------------------------------------------------------------- */
 330
 331
 332/* *********************** *
 333 * i2c interface functions *
 334 * *********************** */
 335
 336static int tda9875_checkit(struct i2c_client *client, int addr)
 337{
 338        int dic, rev;
 339
 340        dic = i2c_read_register(client, addr, 254);
 341        rev = i2c_read_register(client, addr, 255);
 342
 343        if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */
 344                v4l_info(client, "tda9875%s rev. %d detected at 0x%02x\n",
 345                        dic == 0 ? "" : "A", rev, addr << 1);
 346                return 1;
 347        }
 348        v4l_info(client, "no such chip at 0x%02x (dic=0x%x rev=0x%x)\n",
 349                        addr << 1, dic, rev);
 350        return 0;
 351}
 352
 353static int tda9875_probe(struct i2c_client *client,
 354                        const struct i2c_device_id *id)
 355{
 356        struct tda9875 *t;
 357        struct v4l2_subdev *sd;
 358
 359        v4l_info(client, "chip found @ 0x%02x (%s)\n",
 360                        client->addr << 1, client->adapter->name);
 361
 362        if (!tda9875_checkit(client, client->addr))
 363                return -ENODEV;
 364
 365        t = kzalloc(sizeof(*t), GFP_KERNEL);
 366        if (!t)
 367                return -ENOMEM;
 368        sd = &t->sd;
 369        v4l2_i2c_subdev_init(sd, client, &tda9875_ops);
 370
 371        do_tda9875_init(sd);
 372        return 0;
 373}
 374
 375static int tda9875_remove(struct i2c_client *client)
 376{
 377        struct v4l2_subdev *sd = i2c_get_clientdata(client);
 378
 379        do_tda9875_init(sd);
 380        v4l2_device_unregister_subdev(sd);
 381        kfree(to_state(sd));
 382        return 0;
 383}
 384
 385static const struct i2c_device_id tda9875_id[] = {
 386        { "tda9875", 0 },
 387        { }
 388};
 389MODULE_DEVICE_TABLE(i2c, tda9875_id);
 390
 391static struct v4l2_i2c_driver_data v4l2_i2c_data = {
 392        .name = "tda9875",
 393        .probe = tda9875_probe,
 394        .remove = tda9875_remove,
 395        .id_table = tda9875_id,
 396};
 397