root/drivers/media/i2c/bt819.c

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

DEFINITIONS

This source file includes following definitions.
  1. to_bt819
  2. to_sd
  3. bt819_write
  4. bt819_setbit
  5. bt819_write_block
  6. bt819_read
  7. bt819_init
  8. bt819_status
  9. bt819_querystd
  10. bt819_g_input_status
  11. bt819_s_std
  12. bt819_s_routing
  13. bt819_s_stream
  14. bt819_s_ctrl
  15. bt819_probe
  16. bt819_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  bt819 - BT819A VideoStream Decoder (Rockwell Part)
   4  *
   5  * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
   6  * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
   7  *
   8  * Modifications for LML33/DC10plus unified driver
   9  * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
  10  *
  11  * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
  12  *    - moved over to linux>=2.4.x i2c protocol (9/9/2002)
  13  *
  14  * This code was modify/ported from the saa7111 driver written
  15  * by Dave Perks.
  16  */
  17 
  18 #include <linux/module.h>
  19 #include <linux/types.h>
  20 #include <linux/ioctl.h>
  21 #include <linux/delay.h>
  22 #include <linux/i2c.h>
  23 #include <linux/videodev2.h>
  24 #include <linux/slab.h>
  25 #include <media/v4l2-device.h>
  26 #include <media/v4l2-ctrls.h>
  27 #include <media/i2c/bt819.h>
  28 
  29 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
  30 MODULE_AUTHOR("Mike Bernson & Dave Perks");
  31 MODULE_LICENSE("GPL");
  32 
  33 static int debug;
  34 module_param(debug, int, 0);
  35 MODULE_PARM_DESC(debug, "Debug level (0-1)");
  36 
  37 
  38 /* ----------------------------------------------------------------------- */
  39 
  40 struct bt819 {
  41         struct v4l2_subdev sd;
  42         struct v4l2_ctrl_handler hdl;
  43         unsigned char reg[32];
  44 
  45         v4l2_std_id norm;
  46         int input;
  47         int enable;
  48 };
  49 
  50 static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
  51 {
  52         return container_of(sd, struct bt819, sd);
  53 }
  54 
  55 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
  56 {
  57         return &container_of(ctrl->handler, struct bt819, hdl)->sd;
  58 }
  59 
  60 struct timing {
  61         int hactive;
  62         int hdelay;
  63         int vactive;
  64         int vdelay;
  65         int hscale;
  66         int vscale;
  67 };
  68 
  69 /* for values, see the bt819 datasheet */
  70 static struct timing timing_data[] = {
  71         {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
  72         {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
  73 };
  74 
  75 /* ----------------------------------------------------------------------- */
  76 
  77 static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
  78 {
  79         struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
  80 
  81         decoder->reg[reg] = value;
  82         return i2c_smbus_write_byte_data(client, reg, value);
  83 }
  84 
  85 static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
  86 {
  87         return bt819_write(decoder, reg,
  88                 (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
  89 }
  90 
  91 static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
  92 {
  93         struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
  94         int ret = -1;
  95         u8 reg;
  96 
  97         /* the bt819 has an autoincrement function, use it if
  98          * the adapter understands raw I2C */
  99         if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 100                 /* do raw I2C, not smbus compatible */
 101                 u8 block_data[32];
 102                 int block_len;
 103 
 104                 while (len >= 2) {
 105                         block_len = 0;
 106                         block_data[block_len++] = reg = data[0];
 107                         do {
 108                                 block_data[block_len++] =
 109                                     decoder->reg[reg++] = data[1];
 110                                 len -= 2;
 111                                 data += 2;
 112                         } while (len >= 2 && data[0] == reg && block_len < 32);
 113                         ret = i2c_master_send(client, block_data, block_len);
 114                         if (ret < 0)
 115                                 break;
 116                 }
 117         } else {
 118                 /* do some slow I2C emulation kind of thing */
 119                 while (len >= 2) {
 120                         reg = *data++;
 121                         ret = bt819_write(decoder, reg, *data++);
 122                         if (ret < 0)
 123                                 break;
 124                         len -= 2;
 125                 }
 126         }
 127 
 128         return ret;
 129 }
 130 
 131 static inline int bt819_read(struct bt819 *decoder, u8 reg)
 132 {
 133         struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
 134 
 135         return i2c_smbus_read_byte_data(client, reg);
 136 }
 137 
 138 static int bt819_init(struct v4l2_subdev *sd)
 139 {
 140         static unsigned char init[] = {
 141                 /*0x1f, 0x00,*/     /* Reset */
 142                 0x01, 0x59,     /* 0x01 input format */
 143                 0x02, 0x00,     /* 0x02 temporal decimation */
 144                 0x03, 0x12,     /* 0x03 Cropping msb */
 145                 0x04, 0x16,     /* 0x04 Vertical Delay, lsb */
 146                 0x05, 0xe0,     /* 0x05 Vertical Active lsb */
 147                 0x06, 0x80,     /* 0x06 Horizontal Delay lsb */
 148                 0x07, 0xd0,     /* 0x07 Horizontal Active lsb */
 149                 0x08, 0x00,     /* 0x08 Horizontal Scaling msb */
 150                 0x09, 0xf8,     /* 0x09 Horizontal Scaling lsb */
 151                 0x0a, 0x00,     /* 0x0a Brightness control */
 152                 0x0b, 0x30,     /* 0x0b Miscellaneous control */
 153                 0x0c, 0xd8,     /* 0x0c Luma Gain lsb */
 154                 0x0d, 0xfe,     /* 0x0d Chroma Gain (U) lsb */
 155                 0x0e, 0xb4,     /* 0x0e Chroma Gain (V) msb */
 156                 0x0f, 0x00,     /* 0x0f Hue control */
 157                 0x12, 0x04,     /* 0x12 Output Format */
 158                 0x13, 0x20,     /* 0x13 Vertical Scaling msb 0x00
 159                                            chroma comb OFF, line drop scaling, interlace scaling
 160                                            BUG? Why does turning the chroma comb on fuck up color?
 161                                            Bug in the bt819 stepping on my board?
 162                                         */
 163                 0x14, 0x00,     /* 0x14 Vertical Scaling lsb */
 164                 0x16, 0x07,     /* 0x16 Video Timing Polarity
 165                                            ACTIVE=active low
 166                                            FIELD: high=odd,
 167                                            vreset=active high,
 168                                            hreset=active high */
 169                 0x18, 0x68,     /* 0x18 AGC Delay */
 170                 0x19, 0x5d,     /* 0x19 Burst Gate Delay */
 171                 0x1a, 0x80,     /* 0x1a ADC Interface */
 172         };
 173 
 174         struct bt819 *decoder = to_bt819(sd);
 175         struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
 176 
 177         init[0x03 * 2 - 1] =
 178             (((timing->vdelay >> 8) & 0x03) << 6) |
 179             (((timing->vactive >> 8) & 0x03) << 4) |
 180             (((timing->hdelay >> 8) & 0x03) << 2) |
 181             ((timing->hactive >> 8) & 0x03);
 182         init[0x04 * 2 - 1] = timing->vdelay & 0xff;
 183         init[0x05 * 2 - 1] = timing->vactive & 0xff;
 184         init[0x06 * 2 - 1] = timing->hdelay & 0xff;
 185         init[0x07 * 2 - 1] = timing->hactive & 0xff;
 186         init[0x08 * 2 - 1] = timing->hscale >> 8;
 187         init[0x09 * 2 - 1] = timing->hscale & 0xff;
 188         /* 0x15 in array is address 0x19 */
 189         init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93;      /* Chroma burst delay */
 190         /* reset */
 191         bt819_write(decoder, 0x1f, 0x00);
 192         mdelay(1);
 193 
 194         /* init */
 195         return bt819_write_block(decoder, init, sizeof(init));
 196 }
 197 
 198 /* ----------------------------------------------------------------------- */
 199 
 200 static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
 201 {
 202         struct bt819 *decoder = to_bt819(sd);
 203         int status = bt819_read(decoder, 0x00);
 204         int res = V4L2_IN_ST_NO_SIGNAL;
 205         v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
 206 
 207         if ((status & 0x80))
 208                 res = 0;
 209         else
 210                 std = V4L2_STD_UNKNOWN;
 211 
 212         if ((status & 0x10))
 213                 std &= V4L2_STD_PAL;
 214         else
 215                 std &= V4L2_STD_NTSC;
 216         if (pstd)
 217                 *pstd = std;
 218         if (pstatus)
 219                 *pstatus = res;
 220 
 221         v4l2_dbg(1, debug, sd, "get status %x\n", status);
 222         return 0;
 223 }
 224 
 225 static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
 226 {
 227         return bt819_status(sd, NULL, std);
 228 }
 229 
 230 static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
 231 {
 232         return bt819_status(sd, status, NULL);
 233 }
 234 
 235 static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 236 {
 237         struct bt819 *decoder = to_bt819(sd);
 238         struct timing *timing = NULL;
 239 
 240         v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
 241 
 242         if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
 243                 v4l2_err(sd, "no notify found!\n");
 244 
 245         if (std & V4L2_STD_NTSC) {
 246                 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
 247                 bt819_setbit(decoder, 0x01, 0, 1);
 248                 bt819_setbit(decoder, 0x01, 1, 0);
 249                 bt819_setbit(decoder, 0x01, 5, 0);
 250                 bt819_write(decoder, 0x18, 0x68);
 251                 bt819_write(decoder, 0x19, 0x5d);
 252                 /* bt819_setbit(decoder, 0x1a,  5, 1); */
 253                 timing = &timing_data[1];
 254         } else if (std & V4L2_STD_PAL) {
 255                 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
 256                 bt819_setbit(decoder, 0x01, 0, 1);
 257                 bt819_setbit(decoder, 0x01, 1, 1);
 258                 bt819_setbit(decoder, 0x01, 5, 1);
 259                 bt819_write(decoder, 0x18, 0x7f);
 260                 bt819_write(decoder, 0x19, 0x72);
 261                 /* bt819_setbit(decoder, 0x1a,  5, 0); */
 262                 timing = &timing_data[0];
 263         } else {
 264                 v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
 265                                 (unsigned long long)std);
 266                 return -EINVAL;
 267         }
 268         bt819_write(decoder, 0x03,
 269                         (((timing->vdelay >> 8) & 0x03) << 6) |
 270                         (((timing->vactive >> 8) & 0x03) << 4) |
 271                         (((timing->hdelay >> 8) & 0x03) << 2) |
 272                         ((timing->hactive >> 8) & 0x03));
 273         bt819_write(decoder, 0x04, timing->vdelay & 0xff);
 274         bt819_write(decoder, 0x05, timing->vactive & 0xff);
 275         bt819_write(decoder, 0x06, timing->hdelay & 0xff);
 276         bt819_write(decoder, 0x07, timing->hactive & 0xff);
 277         bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
 278         bt819_write(decoder, 0x09, timing->hscale & 0xff);
 279         decoder->norm = std;
 280         v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
 281         return 0;
 282 }
 283 
 284 static int bt819_s_routing(struct v4l2_subdev *sd,
 285                            u32 input, u32 output, u32 config)
 286 {
 287         struct bt819 *decoder = to_bt819(sd);
 288 
 289         v4l2_dbg(1, debug, sd, "set input %x\n", input);
 290 
 291         if (input > 7)
 292                 return -EINVAL;
 293 
 294         if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
 295                 v4l2_err(sd, "no notify found!\n");
 296 
 297         if (decoder->input != input) {
 298                 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
 299                 decoder->input = input;
 300                 /* select mode */
 301                 if (decoder->input == 0) {
 302                         bt819_setbit(decoder, 0x0b, 6, 0);
 303                         bt819_setbit(decoder, 0x1a, 1, 1);
 304                 } else {
 305                         bt819_setbit(decoder, 0x0b, 6, 1);
 306                         bt819_setbit(decoder, 0x1a, 1, 0);
 307                 }
 308                 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
 309         }
 310         return 0;
 311 }
 312 
 313 static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
 314 {
 315         struct bt819 *decoder = to_bt819(sd);
 316 
 317         v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
 318 
 319         if (decoder->enable != enable) {
 320                 decoder->enable = enable;
 321                 bt819_setbit(decoder, 0x16, 7, !enable);
 322         }
 323         return 0;
 324 }
 325 
 326 static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
 327 {
 328         struct v4l2_subdev *sd = to_sd(ctrl);
 329         struct bt819 *decoder = to_bt819(sd);
 330         int temp;
 331 
 332         switch (ctrl->id) {
 333         case V4L2_CID_BRIGHTNESS:
 334                 bt819_write(decoder, 0x0a, ctrl->val);
 335                 break;
 336 
 337         case V4L2_CID_CONTRAST:
 338                 bt819_write(decoder, 0x0c, ctrl->val & 0xff);
 339                 bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
 340                 break;
 341 
 342         case V4L2_CID_SATURATION:
 343                 bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
 344                 bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
 345 
 346                 /* Ratio between U gain and V gain must stay the same as
 347                    the ratio between the default U and V gain values. */
 348                 temp = (ctrl->val * 180) / 254;
 349                 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
 350                 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
 351                 break;
 352 
 353         case V4L2_CID_HUE:
 354                 bt819_write(decoder, 0x0f, ctrl->val);
 355                 break;
 356 
 357         default:
 358                 return -EINVAL;
 359         }
 360         return 0;
 361 }
 362 
 363 /* ----------------------------------------------------------------------- */
 364 
 365 static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
 366         .s_ctrl = bt819_s_ctrl,
 367 };
 368 
 369 static const struct v4l2_subdev_video_ops bt819_video_ops = {
 370         .s_std = bt819_s_std,
 371         .s_routing = bt819_s_routing,
 372         .s_stream = bt819_s_stream,
 373         .querystd = bt819_querystd,
 374         .g_input_status = bt819_g_input_status,
 375 };
 376 
 377 static const struct v4l2_subdev_ops bt819_ops = {
 378         .video = &bt819_video_ops,
 379 };
 380 
 381 /* ----------------------------------------------------------------------- */
 382 
 383 static int bt819_probe(struct i2c_client *client,
 384                         const struct i2c_device_id *id)
 385 {
 386         int i, ver;
 387         struct bt819 *decoder;
 388         struct v4l2_subdev *sd;
 389         const char *name;
 390 
 391         /* Check if the adapter supports the needed features */
 392         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 393                 return -ENODEV;
 394 
 395         decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 396         if (decoder == NULL)
 397                 return -ENOMEM;
 398         sd = &decoder->sd;
 399         v4l2_i2c_subdev_init(sd, client, &bt819_ops);
 400 
 401         ver = bt819_read(decoder, 0x17);
 402         switch (ver & 0xf0) {
 403         case 0x70:
 404                 name = "bt819a";
 405                 break;
 406         case 0x60:
 407                 name = "bt817a";
 408                 break;
 409         case 0x20:
 410                 name = "bt815a";
 411                 break;
 412         default:
 413                 v4l2_dbg(1, debug, sd,
 414                         "unknown chip version 0x%02x\n", ver);
 415                 return -ENODEV;
 416         }
 417 
 418         v4l_info(client, "%s found @ 0x%x (%s)\n", name,
 419                         client->addr << 1, client->adapter->name);
 420 
 421         decoder->norm = V4L2_STD_NTSC;
 422         decoder->input = 0;
 423         decoder->enable = 1;
 424 
 425         i = bt819_init(sd);
 426         if (i < 0)
 427                 v4l2_dbg(1, debug, sd, "init status %d\n", i);
 428 
 429         v4l2_ctrl_handler_init(&decoder->hdl, 4);
 430         v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
 431                         V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
 432         v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
 433                         V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
 434         v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
 435                         V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
 436         v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
 437                         V4L2_CID_HUE, -128, 127, 1, 0);
 438         sd->ctrl_handler = &decoder->hdl;
 439         if (decoder->hdl.error) {
 440                 int err = decoder->hdl.error;
 441 
 442                 v4l2_ctrl_handler_free(&decoder->hdl);
 443                 return err;
 444         }
 445         v4l2_ctrl_handler_setup(&decoder->hdl);
 446         return 0;
 447 }
 448 
 449 static int bt819_remove(struct i2c_client *client)
 450 {
 451         struct v4l2_subdev *sd = i2c_get_clientdata(client);
 452         struct bt819 *decoder = to_bt819(sd);
 453 
 454         v4l2_device_unregister_subdev(sd);
 455         v4l2_ctrl_handler_free(&decoder->hdl);
 456         return 0;
 457 }
 458 
 459 /* ----------------------------------------------------------------------- */
 460 
 461 static const struct i2c_device_id bt819_id[] = {
 462         { "bt819a", 0 },
 463         { "bt817a", 0 },
 464         { "bt815a", 0 },
 465         { }
 466 };
 467 MODULE_DEVICE_TABLE(i2c, bt819_id);
 468 
 469 static struct i2c_driver bt819_driver = {
 470         .driver = {
 471                 .name   = "bt819",
 472         },
 473         .probe          = bt819_probe,
 474         .remove         = bt819_remove,
 475         .id_table       = bt819_id,
 476 };
 477 
 478 module_i2c_driver(bt819_driver);

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