root/drivers/media/i2c/tda7432.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_state
  2. to_sd
  3. tda7432_write
  4. tda7432_set
  5. tda7432_log_status
  6. tda7432_s_ctrl
  7. tda7432_probe
  8. tda7432_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * For the STS-Thompson TDA7432 audio processor chip
   4  *
   5  * Handles audio functions: volume, balance, tone, loudness
   6  * This driver will not complain if used with any
   7  * other i2c device with the same address.
   8  *
   9  * Muting and tone control by Jonathan Isom <jisom@ematic.com>
  10  *
  11  * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com>
  12  * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org>
  13  *
  14  * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
  15  * Which was based on tda8425.c by Greg Alexander (c) 1998
  16  *
  17  * OPTIONS:
  18  * debug    - set to 1 if you'd like to see debug messages
  19  *            set to 2 if you'd like to be inundated with debug messages
  20  *
  21  * loudness - set between 0 and 15 for varying degrees of loudness effect
  22  *
  23  * maxvol   - set maximum volume to +20db (1), default is 0db(0)
  24  */
  25 
  26 #include <linux/module.h>
  27 #include <linux/init.h>
  28 #include <linux/kernel.h>
  29 #include <linux/string.h>
  30 #include <linux/timer.h>
  31 #include <linux/delay.h>
  32 #include <linux/errno.h>
  33 #include <linux/slab.h>
  34 #include <linux/videodev2.h>
  35 #include <linux/i2c.h>
  36 
  37 #include <media/v4l2-device.h>
  38 #include <media/v4l2-ioctl.h>
  39 #include <media/v4l2-ctrls.h>
  40 
  41 #ifndef VIDEO_AUDIO_BALANCE
  42 # define VIDEO_AUDIO_BALANCE 32
  43 #endif
  44 
  45 MODULE_AUTHOR("Eric Sandeen <eric_sandeen@bigfoot.com>");
  46 MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip");
  47 MODULE_LICENSE("GPL");
  48 
  49 static int maxvol;
  50 static int loudness; /* disable loudness by default */
  51 static int debug;        /* insmod parameter */
  52 module_param(debug, int, S_IRUGO | S_IWUSR);
  53 MODULE_PARM_DESC(debug, "Set debugging level from 0 to 3. Default is off(0).");
  54 module_param(loudness, int, S_IRUGO);
  55 MODULE_PARM_DESC(loudness, "Turn loudness on(1) else off(0). Default is off(0).");
  56 module_param(maxvol, int, S_IRUGO | S_IWUSR);
  57 MODULE_PARM_DESC(maxvol, "Set maximum volume to +20dB(0) else +0dB(1). Default is +20dB(0).");
  58 
  59 
  60 /* Structure of address and subaddresses for the tda7432 */
  61 
  62 struct tda7432 {
  63         struct v4l2_subdev sd;
  64         struct v4l2_ctrl_handler hdl;
  65         struct {
  66                 /* bass/treble cluster */
  67                 struct v4l2_ctrl *bass;
  68                 struct v4l2_ctrl *treble;
  69         };
  70         struct {
  71                 /* mute/balance cluster */
  72                 struct v4l2_ctrl *mute;
  73                 struct v4l2_ctrl *balance;
  74         };
  75 };
  76 
  77 static inline struct tda7432 *to_state(struct v4l2_subdev *sd)
  78 {
  79         return container_of(sd, struct tda7432, sd);
  80 }
  81 
  82 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
  83 {
  84         return &container_of(ctrl->handler, struct tda7432, hdl)->sd;
  85 }
  86 
  87 /* The TDA7432 is made by STS-Thompson
  88  * http://www.st.com
  89  * http://us.st.com/stonline/books/pdf/docs/4056.pdf
  90  *
  91  * TDA7432: I2C-bus controlled basic audio processor
  92  *
  93  * The TDA7432 controls basic audio functions like volume, balance,
  94  * and tone control (including loudness).  It also has four channel
  95  * output (for front and rear).  Since most vidcap cards probably
  96  * don't have 4 channel output, this driver will set front & rear
  97  * together (no independent control).
  98  */
  99 
 100                 /* Subaddresses for TDA7432 */
 101 
 102 #define TDA7432_IN      0x00 /* Input select                 */
 103 #define TDA7432_VL      0x01 /* Volume                       */
 104 #define TDA7432_TN      0x02 /* Bass, Treble (Tone)          */
 105 #define TDA7432_LF      0x03 /* Attenuation LF (Left Front)  */
 106 #define TDA7432_LR      0x04 /* Attenuation LR (Left Rear)   */
 107 #define TDA7432_RF      0x05 /* Attenuation RF (Right Front) */
 108 #define TDA7432_RR      0x06 /* Attenuation RR (Right Rear)  */
 109 #define TDA7432_LD      0x07 /* Loudness                     */
 110 
 111 
 112                 /* Masks for bits in TDA7432 subaddresses */
 113 
 114 /* Many of these not used - just for documentation */
 115 
 116 /* Subaddress 0x00 - Input selection and bass control */
 117 
 118 /* Bits 0,1,2 control input:
 119  * 0x00 - Stereo input
 120  * 0x02 - Mono input
 121  * 0x03 - Mute  (Using Attenuators Plays better with modules)
 122  * Mono probably isn't used - I'm guessing only the stereo
 123  * input is connected on most cards, so we'll set it to stereo.
 124  *
 125  * Bit 3 controls bass cut: 0/1 is non-symmetric/symmetric bass cut
 126  * Bit 4 controls bass range: 0/1 is extended/standard bass range
 127  *
 128  * Highest 3 bits not used
 129  */
 130 
 131 #define TDA7432_STEREO_IN       0
 132 #define TDA7432_MONO_IN         2       /* Probably won't be used */
 133 #define TDA7432_BASS_SYM        1 << 3
 134 #define TDA7432_BASS_NORM       1 << 4
 135 
 136 /* Subaddress 0x01 - Volume */
 137 
 138 /* Lower 7 bits control volume from -79dB to +32dB in 1dB steps
 139  * Recommended maximum is +20 dB
 140  *
 141  * +32dB: 0x00
 142  * +20dB: 0x0c
 143  *   0dB: 0x20
 144  * -79dB: 0x6f
 145  *
 146  * MSB (bit 7) controls loudness: 1/0 is loudness on/off
 147  */
 148 
 149 #define TDA7432_VOL_0DB         0x20
 150 #define TDA7432_LD_ON           1 << 7
 151 
 152 
 153 /* Subaddress 0x02 - Tone control */
 154 
 155 /* Bits 0,1,2 control absolute treble gain from 0dB to 14dB
 156  * 0x0 is 14dB, 0x7 is 0dB
 157  *
 158  * Bit 3 controls treble attenuation/gain (sign)
 159  * 1 = gain (+)
 160  * 0 = attenuation (-)
 161  *
 162  * Bits 4,5,6 control absolute bass gain from 0dB to 14dB
 163  * (This is only true for normal base range, set in 0x00)
 164  * 0x0 << 4 is 14dB, 0x7 is 0dB
 165  *
 166  * Bit 7 controls bass attenuation/gain (sign)
 167  * 1 << 7 = gain (+)
 168  * 0 << 7 = attenuation (-)
 169  *
 170  * Example:
 171  * 1 1 0 1 0 1 0 1 is +4dB bass, -4dB treble
 172  */
 173 
 174 #define TDA7432_TREBLE_0DB              0xf
 175 #define TDA7432_TREBLE                  7
 176 #define TDA7432_TREBLE_GAIN             1 << 3
 177 #define TDA7432_BASS_0DB                0xf
 178 #define TDA7432_BASS                    7 << 4
 179 #define TDA7432_BASS_GAIN               1 << 7
 180 
 181 
 182 /* Subaddress 0x03 - Left  Front attenuation */
 183 /* Subaddress 0x04 - Left  Rear  attenuation */
 184 /* Subaddress 0x05 - Right Front attenuation */
 185 /* Subaddress 0x06 - Right Rear  attenuation */
 186 
 187 /* Bits 0,1,2,3,4 control attenuation from 0dB to -37.5dB
 188  * in 1.5dB steps.
 189  *
 190  * 0x00 is     0dB
 191  * 0x1f is -37.5dB
 192  *
 193  * Bit 5 mutes that channel when set (1 = mute, 0 = unmute)
 194  * We'll use the mute on the input, though (above)
 195  * Bits 6,7 unused
 196  */
 197 
 198 #define TDA7432_ATTEN_0DB       0x00
 199 #define TDA7432_MUTE        0x1 << 5
 200 
 201 
 202 /* Subaddress 0x07 - Loudness Control */
 203 
 204 /* Bits 0,1,2,3 control loudness from 0dB to -15dB in 1dB steps
 205  * when bit 4 is NOT set
 206  *
 207  * 0x0 is   0dB
 208  * 0xf is -15dB
 209  *
 210  * If bit 4 is set, then there is a flat attenuation according to
 211  * the lower 4 bits, as above.
 212  *
 213  * Bits 5,6,7 unused
 214  */
 215 
 216 
 217 
 218 /* Begin code */
 219 
 220 static int tda7432_write(struct v4l2_subdev *sd, int subaddr, int val)
 221 {
 222         struct i2c_client *client = v4l2_get_subdevdata(sd);
 223         unsigned char buffer[2];
 224 
 225         v4l2_dbg(2, debug, sd, "In tda7432_write\n");
 226         v4l2_dbg(1, debug, sd, "Writing %d 0x%x\n", subaddr, val);
 227         buffer[0] = subaddr;
 228         buffer[1] = val;
 229         if (2 != i2c_master_send(client, buffer, 2)) {
 230                 v4l2_err(sd, "I/O error, trying (write %d 0x%x)\n",
 231                        subaddr, val);
 232                 return -1;
 233         }
 234         return 0;
 235 }
 236 
 237 static int tda7432_set(struct v4l2_subdev *sd)
 238 {
 239         struct i2c_client *client = v4l2_get_subdevdata(sd);
 240         unsigned char buf[16];
 241 
 242         buf[0]  = TDA7432_IN;
 243         buf[1]  = TDA7432_STEREO_IN |  /* Main (stereo) input   */
 244                   TDA7432_BASS_SYM  |  /* Symmetric bass cut    */
 245                   TDA7432_BASS_NORM;   /* Normal bass range     */
 246         buf[2]  = 0x3b;
 247         if (loudness)                    /* Turn loudness on?     */
 248                 buf[2] |= TDA7432_LD_ON;
 249         buf[3]  = TDA7432_TREBLE_0DB | (TDA7432_BASS_0DB << 4);
 250         buf[4]  = TDA7432_ATTEN_0DB;
 251         buf[5]  = TDA7432_ATTEN_0DB;
 252         buf[6]  = TDA7432_ATTEN_0DB;
 253         buf[7]  = TDA7432_ATTEN_0DB;
 254         buf[8]  = loudness;
 255         if (9 != i2c_master_send(client, buf, 9)) {
 256                 v4l2_err(sd, "I/O error, trying tda7432_set\n");
 257                 return -1;
 258         }
 259 
 260         return 0;
 261 }
 262 
 263 static int tda7432_log_status(struct v4l2_subdev *sd)
 264 {
 265         struct tda7432 *state = to_state(sd);
 266 
 267         v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
 268         return 0;
 269 }
 270 
 271 static int tda7432_s_ctrl(struct v4l2_ctrl *ctrl)
 272 {
 273         struct v4l2_subdev *sd = to_sd(ctrl);
 274         struct tda7432 *t = to_state(sd);
 275         u8 bass, treble, volume;
 276         u8 lf, lr, rf, rr;
 277 
 278         switch (ctrl->id) {
 279         case V4L2_CID_AUDIO_MUTE:
 280                 if (t->balance->val < 0) {
 281                         /* shifted to left, attenuate right */
 282                         rr = rf = -t->balance->val;
 283                         lr = lf = TDA7432_ATTEN_0DB;
 284                 } else if (t->balance->val > 0) {
 285                         /* shifted to right, attenuate left */
 286                         rr = rf = TDA7432_ATTEN_0DB;
 287                         lr = lf = t->balance->val;
 288                 } else {
 289                         /* centered */
 290                         rr = rf = TDA7432_ATTEN_0DB;
 291                         lr = lf = TDA7432_ATTEN_0DB;
 292                 }
 293                 if (t->mute->val) {
 294                         lf |= TDA7432_MUTE;
 295                         lr |= TDA7432_MUTE;
 296                         rf |= TDA7432_MUTE;
 297                         rr |= TDA7432_MUTE;
 298                 }
 299                 /* Mute & update balance*/
 300                 tda7432_write(sd, TDA7432_LF, lf);
 301                 tda7432_write(sd, TDA7432_LR, lr);
 302                 tda7432_write(sd, TDA7432_RF, rf);
 303                 tda7432_write(sd, TDA7432_RR, rr);
 304                 return 0;
 305         case V4L2_CID_AUDIO_VOLUME:
 306                 volume = 0x6f - ctrl->val;
 307                 if (loudness)           /* Turn on the loudness bit */
 308                         volume |= TDA7432_LD_ON;
 309 
 310                 tda7432_write(sd, TDA7432_VL, volume);
 311                 return 0;
 312         case V4L2_CID_AUDIO_BASS:
 313                 bass = t->bass->val;
 314                 treble = t->treble->val;
 315                 if (bass >= 0x8)
 316                         bass = 14 - (bass - 8);
 317                 if (treble >= 0x8)
 318                         treble = 14 - (treble - 8);
 319 
 320                 tda7432_write(sd, TDA7432_TN, 0x10 | (bass << 4) | treble);
 321                 return 0;
 322         }
 323         return -EINVAL;
 324 }
 325 
 326 /* ----------------------------------------------------------------------- */
 327 
 328 static const struct v4l2_ctrl_ops tda7432_ctrl_ops = {
 329         .s_ctrl = tda7432_s_ctrl,
 330 };
 331 
 332 static const struct v4l2_subdev_core_ops tda7432_core_ops = {
 333         .log_status = tda7432_log_status,
 334 };
 335 
 336 static const struct v4l2_subdev_ops tda7432_ops = {
 337         .core = &tda7432_core_ops,
 338 };
 339 
 340 /* ----------------------------------------------------------------------- */
 341 
 342 /* *********************** *
 343  * i2c interface functions *
 344  * *********************** */
 345 
 346 static int tda7432_probe(struct i2c_client *client,
 347                         const struct i2c_device_id *id)
 348 {
 349         struct tda7432 *t;
 350         struct v4l2_subdev *sd;
 351 
 352         v4l_info(client, "chip found @ 0x%02x (%s)\n",
 353                         client->addr << 1, client->adapter->name);
 354 
 355         t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
 356         if (!t)
 357                 return -ENOMEM;
 358         sd = &t->sd;
 359         v4l2_i2c_subdev_init(sd, client, &tda7432_ops);
 360         v4l2_ctrl_handler_init(&t->hdl, 5);
 361         v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops,
 362                 V4L2_CID_AUDIO_VOLUME, 0, maxvol ? 0x68 : 0x4f, 1, maxvol ? 0x5d : 0x47);
 363         t->mute = v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops,
 364                 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
 365         t->balance = v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops,
 366                 V4L2_CID_AUDIO_BALANCE, -31, 31, 1, 0);
 367         t->bass = v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops,
 368                 V4L2_CID_AUDIO_BASS, 0, 14, 1, 7);
 369         t->treble = v4l2_ctrl_new_std(&t->hdl, &tda7432_ctrl_ops,
 370                 V4L2_CID_AUDIO_TREBLE, 0, 14, 1, 7);
 371         sd->ctrl_handler = &t->hdl;
 372         if (t->hdl.error) {
 373                 int err = t->hdl.error;
 374 
 375                 v4l2_ctrl_handler_free(&t->hdl);
 376                 return err;
 377         }
 378         v4l2_ctrl_cluster(2, &t->bass);
 379         v4l2_ctrl_cluster(2, &t->mute);
 380         v4l2_ctrl_handler_setup(&t->hdl);
 381         if (loudness < 0 || loudness > 15) {
 382                 v4l2_warn(sd, "loudness parameter must be between 0 and 15\n");
 383                 if (loudness < 0)
 384                         loudness = 0;
 385                 if (loudness > 15)
 386                         loudness = 15;
 387         }
 388 
 389         tda7432_set(sd);
 390         return 0;
 391 }
 392 
 393 static int tda7432_remove(struct i2c_client *client)
 394 {
 395         struct v4l2_subdev *sd = i2c_get_clientdata(client);
 396         struct tda7432 *t = to_state(sd);
 397 
 398         tda7432_set(sd);
 399         v4l2_device_unregister_subdev(sd);
 400         v4l2_ctrl_handler_free(&t->hdl);
 401         return 0;
 402 }
 403 
 404 static const struct i2c_device_id tda7432_id[] = {
 405         { "tda7432", 0 },
 406         { }
 407 };
 408 MODULE_DEVICE_TABLE(i2c, tda7432_id);
 409 
 410 static struct i2c_driver tda7432_driver = {
 411         .driver = {
 412                 .name   = "tda7432",
 413         },
 414         .probe          = tda7432_probe,
 415         .remove         = tda7432_remove,
 416         .id_table       = tda7432_id,
 417 };
 418 
 419 module_i2c_driver(tda7432_driver);

/* [<][>][^][v][top][bottom][index][help] */