1/* 2 * saa7191.c - Philips SAA7191 video decoder driver 3 * 4 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org> 5 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12#include <linux/delay.h> 13#include <linux/errno.h> 14#include <linux/fs.h> 15#include <linux/init.h> 16#include <linux/kernel.h> 17#include <linux/major.h> 18#include <linux/module.h> 19#include <linux/mm.h> 20#include <linux/slab.h> 21 22#include <linux/videodev2.h> 23#include <linux/i2c.h> 24#include <media/v4l2-device.h> 25#include <media/v4l2-chip-ident.h> 26#include <media/v4l2-i2c-drv.h> 27 28#include "saa7191.h" 29 30#define SAA7191_MODULE_VERSION "0.0.5" 31 32MODULE_DESCRIPTION("Philips SAA7191 video decoder driver"); 33MODULE_VERSION(SAA7191_MODULE_VERSION); 34MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>"); 35MODULE_LICENSE("GPL"); 36 37 38// #define SAA7191_DEBUG 39 40#ifdef SAA7191_DEBUG 41#define dprintk(x...) printk("SAA7191: " x); 42#else 43#define dprintk(x...) 44#endif 45 46#define SAA7191_SYNC_COUNT 30 47#define SAA7191_SYNC_DELAY 100 /* milliseconds */ 48 49struct saa7191 { 50 struct v4l2_subdev sd; 51 52 /* the register values are stored here as the actual 53 * I2C-registers are write-only */ 54 u8 reg[25]; 55 56 int input; 57 v4l2_std_id norm; 58}; 59 60static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd) 61{ 62 return container_of(sd, struct saa7191, sd); 63} 64 65static const u8 initseq[] = { 66 0, /* Subaddress */ 67 68 0x50, /* (0x50) SAA7191_REG_IDEL */ 69 70 /* 50 Hz signal timing */ 71 0x30, /* (0x30) SAA7191_REG_HSYB */ 72 0x00, /* (0x00) SAA7191_REG_HSYS */ 73 0xe8, /* (0xe8) SAA7191_REG_HCLB */ 74 0xb6, /* (0xb6) SAA7191_REG_HCLS */ 75 0xf4, /* (0xf4) SAA7191_REG_HPHI */ 76 77 /* control */ 78 SAA7191_LUMA_APER_1, /* (0x01) SAA7191_REG_LUMA - CVBS mode */ 79 0x00, /* (0x00) SAA7191_REG_HUEC */ 80 0xf8, /* (0xf8) SAA7191_REG_CKTQ */ 81 0xf8, /* (0xf8) SAA7191_REG_CKTS */ 82 0x90, /* (0x90) SAA7191_REG_PLSE */ 83 0x90, /* (0x90) SAA7191_REG_SESE */ 84 0x00, /* (0x00) SAA7191_REG_GAIN */ 85 SAA7191_STDC_NFEN | SAA7191_STDC_HRMV, /* (0x0c) SAA7191_REG_STDC 86 * - not SECAM, 87 * slow time constant */ 88 SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS 89 | SAA7191_IOCK_OEDY, /* (0x78) SAA7191_REG_IOCK 90 * - chroma from CVBS, GPSW1 & 2 off */ 91 SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS 92 | SAA7191_CTL3_YDEL0, /* (0x99) SAA7191_REG_CTL3 93 * - automatic field detection */ 94 0x00, /* (0x00) SAA7191_REG_CTL4 */ 95 0x2c, /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */ 96 0x00, /* unused */ 97 0x00, /* unused */ 98 99 /* 60 Hz signal timing */ 100 0x34, /* (0x34) SAA7191_REG_HS6B */ 101 0x0a, /* (0x0a) SAA7191_REG_HS6S */ 102 0xf4, /* (0xf4) SAA7191_REG_HC6B */ 103 0xce, /* (0xce) SAA7191_REG_HC6S */ 104 0xf4, /* (0xf4) SAA7191_REG_HP6I */ 105}; 106 107/* SAA7191 register handling */ 108 109static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg) 110{ 111 return to_saa7191(sd)->reg[reg]; 112} 113 114static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value) 115{ 116 struct i2c_client *client = v4l2_get_subdevdata(sd); 117 int ret; 118 119 ret = i2c_master_recv(client, value, 1); 120 if (ret < 0) { 121 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n"); 122 return ret; 123 } 124 125 return 0; 126} 127 128 129static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value) 130{ 131 struct i2c_client *client = v4l2_get_subdevdata(sd); 132 133 to_saa7191(sd)->reg[reg] = value; 134 return i2c_smbus_write_byte_data(client, reg, value); 135} 136 137/* the first byte of data must be the first subaddress number (register) */ 138static int saa7191_write_block(struct v4l2_subdev *sd, 139 u8 length, const u8 *data) 140{ 141 struct i2c_client *client = v4l2_get_subdevdata(sd); 142 struct saa7191 *decoder = to_saa7191(sd); 143 int i; 144 int ret; 145 146 for (i = 0; i < (length - 1); i++) { 147 decoder->reg[data[0] + i] = data[i + 1]; 148 } 149 150 ret = i2c_master_send(client, data, length); 151 if (ret < 0) { 152 printk(KERN_ERR "SAA7191: saa7191_write_block(): " 153 "write failed\n"); 154 return ret; 155 } 156 157 return 0; 158} 159 160/* Helper functions */ 161 162static int saa7191_s_routing(struct v4l2_subdev *sd, 163 u32 input, u32 output, u32 config) 164{ 165 struct saa7191 *decoder = to_saa7191(sd); 166 u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA); 167 u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK); 168 int err; 169 170 switch (input) { 171 case SAA7191_INPUT_COMPOSITE: /* Set Composite input */ 172 iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1 173 | SAA7191_IOCK_GPSW2); 174 /* Chrominance trap active */ 175 luma &= ~SAA7191_LUMA_BYPS; 176 break; 177 case SAA7191_INPUT_SVIDEO: /* Set S-Video input */ 178 iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2; 179 /* Chrominance trap bypassed */ 180 luma |= SAA7191_LUMA_BYPS; 181 break; 182 default: 183 return -EINVAL; 184 } 185 186 err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma); 187 if (err) 188 return -EIO; 189 err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock); 190 if (err) 191 return -EIO; 192 193 decoder->input = input; 194 195 return 0; 196} 197 198static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) 199{ 200 struct saa7191 *decoder = to_saa7191(sd); 201 u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC); 202 u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3); 203 u8 chcv = saa7191_read_reg(sd, SAA7191_REG_CHCV); 204 int err; 205 206 if (norm & V4L2_STD_PAL) { 207 stdc &= ~SAA7191_STDC_SECS; 208 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); 209 chcv = SAA7191_CHCV_PAL; 210 } else if (norm & V4L2_STD_NTSC) { 211 stdc &= ~SAA7191_STDC_SECS; 212 ctl3 &= ~SAA7191_CTL3_AUFD; 213 ctl3 |= SAA7191_CTL3_FSEL; 214 chcv = SAA7191_CHCV_NTSC; 215 } else if (norm & V4L2_STD_SECAM) { 216 stdc |= SAA7191_STDC_SECS; 217 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); 218 chcv = SAA7191_CHCV_PAL; 219 } else { 220 return -EINVAL; 221 } 222 223 err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); 224 if (err) 225 return -EIO; 226 err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc); 227 if (err) 228 return -EIO; 229 err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv); 230 if (err) 231 return -EIO; 232 233 decoder->norm = norm; 234 235 dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3, 236 stdc, chcv); 237 dprintk("norm: %llx\n", norm); 238 239 return 0; 240} 241 242static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status) 243{ 244 int i = 0; 245 246 dprintk("Checking for signal...\n"); 247 248 for (i = 0; i < SAA7191_SYNC_COUNT; i++) { 249 if (saa7191_read_status(sd, status)) 250 return -EIO; 251 252 if (((*status) & SAA7191_STATUS_HLCK) == 0) { 253 dprintk("Signal found\n"); 254 return 0; 255 } 256 257 msleep(SAA7191_SYNC_DELAY); 258 } 259 260 dprintk("No signal\n"); 261 262 return -EBUSY; 263} 264 265static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm) 266{ 267 struct saa7191 *decoder = to_saa7191(sd); 268 u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC); 269 u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3); 270 u8 status; 271 v4l2_std_id old_norm = decoder->norm; 272 int err = 0; 273 274 dprintk("SAA7191 extended signal auto-detection...\n"); 275 276 *norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; 277 stdc &= ~SAA7191_STDC_SECS; 278 ctl3 &= ~(SAA7191_CTL3_FSEL); 279 280 err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc); 281 if (err) { 282 err = -EIO; 283 goto out; 284 } 285 err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); 286 if (err) { 287 err = -EIO; 288 goto out; 289 } 290 291 ctl3 |= SAA7191_CTL3_AUFD; 292 err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3); 293 if (err) { 294 err = -EIO; 295 goto out; 296 } 297 298 msleep(SAA7191_SYNC_DELAY); 299 300 err = saa7191_wait_for_signal(sd, &status); 301 if (err) 302 goto out; 303 304 if (status & SAA7191_STATUS_FIDT) { 305 /* 60Hz signal -> NTSC */ 306 dprintk("60Hz signal: NTSC\n"); 307 *norm = V4L2_STD_NTSC; 308 return 0; 309 } 310 311 /* 50Hz signal */ 312 dprintk("50Hz signal: Trying PAL...\n"); 313 314 /* try PAL first */ 315 err = saa7191_s_std(sd, V4L2_STD_PAL); 316 if (err) 317 goto out; 318 319 msleep(SAA7191_SYNC_DELAY); 320 321 err = saa7191_wait_for_signal(sd, &status); 322 if (err) 323 goto out; 324 325 /* not 50Hz ? */ 326 if (status & SAA7191_STATUS_FIDT) { 327 dprintk("No 50Hz signal\n"); 328 saa7191_s_std(sd, old_norm); 329 return -EAGAIN; 330 } 331 332 if (status & SAA7191_STATUS_CODE) { 333 dprintk("PAL\n"); 334 *norm = V4L2_STD_PAL; 335 return saa7191_s_std(sd, old_norm); 336 } 337 338 dprintk("No color detected with PAL - Trying SECAM...\n"); 339 340 /* no color detected ? -> try SECAM */ 341 err = saa7191_s_std(sd, V4L2_STD_SECAM); 342 if (err) 343 goto out; 344 345 msleep(SAA7191_SYNC_DELAY); 346 347 err = saa7191_wait_for_signal(sd, &status); 348 if (err) 349 goto out; 350 351 /* not 50Hz ? */ 352 if (status & SAA7191_STATUS_FIDT) { 353 dprintk("No 50Hz signal\n"); 354 err = -EAGAIN; 355 goto out; 356 } 357 358 if (status & SAA7191_STATUS_CODE) { 359 /* Color detected -> SECAM */ 360 dprintk("SECAM\n"); 361 *norm = V4L2_STD_SECAM; 362 return saa7191_s_std(sd, old_norm); 363 } 364 365 dprintk("No color detected with SECAM - Going back to PAL.\n"); 366 367out: 368 return saa7191_s_std(sd, old_norm); 369} 370 371static int saa7191_autodetect_norm(struct v4l2_subdev *sd) 372{ 373 u8 status; 374 375 dprintk("SAA7191 signal auto-detection...\n"); 376 377 dprintk("Reading status...\n"); 378 379 if (saa7191_read_status(sd, &status)) 380 return -EIO; 381 382 dprintk("Checking for signal...\n"); 383 384 /* no signal ? */ 385 if (status & SAA7191_STATUS_HLCK) { 386 dprintk("No signal\n"); 387 return -EBUSY; 388 } 389 390 dprintk("Signal found\n"); 391 392 if (status & SAA7191_STATUS_FIDT) { 393 /* 60hz signal -> NTSC */ 394 dprintk("NTSC\n"); 395 return saa7191_s_std(sd, V4L2_STD_NTSC); 396 } else { 397 /* 50hz signal -> PAL */ 398 dprintk("PAL\n"); 399 return saa7191_s_std(sd, V4L2_STD_PAL); 400 } 401} 402 403static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 404{ 405 u8 reg; 406 int ret = 0; 407 408 switch (ctrl->id) { 409 case SAA7191_CONTROL_BANDPASS: 410 case SAA7191_CONTROL_BANDPASS_WEIGHT: 411 case SAA7191_CONTROL_CORING: 412 reg = saa7191_read_reg(sd, SAA7191_REG_LUMA); 413 switch (ctrl->id) { 414 case SAA7191_CONTROL_BANDPASS: 415 ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK) 416 >> SAA7191_LUMA_BPSS_SHIFT; 417 break; 418 case SAA7191_CONTROL_BANDPASS_WEIGHT: 419 ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK) 420 >> SAA7191_LUMA_APER_SHIFT; 421 break; 422 case SAA7191_CONTROL_CORING: 423 ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK) 424 >> SAA7191_LUMA_CORI_SHIFT; 425 break; 426 } 427 break; 428 case SAA7191_CONTROL_FORCE_COLOUR: 429 case SAA7191_CONTROL_CHROMA_GAIN: 430 reg = saa7191_read_reg(sd, SAA7191_REG_GAIN); 431 if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) 432 ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0; 433 else 434 ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK) 435 >> SAA7191_GAIN_LFIS_SHIFT; 436 break; 437 case V4L2_CID_HUE: 438 reg = saa7191_read_reg(sd, SAA7191_REG_HUEC); 439 if (reg < 0x80) 440 reg += 0x80; 441 else 442 reg -= 0x80; 443 ctrl->value = (s32)reg; 444 break; 445 case SAA7191_CONTROL_VTRC: 446 reg = saa7191_read_reg(sd, SAA7191_REG_STDC); 447 ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0; 448 break; 449 case SAA7191_CONTROL_LUMA_DELAY: 450 reg = saa7191_read_reg(sd, SAA7191_REG_CTL3); 451 ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK) 452 >> SAA7191_CTL3_YDEL_SHIFT; 453 if (ctrl->value >= 4) 454 ctrl->value -= 8; 455 break; 456 case SAA7191_CONTROL_VNR: 457 reg = saa7191_read_reg(sd, SAA7191_REG_CTL4); 458 ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK) 459 >> SAA7191_CTL4_VNOI_SHIFT; 460 break; 461 default: 462 ret = -EINVAL; 463 } 464 465 return ret; 466} 467 468static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 469{ 470 u8 reg; 471 int ret = 0; 472 473 switch (ctrl->id) { 474 case SAA7191_CONTROL_BANDPASS: 475 case SAA7191_CONTROL_BANDPASS_WEIGHT: 476 case SAA7191_CONTROL_CORING: 477 reg = saa7191_read_reg(sd, SAA7191_REG_LUMA); 478 switch (ctrl->id) { 479 case SAA7191_CONTROL_BANDPASS: 480 reg &= ~SAA7191_LUMA_BPSS_MASK; 481 reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT) 482 & SAA7191_LUMA_BPSS_MASK; 483 break; 484 case SAA7191_CONTROL_BANDPASS_WEIGHT: 485 reg &= ~SAA7191_LUMA_APER_MASK; 486 reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT) 487 & SAA7191_LUMA_APER_MASK; 488 break; 489 case SAA7191_CONTROL_CORING: 490 reg &= ~SAA7191_LUMA_CORI_MASK; 491 reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT) 492 & SAA7191_LUMA_CORI_MASK; 493 break; 494 } 495 ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg); 496 break; 497 case SAA7191_CONTROL_FORCE_COLOUR: 498 case SAA7191_CONTROL_CHROMA_GAIN: 499 reg = saa7191_read_reg(sd, SAA7191_REG_GAIN); 500 if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) { 501 if (ctrl->value) 502 reg |= SAA7191_GAIN_COLO; 503 else 504 reg &= ~SAA7191_GAIN_COLO; 505 } else { 506 reg &= ~SAA7191_GAIN_LFIS_MASK; 507 reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT) 508 & SAA7191_GAIN_LFIS_MASK; 509 } 510 ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg); 511 break; 512 case V4L2_CID_HUE: 513 reg = ctrl->value & 0xff; 514 if (reg < 0x80) 515 reg += 0x80; 516 else 517 reg -= 0x80; 518 ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg); 519 break; 520 case SAA7191_CONTROL_VTRC: 521 reg = saa7191_read_reg(sd, SAA7191_REG_STDC); 522 if (ctrl->value) 523 reg |= SAA7191_STDC_VTRC; 524 else 525 reg &= ~SAA7191_STDC_VTRC; 526 ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg); 527 break; 528 case SAA7191_CONTROL_LUMA_DELAY: { 529 s32 value = ctrl->value; 530 if (value < 0) 531 value += 8; 532 reg = saa7191_read_reg(sd, SAA7191_REG_CTL3); 533 reg &= ~SAA7191_CTL3_YDEL_MASK; 534 reg |= (value << SAA7191_CTL3_YDEL_SHIFT) 535 & SAA7191_CTL3_YDEL_MASK; 536 ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg); 537 break; 538 } 539 case SAA7191_CONTROL_VNR: 540 reg = saa7191_read_reg(sd, SAA7191_REG_CTL4); 541 reg &= ~SAA7191_CTL4_VNOI_MASK; 542 reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT) 543 & SAA7191_CTL4_VNOI_MASK; 544 ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg); 545 break; 546 default: 547 ret = -EINVAL; 548 } 549 550 return ret; 551} 552 553/* I2C-interface */ 554 555static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status) 556{ 557 u8 status_reg; 558 int res = V4L2_IN_ST_NO_SIGNAL; 559 560 if (saa7191_read_status(sd, &status_reg)) 561 return -EIO; 562 if ((status_reg & SAA7191_STATUS_HLCK) == 0) 563 res = 0; 564 if (!(status_reg & SAA7191_STATUS_CODE)) 565 res |= V4L2_IN_ST_NO_COLOR; 566 *status = res; 567 return 0; 568} 569 570 571static int saa7191_g_chip_ident(struct v4l2_subdev *sd, 572 struct v4l2_dbg_chip_ident *chip) 573{ 574 struct i2c_client *client = v4l2_get_subdevdata(sd); 575 576 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0); 577} 578 579/* ----------------------------------------------------------------------- */ 580 581static const struct v4l2_subdev_core_ops saa7191_core_ops = { 582 .g_chip_ident = saa7191_g_chip_ident, 583 .g_ctrl = saa7191_g_ctrl, 584 .s_ctrl = saa7191_s_ctrl, 585 .s_std = saa7191_s_std, 586}; 587 588static const struct v4l2_subdev_video_ops saa7191_video_ops = { 589 .s_routing = saa7191_s_routing, 590 .querystd = saa7191_querystd, 591 .g_input_status = saa7191_g_input_status, 592}; 593 594static const struct v4l2_subdev_ops saa7191_ops = { 595 .core = &saa7191_core_ops, 596 .video = &saa7191_video_ops, 597}; 598 599static int saa7191_probe(struct i2c_client *client, 600 const struct i2c_device_id *id) 601{ 602 int err = 0; 603 struct saa7191 *decoder; 604 struct v4l2_subdev *sd; 605 606 v4l_info(client, "chip found @ 0x%x (%s)\n", 607 client->addr << 1, client->adapter->name); 608 609 decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); 610 if (!decoder) 611 return -ENOMEM; 612 613 sd = &decoder->sd; 614 v4l2_i2c_subdev_init(sd, client, &saa7191_ops); 615 616 err = saa7191_write_block(sd, sizeof(initseq), initseq); 617 if (err) { 618 printk(KERN_ERR "SAA7191 initialization failed\n"); 619 kfree(decoder); 620 return err; 621 } 622 623 printk(KERN_INFO "SAA7191 initialized\n"); 624 625 decoder->input = SAA7191_INPUT_COMPOSITE; 626 decoder->norm = V4L2_STD_PAL; 627 628 err = saa7191_autodetect_norm(sd); 629 if (err && (err != -EBUSY)) 630 printk(KERN_ERR "SAA7191: Signal auto-detection failed\n"); 631 632 return 0; 633} 634 635static int saa7191_remove(struct i2c_client *client) 636{ 637 struct v4l2_subdev *sd = i2c_get_clientdata(client); 638 639 v4l2_device_unregister_subdev(sd); 640 kfree(to_saa7191(sd)); 641 return 0; 642} 643 644static const struct i2c_device_id saa7191_id[] = { 645 { "saa7191", 0 }, 646 { } 647}; 648MODULE_DEVICE_TABLE(i2c, saa7191_id); 649 650static struct v4l2_i2c_driver_data v4l2_i2c_data = { 651 .name = "saa7191", 652 .probe = saa7191_probe, 653 .remove = saa7191_remove, 654 .id_table = saa7191_id, 655}; 656