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