Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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