• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/media/video/
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