Эх сурвалжийг харах

Merge branch 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (101 commits)
  [media] staging/lirc: fix mem leaks and ptr err usage
  [media] hdpvr: reduce latency of i2c read/write w/recycled buffer
  [media] hdpvr: enable IR part
  [media] rc/mceusb: timeout should be in ns, not us
  [media] v4l2-device: fix 'use-after-freed' oops
  [media] v4l2-dev: don't memset video_device.dev
  [media] zoran: use video_device_alloc instead of kmalloc
  [media] w9966: zero device state after a detach
  [media] v4l: Fix a use-before-set in the control framework
  [media] v4l: Include linux/videodev2.h in media/v4l2-ctrls.h
  [media] DocBook/v4l: update V4L2 revision and update copyright years
  [media] DocBook/v4l: fix validation error in dev-rds.xml
  [media] v4l2-ctrls: queryctrl shouldn't attempt to replace V4L2_CID_PRIVATE_BASE IDs
  [media] v4l2-ctrls: fix missing 'read-only' check
  [media] pvrusb2: Provide more information about IR units to lirc_zilog and ir-kbd-i2c
  [media] ir-kbd-i2c: Add back defaults setting for Zilog Z8's at addr 0x71
  [media] lirc_zilog: Update TODO.lirc_zilog
  [media] lirc_zilog: Add Andy Walls to copyright notice and authors list
  [media] lirc_zilog: Remove useless struct i2c_driver.command function
  [media] lirc_zilog: Remove unneeded tests for existence of the IR Tx function
  ...
Linus Torvalds 14 жил өмнө
parent
commit
13a3cec844
100 өөрчлөгдсөн 1704 нэмэгдсэн , 1608 устгасан
  1. 1 1
      Documentation/DocBook/dvb/dvbapi.xml
  2. 2 2
      Documentation/DocBook/media.tmpl
  3. 4 2
      Documentation/DocBook/v4l/dev-rds.xml
  4. 2 1
      Documentation/DocBook/v4l/v4l2.xml
  5. 12 0
      Documentation/video4linux/v4l2-controls.txt
  6. 1 1
      drivers/media/common/saa7146_core.c
  7. 2 6
      drivers/media/common/saa7146_fops.c
  8. 1 1
      drivers/media/common/saa7146_vbi.c
  9. 1 19
      drivers/media/common/saa7146_video.c
  10. 74 56
      drivers/media/common/tuners/tda8290.c
  11. 3 3
      drivers/media/dvb/dvb-usb/dib0700_core.c
  12. 6 3
      drivers/media/dvb/firewire/firedtv-rc.c
  13. 2 2
      drivers/media/dvb/frontends/af9013.c
  14. 1 1
      drivers/media/dvb/frontends/ix2505v.c
  15. 30 6
      drivers/media/dvb/frontends/mb86a20s.c
  16. 1 1
      drivers/media/dvb/ttpci/av7110_ca.c
  17. 0 14
      drivers/media/radio/Kconfig
  18. 0 1
      drivers/media/radio/Makefile
  19. 1 0
      drivers/media/radio/radio-aimslab.c
  20. 0 478
      drivers/media/radio/radio-gemtek-pci.c
  21. 2 2
      drivers/media/radio/radio-maxiradio.c
  22. 1 1
      drivers/media/radio/radio-wl1273.c
  23. 2 7
      drivers/media/radio/si470x/radio-si470x-common.c
  24. 14 9
      drivers/media/rc/ene_ir.c
  25. 0 2
      drivers/media/rc/ene_ir.h
  26. 26 34
      drivers/media/rc/imon.c
  27. 1 1
      drivers/media/rc/ir-raw.c
  28. 26 26
      drivers/media/rc/keymaps/rc-dib0700-nec.c
  29. 1 2
      drivers/media/rc/mceusb.c
  30. 0 9
      drivers/media/video/Kconfig
  31. 0 1
      drivers/media/video/Makefile
  32. 11 0
      drivers/media/video/adv7175.c
  33. 0 39
      drivers/media/video/bt8xx/bttv-cards.c
  34. 0 1
      drivers/media/video/bt8xx/bttv.h
  35. 8 3
      drivers/media/video/cafe_ccic.c
  36. 1 1
      drivers/media/video/cpia2/cpia2.h
  37. 15 50
      drivers/media/video/cpia2/cpia2_core.c
  38. 34 70
      drivers/media/video/cpia2/cpia2_v4l.c
  39. 2 22
      drivers/media/video/cx18/cx18-driver.c
  40. 0 3
      drivers/media/video/cx18/cx18-driver.h
  41. 1 2
      drivers/media/video/cx18/cx18-streams.h
  42. 2 3
      drivers/media/video/cx231xx/cx231xx-dvb.c
  43. 6 16
      drivers/media/video/cx25840/cx25840-core.c
  44. 177 0
      drivers/media/video/davinci/vpif.c
  45. 10 8
      drivers/media/video/davinci/vpif.h
  46. 349 102
      drivers/media/video/davinci/vpif_capture.c
  47. 2 0
      drivers/media/video/davinci/vpif_capture.h
  48. 367 107
      drivers/media/video/davinci/vpif_display.c
  49. 2 0
      drivers/media/video/davinci/vpif_display.h
  50. 11 8
      drivers/media/video/em28xx/em28xx-cards.c
  51. 0 24
      drivers/media/video/et61x251/et61x251.h
  52. 1 1
      drivers/media/video/gspca/benq.c
  53. 2 2
      drivers/media/video/gspca/conex.c
  54. 1 1
      drivers/media/video/gspca/cpia1.c
  55. 2 2
      drivers/media/video/gspca/etoms.c
  56. 1 1
      drivers/media/video/gspca/finepix.c
  57. 1 1
      drivers/media/video/gspca/gl860/gl860.c
  58. 95 115
      drivers/media/video/gspca/gspca.c
  59. 0 2
      drivers/media/video/gspca/gspca.h
  60. 1 1
      drivers/media/video/gspca/jeilinj.c
  61. 2 2
      drivers/media/video/gspca/jpeg.h
  62. 1 1
      drivers/media/video/gspca/konica.c
  63. 1 1
      drivers/media/video/gspca/m5602/m5602_core.c
  64. 1 1
      drivers/media/video/gspca/mars.c
  65. 1 1
      drivers/media/video/gspca/mr97310a.c
  66. 3 5
      drivers/media/video/gspca/ov519.c
  67. 20 9
      drivers/media/video/gspca/ov534.c
  68. 1 1
      drivers/media/video/gspca/ov534_9.c
  69. 1 1
      drivers/media/video/gspca/pac207.c
  70. 2 2
      drivers/media/video/gspca/pac7302.c
  71. 2 2
      drivers/media/video/gspca/pac7311.c
  72. 1 1
      drivers/media/video/gspca/sn9c2028.c
  73. 1 1
      drivers/media/video/gspca/sn9c20x.c
  74. 157 113
      drivers/media/video/gspca/sonixb.c
  75. 78 77
      drivers/media/video/gspca/sonixj.c
  76. 1 1
      drivers/media/video/gspca/spca1528.c
  77. 1 1
      drivers/media/video/gspca/spca500.c
  78. 1 1
      drivers/media/video/gspca/spca501.c
  79. 1 1
      drivers/media/video/gspca/spca505.c
  80. 1 1
      drivers/media/video/gspca/spca508.c
  81. 1 1
      drivers/media/video/gspca/spca561.c
  82. 1 1
      drivers/media/video/gspca/sq905.c
  83. 1 1
      drivers/media/video/gspca/sq905c.c
  84. 1 1
      drivers/media/video/gspca/sq930x.c
  85. 1 1
      drivers/media/video/gspca/stk014.c
  86. 1 1
      drivers/media/video/gspca/stv0680.c
  87. 1 1
      drivers/media/video/gspca/stv06xx/stv06xx.c
  88. 1 1
      drivers/media/video/gspca/sunplus.c
  89. 1 1
      drivers/media/video/gspca/t613.c
  90. 1 1
      drivers/media/video/gspca/tv8532.c
  91. 1 1
      drivers/media/video/gspca/vc032x.c
  92. 1 1
      drivers/media/video/gspca/xirlink_cit.c
  93. 1 1
      drivers/media/video/gspca/zc3xx.c
  94. 1 3
      drivers/media/video/hdpvr/Makefile
  95. 4 6
      drivers/media/video/hdpvr/hdpvr-core.c
  96. 67 76
      drivers/media/video/hdpvr/hdpvr-i2c.c
  97. 2 5
      drivers/media/video/hdpvr/hdpvr-video.c
  98. 4 1
      drivers/media/video/hdpvr/hdpvr.h
  99. 10 2
      drivers/media/video/ir-kbd-i2c.c
  100. 7 2
      drivers/media/video/ivtv/ivtv-i2c.c

+ 1 - 1
Documentation/DocBook/dvb/dvbapi.xml

@@ -28,7 +28,7 @@
 	<holder>Convergence GmbH</holder>
 	<holder>Convergence GmbH</holder>
 </copyright>
 </copyright>
 <copyright>
 <copyright>
-	<year>2009-2010</year>
+	<year>2009-2011</year>
 	<holder>Mauro Carvalho Chehab</holder>
 	<holder>Mauro Carvalho Chehab</holder>
 </copyright>
 </copyright>
 
 

+ 2 - 2
Documentation/DocBook/media.tmpl

@@ -28,7 +28,7 @@
 <title>LINUX MEDIA INFRASTRUCTURE API</title>
 <title>LINUX MEDIA INFRASTRUCTURE API</title>
 
 
 <copyright>
 <copyright>
-	<year>2009-2010</year>
+	<year>2009-2011</year>
 	<holder>LinuxTV Developers</holder>
 	<holder>LinuxTV Developers</holder>
 </copyright>
 </copyright>
 
 
@@ -86,7 +86,7 @@ Foundation. A copy of the license is included in the chapter entitled
 </author>
 </author>
 </authorgroup>
 </authorgroup>
 <copyright>
 <copyright>
-	<year>2009-2010</year>
+	<year>2009-2011</year>
 	<holder>Mauro Carvalho Chehab</holder>
 	<holder>Mauro Carvalho Chehab</holder>
 </copyright>
 </copyright>
 
 

+ 4 - 2
Documentation/DocBook/v4l/dev-rds.xml

@@ -75,6 +75,7 @@ as follows:</para>
   </section>
   </section>
 
 
   <section>
   <section>
+    <title>RDS datastructures</title>
     <table frame="none" pgwide="1" id="v4l2-rds-data">
     <table frame="none" pgwide="1" id="v4l2-rds-data">
       <title>struct
       <title>struct
 <structname>v4l2_rds_data</structname></title>
 <structname>v4l2_rds_data</structname></title>
@@ -129,10 +130,11 @@ as follows:</para>
 
 
     <table frame="none" pgwide="1" id="v4l2-rds-block-codes">
     <table frame="none" pgwide="1" id="v4l2-rds-block-codes">
       <title>Block defines</title>
       <title>Block defines</title>
-      <tgroup cols="3">
+      <tgroup cols="4">
 	<colspec colname="c1" colwidth="1*" />
 	<colspec colname="c1" colwidth="1*" />
 	<colspec colname="c2" colwidth="1*" />
 	<colspec colname="c2" colwidth="1*" />
-	<colspec colname="c3" colwidth="5*" />
+	<colspec colname="c3" colwidth="1*" />
+	<colspec colname="c4" colwidth="5*" />
 	<tbody valign="top">
 	<tbody valign="top">
 	  <row>
 	  <row>
 	    <entry>V4L2_RDS_BLOCK_MSK</entry>
 	    <entry>V4L2_RDS_BLOCK_MSK</entry>

+ 2 - 1
Documentation/DocBook/v4l/v4l2.xml

@@ -100,6 +100,7 @@ Remote Controller chapter.</contrib>
       <year>2008</year>
       <year>2008</year>
       <year>2009</year>
       <year>2009</year>
       <year>2010</year>
       <year>2010</year>
+      <year>2011</year>
       <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
       <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
 Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder>
 Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder>
     </copyright>
     </copyright>
@@ -381,7 +382,7 @@ and discussions on the V4L mailing list.</revremark>
 </partinfo>
 </partinfo>
 
 
 <title>Video for Linux Two API Specification</title>
 <title>Video for Linux Two API Specification</title>
- <subtitle>Revision 2.6.33</subtitle>
+ <subtitle>Revision 2.6.38</subtitle>
 
 
   <chapter id="common">
   <chapter id="common">
     &sub-common;
     &sub-common;

+ 12 - 0
Documentation/video4linux/v4l2-controls.txt

@@ -285,6 +285,9 @@ implement g_volatile_ctrl like this:
 The 'new value' union is not used in g_volatile_ctrl. In general controls
 The 'new value' union is not used in g_volatile_ctrl. In general controls
 that need to implement g_volatile_ctrl are read-only controls.
 that need to implement g_volatile_ctrl are read-only controls.
 
 
+Note that if one or more controls in a control cluster are marked as volatile,
+then all the controls in the cluster are seen as volatile.
+
 To mark a control as volatile you have to set the is_volatile flag:
 To mark a control as volatile you have to set the is_volatile flag:
 
 
 	ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...);
 	ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...);
@@ -462,6 +465,15 @@ pointer to the v4l2_ctrl_ops struct that is used for that cluster.
 Obviously, all controls in the cluster array must be initialized to either
 Obviously, all controls in the cluster array must be initialized to either
 a valid control or to NULL.
 a valid control or to NULL.
 
 
+In rare cases you might want to know which controls of a cluster actually
+were set explicitly by the user. For this you can check the 'is_new' flag of
+each control. For example, in the case of a volume/mute cluster the 'is_new'
+flag of the mute control would be set if the user called VIDIOC_S_CTRL for
+mute only. If the user would call VIDIOC_S_EXT_CTRLS for both mute and volume
+controls, then the 'is_new' flag would be 1 for both controls.
+
+The 'is_new' flag is always 1 when called from v4l2_ctrl_handler_setup().
+
 
 
 VIDIOC_LOG_STATUS Support
 VIDIOC_LOG_STATUS Support
 =========================
 =========================

+ 1 - 1
drivers/media/common/saa7146_core.c

@@ -452,7 +452,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
 	INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device));
 	INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device));
 	dev->ext = ext;
 	dev->ext = ext;
 
 
-	mutex_init(&dev->lock);
+	mutex_init(&dev->v4l2_lock);
 	spin_lock_init(&dev->int_slock);
 	spin_lock_init(&dev->int_slock);
 	spin_lock_init(&dev->slock);
 	spin_lock_init(&dev->slock);
 
 

+ 2 - 6
drivers/media/common/saa7146_fops.c

@@ -15,18 +15,15 @@ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
 	}
 	}
 
 
 	/* is it free? */
 	/* is it free? */
-	mutex_lock(&dev->lock);
 	if (vv->resources & bit) {
 	if (vv->resources & bit) {
 		DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
 		DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
 		/* no, someone else uses it */
 		/* no, someone else uses it */
-		mutex_unlock(&dev->lock);
 		return 0;
 		return 0;
 	}
 	}
 	/* it's free, grab it */
 	/* it's free, grab it */
 	fh->resources  |= bit;
 	fh->resources  |= bit;
 	vv->resources |= bit;
 	vv->resources |= bit;
 	DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources));
 	DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources));
-	mutex_unlock(&dev->lock);
 	return 1;
 	return 1;
 }
 }
 
 
@@ -37,11 +34,9 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
 
 
 	BUG_ON((fh->resources & bits) != bits);
 	BUG_ON((fh->resources & bits) != bits);
 
 
-	mutex_lock(&dev->lock);
 	fh->resources  &= ~bits;
 	fh->resources  &= ~bits;
 	vv->resources &= ~bits;
 	vv->resources &= ~bits;
 	DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources));
 	DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources));
-	mutex_unlock(&dev->lock);
 }
 }
 
 
 
 
@@ -396,7 +391,7 @@ static const struct v4l2_file_operations video_fops =
 	.write		= fops_write,
 	.write		= fops_write,
 	.poll		= fops_poll,
 	.poll		= fops_poll,
 	.mmap		= fops_mmap,
 	.mmap		= fops_mmap,
-	.ioctl		= video_ioctl2,
+	.unlocked_ioctl	= video_ioctl2,
 };
 };
 
 
 static void vv_callback(struct saa7146_dev *dev, unsigned long status)
 static void vv_callback(struct saa7146_dev *dev, unsigned long status)
@@ -505,6 +500,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
 	vfd->fops = &video_fops;
 	vfd->fops = &video_fops;
 	vfd->ioctl_ops = &dev->ext_vv_data->ops;
 	vfd->ioctl_ops = &dev->ext_vv_data->ops;
 	vfd->release = video_device_release;
 	vfd->release = video_device_release;
+	vfd->lock = &dev->v4l2_lock;
 	vfd->tvnorms = 0;
 	vfd->tvnorms = 0;
 	for (i = 0; i < dev->ext_vv_data->num_stds; i++)
 	for (i = 0; i < dev->ext_vv_data->num_stds; i++)
 		vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
 		vfd->tvnorms |= dev->ext_vv_data->stds[i].id;

+ 1 - 1
drivers/media/common/saa7146_vbi.c

@@ -412,7 +412,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
 			    V4L2_BUF_TYPE_VBI_CAPTURE,
 			    V4L2_BUF_TYPE_VBI_CAPTURE,
 			    V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
 			    V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
 			    sizeof(struct saa7146_buf),
 			    sizeof(struct saa7146_buf),
-			    file, NULL);
+			    file, &dev->v4l2_lock);
 
 
 	init_timer(&fh->vbi_read_timeout);
 	init_timer(&fh->vbi_read_timeout);
 	fh->vbi_read_timeout.function = vbi_read_timeout;
 	fh->vbi_read_timeout.function = vbi_read_timeout;

+ 1 - 19
drivers/media/common/saa7146_video.c

@@ -553,8 +553,6 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
 		}
 		}
 	}
 	}
 
 
-	mutex_lock(&dev->lock);
-
 	/* ok, accept it */
 	/* ok, accept it */
 	vv->ov_fb = *fb;
 	vv->ov_fb = *fb;
 	vv->ov_fmt = fmt;
 	vv->ov_fmt = fmt;
@@ -563,8 +561,6 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
 		vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
 		vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
 		DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline));
 		DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline));
 	}
 	}
-
-	mutex_unlock(&dev->lock);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -649,8 +645,6 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	mutex_lock(&dev->lock);
-
 	switch (ctrl->type) {
 	switch (ctrl->type) {
 	case V4L2_CTRL_TYPE_BOOLEAN:
 	case V4L2_CTRL_TYPE_BOOLEAN:
 	case V4L2_CTRL_TYPE_MENU:
 	case V4L2_CTRL_TYPE_MENU:
@@ -693,7 +687,6 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
 		/* fixme: we can support changing VFLIP and HFLIP here... */
 		/* fixme: we can support changing VFLIP and HFLIP here... */
 		if (IS_CAPTURE_ACTIVE(fh) != 0) {
 		if (IS_CAPTURE_ACTIVE(fh) != 0) {
 			DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
 			DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
-			mutex_unlock(&dev->lock);
 			return -EBUSY;
 			return -EBUSY;
 		}
 		}
 		vv->hflip = c->value;
 		vv->hflip = c->value;
@@ -701,16 +694,13 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
 	case V4L2_CID_VFLIP:
 	case V4L2_CID_VFLIP:
 		if (IS_CAPTURE_ACTIVE(fh) != 0) {
 		if (IS_CAPTURE_ACTIVE(fh) != 0) {
 			DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
 			DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
-			mutex_unlock(&dev->lock);
 			return -EBUSY;
 			return -EBUSY;
 		}
 		}
 		vv->vflip = c->value;
 		vv->vflip = c->value;
 		break;
 		break;
 	default:
 	default:
-		mutex_unlock(&dev->lock);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-	mutex_unlock(&dev->lock);
 
 
 	if (IS_OVERLAY_ACTIVE(fh) != 0) {
 	if (IS_OVERLAY_ACTIVE(fh) != 0) {
 		saa7146_stop_preview(fh);
 		saa7146_stop_preview(fh);
@@ -902,22 +892,18 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_f
 	err = vidioc_try_fmt_vid_overlay(file, fh, f);
 	err = vidioc_try_fmt_vid_overlay(file, fh, f);
 	if (0 != err)
 	if (0 != err)
 		return err;
 		return err;
-	mutex_lock(&dev->lock);
 	fh->ov.win    = f->fmt.win;
 	fh->ov.win    = f->fmt.win;
 	fh->ov.nclips = f->fmt.win.clipcount;
 	fh->ov.nclips = f->fmt.win.clipcount;
 	if (fh->ov.nclips > 16)
 	if (fh->ov.nclips > 16)
 		fh->ov.nclips = 16;
 		fh->ov.nclips = 16;
 	if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
 	if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
 				sizeof(struct v4l2_clip) * fh->ov.nclips)) {
 				sizeof(struct v4l2_clip) * fh->ov.nclips)) {
-		mutex_unlock(&dev->lock);
 		return -EFAULT;
 		return -EFAULT;
 	}
 	}
 
 
 	/* fh->ov.fh is used to indicate that we have valid overlay informations, too */
 	/* fh->ov.fh is used to indicate that we have valid overlay informations, too */
 	fh->ov.fh = fh;
 	fh->ov.fh = fh;
 
 
-	mutex_unlock(&dev->lock);
-
 	/* check if our current overlay is active */
 	/* check if our current overlay is active */
 	if (IS_OVERLAY_ACTIVE(fh) != 0) {
 	if (IS_OVERLAY_ACTIVE(fh) != 0) {
 		saa7146_stop_preview(fh);
 		saa7146_stop_preview(fh);
@@ -976,8 +962,6 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
 		}
 		}
 	}
 	}
 
 
-	mutex_lock(&dev->lock);
-
 	for (i = 0; i < dev->ext_vv_data->num_stds; i++)
 	for (i = 0; i < dev->ext_vv_data->num_stds; i++)
 		if (*id & dev->ext_vv_data->stds[i].id)
 		if (*id & dev->ext_vv_data->stds[i].id)
 			break;
 			break;
@@ -988,8 +972,6 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
 		found = 1;
 		found = 1;
 	}
 	}
 
 
-	mutex_unlock(&dev->lock);
-
 	if (vv->ov_suspend != NULL) {
 	if (vv->ov_suspend != NULL) {
 		saa7146_start_preview(vv->ov_suspend);
 		saa7146_start_preview(vv->ov_suspend);
 		vv->ov_suspend = NULL;
 		vv->ov_suspend = NULL;
@@ -1354,7 +1336,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
 			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
 			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
 			    V4L2_FIELD_INTERLACED,
 			    V4L2_FIELD_INTERLACED,
 			    sizeof(struct saa7146_buf),
 			    sizeof(struct saa7146_buf),
-			    file, NULL);
+			    file, &dev->v4l2_lock);
 
 
 	return 0;
 	return 0;
 }
 }

+ 74 - 56
drivers/media/common/tuners/tda8290.c

@@ -95,8 +95,7 @@ static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close)
 		msleep(20);
 		msleep(20);
 	} else {
 	} else {
 		msg = disable;
 		msg = disable;
-		tuner_i2c_xfer_send(&priv->i2c_props, msg, 1);
-		tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1);
+		tuner_i2c_xfer_send_recv(&priv->i2c_props, msg, 1, &msg[1], 1);
 
 
 		buf[2] = msg[1];
 		buf[2] = msg[1];
 		buf[2] &= ~0x04;
 		buf[2] &= ~0x04;
@@ -233,19 +232,22 @@ static void tda8290_set_params(struct dvb_frontend *fe,
 		tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
 		tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
 	}
 	}
 
 
+
 	tda8290_i2c_bridge(fe, 1);
 	tda8290_i2c_bridge(fe, 1);
 
 
 	if (fe->ops.tuner_ops.set_analog_params)
 	if (fe->ops.tuner_ops.set_analog_params)
 		fe->ops.tuner_ops.set_analog_params(fe, params);
 		fe->ops.tuner_ops.set_analog_params(fe, params);
 
 
 	for (i = 0; i < 3; i++) {
 	for (i = 0; i < 3; i++) {
-		tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
-		tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
+		tuner_i2c_xfer_send_recv(&priv->i2c_props,
+					 &addr_pll_stat, 1, &pll_stat, 1);
 		if (pll_stat & 0x80) {
 		if (pll_stat & 0x80) {
-			tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
-			tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
-			tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
-			tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
+			tuner_i2c_xfer_send_recv(&priv->i2c_props,
+						 &addr_adc_sat, 1,
+						 &adc_sat, 1);
+			tuner_i2c_xfer_send_recv(&priv->i2c_props,
+						 &addr_agc_stat, 1,
+						 &agc_stat, 1);
 			tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
 			tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
 			break;
 			break;
 		} else {
 		} else {
@@ -259,20 +261,22 @@ static void tda8290_set_params(struct dvb_frontend *fe,
 			   agc_stat, adc_sat, pll_stat & 0x80);
 			   agc_stat, adc_sat, pll_stat & 0x80);
 		tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
 		tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
 		msleep(100);
 		msleep(100);
-		tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
-		tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
-		tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
-		tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
+		tuner_i2c_xfer_send_recv(&priv->i2c_props,
+					 &addr_agc_stat, 1, &agc_stat, 1);
+		tuner_i2c_xfer_send_recv(&priv->i2c_props,
+					 &addr_pll_stat, 1, &pll_stat, 1);
 		if ((agc_stat > 115) || !(pll_stat & 0x80)) {
 		if ((agc_stat > 115) || !(pll_stat & 0x80)) {
 			tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
 			tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
 				   agc_stat, pll_stat & 0x80);
 				   agc_stat, pll_stat & 0x80);
 			if (priv->cfg.agcf)
 			if (priv->cfg.agcf)
 				priv->cfg.agcf(fe);
 				priv->cfg.agcf(fe);
 			msleep(100);
 			msleep(100);
-			tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
-			tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
-			tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
-			tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
+			tuner_i2c_xfer_send_recv(&priv->i2c_props,
+						 &addr_agc_stat, 1,
+						 &agc_stat, 1);
+			tuner_i2c_xfer_send_recv(&priv->i2c_props,
+						 &addr_pll_stat, 1,
+						 &pll_stat, 1);
 			if((agc_stat > 115) || !(pll_stat & 0x80)) {
 			if((agc_stat > 115) || !(pll_stat & 0x80)) {
 				tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
 				tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
 				tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
 				tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
@@ -284,10 +288,12 @@ static void tda8290_set_params(struct dvb_frontend *fe,
 
 
 	/* l/ l' deadlock? */
 	/* l/ l' deadlock? */
 	if(priv->tda8290_easy_mode & 0x60) {
 	if(priv->tda8290_easy_mode & 0x60) {
-		tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
-		tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
-		tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
-		tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
+		tuner_i2c_xfer_send_recv(&priv->i2c_props,
+					 &addr_adc_sat, 1,
+					 &adc_sat, 1);
+		tuner_i2c_xfer_send_recv(&priv->i2c_props,
+					 &addr_pll_stat, 1,
+					 &pll_stat, 1);
 		if ((adc_sat > 20) || !(pll_stat & 0x80)) {
 		if ((adc_sat > 20) || !(pll_stat & 0x80)) {
 			tuner_dbg("trying to resolve SECAM L deadlock\n");
 			tuner_dbg("trying to resolve SECAM L deadlock\n");
 			tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
 			tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
@@ -307,8 +313,7 @@ static void tda8295_power(struct dvb_frontend *fe, int enable)
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 	unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */
 	unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */
 
 
-	tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
-	tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
+	tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
 
 
 	if (enable)
 	if (enable)
 		buf[1] = 0x01;
 		buf[1] = 0x01;
@@ -323,8 +328,7 @@ static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable)
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 	unsigned char buf[] = { 0x01, 0x00 };
 	unsigned char buf[] = { 0x01, 0x00 };
 
 
-	tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
-	tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
+	tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
 
 
 	if (enable)
 	if (enable)
 		buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */
 		buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */
@@ -353,8 +357,7 @@ static void tda8295_agc1_out(struct dvb_frontend *fe, int enable)
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 	unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */
 	unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */
 
 
-	tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
-	tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
+	tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
 
 
 	if (enable)
 	if (enable)
 		buf[1] &= ~0x40;
 		buf[1] &= ~0x40;
@@ -370,10 +373,10 @@ static void tda8295_agc2_out(struct dvb_frontend *fe, int enable)
 	unsigned char set_gpio_cf[]    = { 0x44, 0x00 };
 	unsigned char set_gpio_cf[]    = { 0x44, 0x00 };
 	unsigned char set_gpio_val[]   = { 0x46, 0x00 };
 	unsigned char set_gpio_val[]   = { 0x46, 0x00 };
 
 
-	tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1);
-	tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1);
-	tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1);
-	tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1);
+	tuner_i2c_xfer_send_recv(&priv->i2c_props,
+				 &set_gpio_cf[0], 1, &set_gpio_cf[1], 1);
+	tuner_i2c_xfer_send_recv(&priv->i2c_props,
+				 &set_gpio_val[0], 1, &set_gpio_val[1], 1);
 
 
 	set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */
 	set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */
 
 
@@ -392,8 +395,7 @@ static int tda8295_has_signal(struct dvb_frontend *fe)
 	unsigned char hvpll_stat = 0x26;
 	unsigned char hvpll_stat = 0x26;
 	unsigned char ret;
 	unsigned char ret;
 
 
-	tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1);
-	tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1);
+	tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1);
 	return (ret & 0x01) ? 65535 : 0;
 	return (ret & 0x01) ? 65535 : 0;
 }
 }
 
 
@@ -413,8 +415,8 @@ static void tda8295_set_params(struct dvb_frontend *fe,
 	tda8295_power(fe, 1);
 	tda8295_power(fe, 1);
 	tda8295_agc1_out(fe, 1);
 	tda8295_agc1_out(fe, 1);
 
 
-	tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1);
-	tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1);
+	tuner_i2c_xfer_send_recv(&priv->i2c_props,
+				 &blanking_mode[0], 1, &blanking_mode[1], 1);
 
 
 	tda8295_set_video_std(fe);
 	tda8295_set_video_std(fe);
 
 
@@ -447,8 +449,8 @@ static int tda8290_has_signal(struct dvb_frontend *fe)
 	unsigned char i2c_get_afc[1] = { 0x1B };
 	unsigned char i2c_get_afc[1] = { 0x1B };
 	unsigned char afc = 0;
 	unsigned char afc = 0;
 
 
-	tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
-	tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1);
+	tuner_i2c_xfer_send_recv(&priv->i2c_props,
+				 i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1);
 	return (afc & 0x80)? 65535:0;
 	return (afc & 0x80)? 65535:0;
 }
 }
 
 
@@ -654,20 +656,26 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
 static int tda8290_probe(struct tuner_i2c_props *i2c_props)
 static int tda8290_probe(struct tuner_i2c_props *i2c_props)
 {
 {
 #define TDA8290_ID 0x89
 #define TDA8290_ID 0x89
-	unsigned char tda8290_id[] = { 0x1f, 0x00 };
+	u8 reg = 0x1f, id;
+	struct i2c_msg msg_read[] = {
+		{ .addr = 0x4b, .flags = 0, .len = 1, .buf = &reg },
+		{ .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id },
+	};
 
 
 	/* detect tda8290 */
 	/* detect tda8290 */
-	tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1);
-	tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1);
+	if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
+		printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n",
+			       __func__, reg);
+		return -ENODEV;
+	}
 
 
-	if (tda8290_id[1] == TDA8290_ID) {
+	if (id == TDA8290_ID) {
 		if (debug)
 		if (debug)
 			printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n",
 			printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n",
 			       __func__, i2c_adapter_id(i2c_props->adap),
 			       __func__, i2c_adapter_id(i2c_props->adap),
 			       i2c_props->addr);
 			       i2c_props->addr);
 		return 0;
 		return 0;
 	}
 	}
-
 	return -ENODEV;
 	return -ENODEV;
 }
 }
 
 
@@ -675,16 +683,23 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props)
 {
 {
 #define TDA8295_ID 0x8a
 #define TDA8295_ID 0x8a
 #define TDA8295C2_ID 0x8b
 #define TDA8295C2_ID 0x8b
-	unsigned char tda8295_id[] = { 0x2f, 0x00 };
+	u8 reg = 0x2f, id;
+	struct i2c_msg msg_read[] = {
+		{ .addr = 0x4b, .flags = 0, .len = 1, .buf = &reg },
+		{ .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id },
+	};
 
 
-	/* detect tda8295 */
-	tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1);
-	tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1);
+	/* detect tda8290 */
+	if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
+		printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n",
+			       __func__, reg);
+		return -ENODEV;
+	}
 
 
-	if ((tda8295_id[1] & 0xfe) == TDA8295_ID) {
+	if ((id & 0xfe) == TDA8295_ID) {
 		if (debug)
 		if (debug)
 			printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n",
 			printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n",
-			       __func__, (tda8295_id[1] == TDA8295_ID) ?
+			       __func__, (id == TDA8295_ID) ?
 			       "tda8295c1" : "tda8295c2",
 			       "tda8295c1" : "tda8295c2",
 			       i2c_adapter_id(i2c_props->adap),
 			       i2c_adapter_id(i2c_props->adap),
 			       i2c_props->addr);
 			       i2c_props->addr);
@@ -740,9 +755,11 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
 		       sizeof(struct analog_demod_ops));
 		       sizeof(struct analog_demod_ops));
 	}
 	}
 
 
-	if ((!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) &&
-	    (tda829x_find_tuner(fe) < 0))
-		goto fail;
+	if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) {
+		tda8295_power(fe, 1);
+		if (tda829x_find_tuner(fe) < 0)
+			goto fail;
+	}
 
 
 	switch (priv->ver) {
 	switch (priv->ver) {
 	case TDA8290:
 	case TDA8290:
@@ -786,6 +803,8 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
 	return fe;
 	return fe;
 
 
 fail:
 fail:
+	memset(&fe->ops.analog_ops, 0, sizeof(struct analog_demod_ops));
+
 	tda829x_release(fe);
 	tda829x_release(fe);
 	return NULL;
 	return NULL;
 }
 }
@@ -809,8 +828,8 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
 	int i;
 	int i;
 
 
 	/* rule out tda9887, which would return the same byte repeatedly */
 	/* rule out tda9887, which would return the same byte repeatedly */
-	tuner_i2c_xfer_send(&i2c_props, soft_reset, 1);
-	tuner_i2c_xfer_recv(&i2c_props, buf, PROBE_BUFFER_SIZE);
+	tuner_i2c_xfer_send_recv(&i2c_props,
+				 soft_reset, 1, buf, PROBE_BUFFER_SIZE);
 	for (i = 1; i < PROBE_BUFFER_SIZE; i++) {
 	for (i = 1; i < PROBE_BUFFER_SIZE; i++) {
 		if (buf[i] != buf[0])
 		if (buf[i] != buf[0])
 			break;
 			break;
@@ -827,13 +846,12 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
 	/* fall back to old probing method */
 	/* fall back to old probing method */
 	tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
 	tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
 	tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
 	tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
-	tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
-	tuner_i2c_xfer_recv(&i2c_props, &data, 1);
+	tuner_i2c_xfer_send_recv(&i2c_props, &addr_dto_lsb, 1, &data, 1);
 	if (data == 0) {
 	if (data == 0) {
 		tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
 		tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
 		tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
 		tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
-		tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
-		tuner_i2c_xfer_recv(&i2c_props, &data, 1);
+		tuner_i2c_xfer_send_recv(&i2c_props,
+					 &addr_dto_lsb, 1, &data, 1);
 		if (data == 0x7b) {
 		if (data == 0x7b) {
 			return 0;
 			return 0;
 		}
 		}

+ 3 - 3
drivers/media/dvb/dvb-usb/dib0700_core.c

@@ -514,8 +514,8 @@ struct dib0700_rc_response {
 	union {
 	union {
 		u16 system16;
 		u16 system16;
 		struct {
 		struct {
-			u8 system;
 			u8 not_system;
 			u8 not_system;
+			u8 system;
 		};
 		};
 	};
 	};
 	u8 data;
 	u8 data;
@@ -575,7 +575,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
 		if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
 		if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
 			deb_data("NEC extended protocol\n");
 			deb_data("NEC extended protocol\n");
 			/* NEC extended code - 24 bits */
 			/* NEC extended code - 24 bits */
-			keycode = poll_reply->system16 << 8 | poll_reply->data;
+			keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data;
 		} else {
 		} else {
 			deb_data("NEC normal protocol\n");
 			deb_data("NEC normal protocol\n");
 			/* normal NEC code - 16 bits */
 			/* normal NEC code - 16 bits */
@@ -587,7 +587,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
 		deb_data("RC5 protocol\n");
 		deb_data("RC5 protocol\n");
 		/* RC5 Protocol */
 		/* RC5 Protocol */
 		toggle = poll_reply->report_id;
 		toggle = poll_reply->report_id;
-		keycode = poll_reply->system16 << 8 | poll_reply->data;
+		keycode = poll_reply->system << 8 | poll_reply->data;
 
 
 		break;
 		break;
 	}
 	}

+ 6 - 3
drivers/media/dvb/firewire/firedtv-rc.c

@@ -172,7 +172,8 @@ void fdtv_unregister_rc(struct firedtv *fdtv)
 
 
 void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
 void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
 {
 {
-	u16 *keycode = fdtv->remote_ctrl_dev->keycode;
+	struct input_dev *idev = fdtv->remote_ctrl_dev;
+	u16 *keycode = idev->keycode;
 
 
 	if (code >= 0x0300 && code <= 0x031f)
 	if (code >= 0x0300 && code <= 0x031f)
 		code = keycode[code - 0x0300];
 		code = keycode[code - 0x0300];
@@ -188,6 +189,8 @@ void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
 		return;
 		return;
 	}
 	}
 
 
-	input_report_key(fdtv->remote_ctrl_dev, code, 1);
-	input_report_key(fdtv->remote_ctrl_dev, code, 0);
+	input_report_key(idev, code, 1);
+	input_sync(idev);
+	input_report_key(idev, code, 0);
+	input_sync(idev);
 }
 }

+ 2 - 2
drivers/media/dvb/frontends/af9013.c

@@ -334,11 +334,11 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw)
 				if_sample_freq = 3300000; /* 3.3 MHz */
 				if_sample_freq = 3300000; /* 3.3 MHz */
 				break;
 				break;
 			case BANDWIDTH_7_MHZ:
 			case BANDWIDTH_7_MHZ:
-				if_sample_freq = 3800000; /* 3.8 MHz */
+				if_sample_freq = 3500000; /* 3.5 MHz */
 				break;
 				break;
 			case BANDWIDTH_8_MHZ:
 			case BANDWIDTH_8_MHZ:
 			default:
 			default:
-				if_sample_freq = 4300000; /* 4.3 MHz */
+				if_sample_freq = 4000000; /* 4.0 MHz */
 				break;
 				break;
 			}
 			}
 		} else if (state->config.tuner == AF9013_TUNER_TDA18218) {
 		} else if (state->config.tuner == AF9013_TUNER_TDA18218) {

+ 1 - 1
drivers/media/dvb/frontends/ix2505v.c

@@ -311,7 +311,7 @@ struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
 	return fe;
 	return fe;
 
 
 error:
 error:
-	ix2505v_release(fe);
+	kfree(state);
 	return NULL;
 	return NULL;
 }
 }
 EXPORT_SYMBOL(ix2505v_attach);
 EXPORT_SYMBOL(ix2505v_attach);

+ 30 - 6
drivers/media/dvb/frontends/mb86a20s.c

@@ -43,6 +43,8 @@ struct mb86a20s_state {
 	const struct mb86a20s_config *config;
 	const struct mb86a20s_config *config;
 
 
 	struct dvb_frontend frontend;
 	struct dvb_frontend frontend;
+
+	bool need_init;
 };
 };
 
 
 struct regdata {
 struct regdata {
@@ -318,7 +320,7 @@ static int mb86a20s_i2c_writereg(struct mb86a20s_state *state,
 
 
 	rc = i2c_transfer(state->i2c, &msg, 1);
 	rc = i2c_transfer(state->i2c, &msg, 1);
 	if (rc != 1) {
 	if (rc != 1) {
-		printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
+		printk("%s: writereg error (rc == %i, reg == 0x%02x,"
 			 " data == 0x%02x)\n", __func__, rc, reg, data);
 			 " data == 0x%02x)\n", __func__, rc, reg, data);
 		return rc;
 		return rc;
 	}
 	}
@@ -353,7 +355,7 @@ static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
 	rc = i2c_transfer(state->i2c, msg, 2);
 	rc = i2c_transfer(state->i2c, msg, 2);
 
 
 	if (rc != 2) {
 	if (rc != 2) {
-		rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
+		rc("%s: reg=0x%x (error=%d)\n", __func__, reg, rc);
 		return rc;
 		return rc;
 	}
 	}
 
 
@@ -382,23 +384,31 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
 	/* Initialize the frontend */
 	/* Initialize the frontend */
 	rc = mb86a20s_writeregdata(state, mb86a20s_init);
 	rc = mb86a20s_writeregdata(state, mb86a20s_init);
 	if (rc < 0)
 	if (rc < 0)
-		return rc;
+		goto err;
 
 
 	if (!state->config->is_serial) {
 	if (!state->config->is_serial) {
 		regD5 &= ~1;
 		regD5 &= ~1;
 
 
 		rc = mb86a20s_writereg(state, 0x50, 0xd5);
 		rc = mb86a20s_writereg(state, 0x50, 0xd5);
 		if (rc < 0)
 		if (rc < 0)
-			return rc;
+			goto err;
 		rc = mb86a20s_writereg(state, 0x51, regD5);
 		rc = mb86a20s_writereg(state, 0x51, regD5);
 		if (rc < 0)
 		if (rc < 0)
-			return rc;
+			goto err;
 	}
 	}
 
 
 	if (fe->ops.i2c_gate_ctrl)
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 		fe->ops.i2c_gate_ctrl(fe, 1);
 
 
-	return 0;
+err:
+	if (rc < 0) {
+		state->need_init = true;
+		printk(KERN_INFO "mb86a20s: Init failed. Will try again later\n");
+	} else {
+		state->need_init = false;
+		dprintk("Initialization succeded.\n");
+	}
+	return rc;
 }
 }
 
 
 static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
@@ -485,8 +495,22 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe,
 
 
 	if (fe->ops.i2c_gate_ctrl)
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 		fe->ops.i2c_gate_ctrl(fe, 1);
+	dprintk("Calling tuner set parameters\n");
 	fe->ops.tuner_ops.set_params(fe, p);
 	fe->ops.tuner_ops.set_params(fe, p);
 
 
+	/*
+	 * Make it more reliable: if, for some reason, the initial
+	 * device initialization doesn't happen, initialize it when
+	 * a SBTVD parameters are adjusted.
+	 *
+	 * Unfortunately, due to a hard to track bug at tda829x/tda18271,
+	 * the agc callback logic is not called during DVB attach time,
+	 * causing mb86a20s to not be initialized with Kworld SBTVD.
+	 * So, this hack is needed, in order to make Kworld SBTVD to work.
+	 */
+	if (state->need_init)
+		mb86a20s_initfe(fe);
+
 	if (fe->ops.i2c_gate_ctrl)
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 		fe->ops.i2c_gate_ctrl(fe, 0);
 	rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
 	rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);

+ 1 - 1
drivers/media/dvb/ttpci/av7110_ca.c

@@ -277,7 +277,7 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg)
 	{
 	{
 		ca_slot_info_t *info=(ca_slot_info_t *)parg;
 		ca_slot_info_t *info=(ca_slot_info_t *)parg;
 
 
-		if (info->num > 1)
+		if (info->num < 0 || info->num > 1)
 			return -EINVAL;
 			return -EINVAL;
 		av7110->ci_slot[info->num].num = info->num;
 		av7110->ci_slot[info->num].num = info->num;
 		av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
 		av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?

+ 0 - 14
drivers/media/radio/Kconfig

@@ -151,20 +151,6 @@ config RADIO_GEMTEK_PROBE
 	  following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and
 	  following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and
 	  0x28c.
 	  0x28c.
 
 
-config RADIO_GEMTEK_PCI
-	tristate "GemTek PCI Radio Card support"
-	depends on VIDEO_V4L2 && PCI
-	---help---
-	  Choose Y here if you have this PCI FM radio card.
-
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video for Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called radio-gemtek-pci.
-
 config RADIO_MAXIRADIO
 config RADIO_MAXIRADIO
 	tristate "Guillemot MAXI Radio FM 2000 radio"
 	tristate "Guillemot MAXI Radio FM 2000 radio"
 	depends on VIDEO_V4L2 && PCI
 	depends on VIDEO_V4L2 && PCI

+ 0 - 1
drivers/media/radio/Makefile

@@ -13,7 +13,6 @@ obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o
 obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
 obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
 obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
 obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
 obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
 obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
-obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
 obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
 obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
 obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
 obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
 obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
 obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o

+ 1 - 0
drivers/media/radio/radio-aimslab.c

@@ -31,6 +31,7 @@
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/ioport.h>	/* request_region		*/
+#include <linux/delay.h>	/* msleep			*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
 #include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
 #include <linux/version.h>	/* for KERNEL_VERSION MACRO	*/
 #include <linux/io.h>		/* outb, outb_p			*/
 #include <linux/io.h>		/* outb, outb_p			*/

+ 0 - 478
drivers/media/radio/radio-gemtek-pci.c

@@ -1,478 +0,0 @@
-/*
- ***************************************************************************
- *
- *     radio-gemtek-pci.c - Gemtek PCI Radio driver
- *     (C) 2001 Vladimir Shebordaev <vshebordaev@mail.ru>
- *
- ***************************************************************************
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public
- *     License along with this program; if not, write to the Free
- *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- *     USA.
- *
- ***************************************************************************
- *
- *     Gemtek Corp still silently refuses to release any specifications
- *     of their multimedia devices, so the protocol still has to be
- *     reverse engineered.
- *
- *     The v4l code was inspired by Jonas Munsin's  Gemtek serial line
- *     radio device driver.
- *
- *     Please, let me know if this piece of code was useful :)
- *
- *     TODO: multiple device support and portability were not tested
- *
- *     Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- ***************************************************************************
- */
-
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/videodev2.h>
-#include <linux/errno.h>
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-
-MODULE_AUTHOR("Vladimir Shebordaev <vshebordaev@mail.ru>");
-MODULE_DESCRIPTION("The video4linux driver for the Gemtek PCI Radio Card");
-MODULE_LICENSE("GPL");
-
-static int nr_radio = -1;
-static int mx = 1;
-
-module_param(mx, bool, 0);
-MODULE_PARM_DESC(mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not");
-module_param(nr_radio, int, 0);
-MODULE_PARM_DESC(nr_radio, "video4linux device number to use");
-
-#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
-
-#ifndef PCI_VENDOR_ID_GEMTEK
-#define PCI_VENDOR_ID_GEMTEK 0x5046
-#endif
-
-#ifndef PCI_DEVICE_ID_GEMTEK_PR103
-#define PCI_DEVICE_ID_GEMTEK_PR103 0x1001
-#endif
-
-#ifndef GEMTEK_PCI_RANGE_LOW
-#define GEMTEK_PCI_RANGE_LOW (87*16000)
-#endif
-
-#ifndef GEMTEK_PCI_RANGE_HIGH
-#define GEMTEK_PCI_RANGE_HIGH (108*16000)
-#endif
-
-struct gemtek_pci {
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	struct mutex lock;
-	struct pci_dev *pdev;
-
-	u32 iobase;
-	u32 length;
-
-	u32 current_frequency;
-	u8  mute;
-};
-
-static inline struct gemtek_pci *to_gemtek_pci(struct v4l2_device *v4l2_dev)
-{
-	return container_of(v4l2_dev, struct gemtek_pci, v4l2_dev);
-}
-
-static inline u8 gemtek_pci_out(u16 value, u32 port)
-{
-	outw(value, port);
-
-	return (u8)value;
-}
-
-#define _b0(v) (*((u8 *)&v))
-
-static void __gemtek_pci_cmd(u16 value, u32 port, u8 *last_byte, int keep)
-{
-	u8 byte = *last_byte;
-
-	if (!value) {
-		if (!keep)
-			value = (u16)port;
-		byte &= 0xfd;
-	} else
-		byte |= 2;
-
-	_b0(value) = byte;
-	outw(value, port);
-	byte |= 1;
-	_b0(value) = byte;
-	outw(value, port);
-	byte &= 0xfe;
-	_b0(value) = byte;
-	outw(value, port);
-
-	*last_byte = byte;
-}
-
-static inline void gemtek_pci_nil(u32 port, u8 *last_byte)
-{
-	__gemtek_pci_cmd(0x00, port, last_byte, false);
-}
-
-static inline void gemtek_pci_cmd(u16 cmd, u32 port, u8 *last_byte)
-{
-	__gemtek_pci_cmd(cmd, port, last_byte, true);
-}
-
-static void gemtek_pci_setfrequency(struct gemtek_pci *card, unsigned long frequency)
-{
-	int i;
-	u32 value = frequency / 200 + 856;
-	u16 mask = 0x8000;
-	u8 last_byte;
-	u32 port = card->iobase;
-
-	mutex_lock(&card->lock);
-	card->current_frequency = frequency;
-	last_byte = gemtek_pci_out(0x06, port);
-
-	i = 0;
-	do {
-		gemtek_pci_nil(port, &last_byte);
-		i++;
-	} while (i < 9);
-
-	i = 0;
-	do {
-		gemtek_pci_cmd(value & mask, port, &last_byte);
-		mask >>= 1;
-		i++;
-	} while (i < 16);
-
-	outw(0x10, port);
-	mutex_unlock(&card->lock);
-}
-
-
-static void gemtek_pci_mute(struct gemtek_pci *card)
-{
-	mutex_lock(&card->lock);
-	outb(0x1f, card->iobase);
-	card->mute = true;
-	mutex_unlock(&card->lock);
-}
-
-static void gemtek_pci_unmute(struct gemtek_pci *card)
-{
-	if (card->mute) {
-		gemtek_pci_setfrequency(card, card->current_frequency);
-		card->mute = false;
-	}
-}
-
-static int gemtek_pci_getsignal(struct gemtek_pci *card)
-{
-	int sig;
-
-	mutex_lock(&card->lock);
-	sig = (inb(card->iobase) & 0x08) ? 0 : 1;
-	mutex_unlock(&card->lock);
-	return sig;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
-					struct v4l2_capability *v)
-{
-	struct gemtek_pci *card = video_drvdata(file);
-
-	strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));
-	strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card));
-	snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(card->pdev));
-	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	struct gemtek_pci *card = video_drvdata(file);
-
-	if (v->index > 0)
-		return -EINVAL;
-
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = GEMTEK_PCI_RANGE_LOW;
-	v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO;
-	v->capability = V4L2_TUNER_CAP_LOW;
-	v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xffff * gemtek_pci_getsignal(card);
-	return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	return v->index ? -EINVAL : 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct gemtek_pci *card = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	if (f->frequency < GEMTEK_PCI_RANGE_LOW ||
-	    f->frequency > GEMTEK_PCI_RANGE_HIGH)
-		return -EINVAL;
-	gemtek_pci_setfrequency(card, f->frequency);
-	card->mute = false;
-	return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct gemtek_pci *card = video_drvdata(file);
-
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = card->current_frequency;
-	return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
-					struct v4l2_queryctrl *qc)
-{
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	case V4L2_CID_AUDIO_VOLUME:
-		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct gemtek_pci *card = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = card->mute;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		if (card->mute)
-			ctrl->value = 0;
-		else
-			ctrl->value = 65535;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct gemtek_pci *card = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			gemtek_pci_mute(card);
-		else
-			gemtek_pci_unmute(card);
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		if (ctrl->value)
-			gemtek_pci_unmute(card);
-		else
-			gemtek_pci_mute(card);
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
-
-enum {
-	GEMTEK_PR103
-};
-
-static char *card_names[] __devinitdata = {
-	"GEMTEK_PR103"
-};
-
-static struct pci_device_id gemtek_pci_id[] =
-{
-	{ PCI_VENDOR_ID_GEMTEK, PCI_DEVICE_ID_GEMTEK_PR103,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, GEMTEK_PR103 },
-	{ 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
-
-static const struct v4l2_file_operations gemtek_pci_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
-};
-
-static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
-{
-	struct gemtek_pci *card;
-	struct v4l2_device *v4l2_dev;
-	int res;
-
-	card = kzalloc(sizeof(struct gemtek_pci), GFP_KERNEL);
-	if (card == NULL) {
-		dev_err(&pdev->dev, "out of memory\n");
-		return -ENOMEM;
-	}
-
-	v4l2_dev = &card->v4l2_dev;
-	mutex_init(&card->lock);
-	card->pdev = pdev;
-
-	strlcpy(v4l2_dev->name, "gemtek_pci", sizeof(v4l2_dev->name));
-
-	res = v4l2_device_register(&pdev->dev, v4l2_dev);
-	if (res < 0) {
-		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
-		kfree(card);
-		return res;
-	}
-
-	if (pci_enable_device(pdev))
-		goto err_pci;
-
-	card->iobase = pci_resource_start(pdev, 0);
-	card->length = pci_resource_len(pdev, 0);
-
-	if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) {
-		v4l2_err(v4l2_dev, "i/o port already in use\n");
-		goto err_pci;
-	}
-
-	strlcpy(card->vdev.name, v4l2_dev->name, sizeof(card->vdev.name));
-	card->vdev.v4l2_dev = v4l2_dev;
-	card->vdev.fops = &gemtek_pci_fops;
-	card->vdev.ioctl_ops = &gemtek_pci_ioctl_ops;
-	card->vdev.release = video_device_release_empty;
-	video_set_drvdata(&card->vdev, card);
-
-	gemtek_pci_mute(card);
-
-	if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)
-		goto err_video;
-
-	v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
-		pdev->revision, card->iobase, card->iobase + card->length - 1);
-
-	return 0;
-
-err_video:
-	release_region(card->iobase, card->length);
-
-err_pci:
-	v4l2_device_unregister(v4l2_dev);
-	kfree(card);
-	return -ENODEV;
-}
-
-static void __devexit gemtek_pci_remove(struct pci_dev *pdev)
-{
-	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
-	struct gemtek_pci *card = to_gemtek_pci(v4l2_dev);
-
-	video_unregister_device(&card->vdev);
-	v4l2_device_unregister(v4l2_dev);
-
-	release_region(card->iobase, card->length);
-
-	if (mx)
-		gemtek_pci_mute(card);
-
-	kfree(card);
-}
-
-static struct pci_driver gemtek_pci_driver = {
-	.name		= "gemtek_pci",
-	.id_table	= gemtek_pci_id,
-	.probe		= gemtek_pci_probe,
-	.remove		= __devexit_p(gemtek_pci_remove),
-};
-
-static int __init gemtek_pci_init(void)
-{
-	return pci_register_driver(&gemtek_pci_driver);
-}
-
-static void __exit gemtek_pci_exit(void)
-{
-	pci_unregister_driver(&gemtek_pci_driver);
-}
-
-module_init(gemtek_pci_init);
-module_exit(gemtek_pci_exit);

+ 2 - 2
drivers/media/radio/radio-maxiradio.c

@@ -77,8 +77,8 @@ MODULE_PARM_DESC(debug, "activates debug info");
 /* TEA5757 pin mappings */
 /* TEA5757 pin mappings */
 static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16;
 static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16;
 
 
-#define FREQ_LO		(50 * 16000)
-#define FREQ_HI		(150 * 16000)
+#define FREQ_LO		(87 * 16000)
+#define FREQ_HI		(108 * 16000)
 
 
 #define FREQ_IF         171200 /* 10.7*16000   */
 #define FREQ_IF         171200 /* 10.7*16000   */
 #define FREQ_STEP       200    /* 12.5*16      */
 #define FREQ_STEP       200    /* 12.5*16      */

+ 1 - 1
drivers/media/radio/radio-wl1273.c

@@ -1407,7 +1407,7 @@ static const struct v4l2_file_operations wl1273_fops = {
 	.read		= wl1273_fm_fops_read,
 	.read		= wl1273_fm_fops_read,
 	.write		= wl1273_fm_fops_write,
 	.write		= wl1273_fm_fops_write,
 	.poll		= wl1273_fm_fops_poll,
 	.poll		= wl1273_fm_fops_poll,
-	.ioctl		= video_ioctl2,
+	.unlocked_ioctl	= video_ioctl2,
 	.open		= wl1273_fm_fops_open,
 	.open		= wl1273_fm_fops_open,
 	.release	= wl1273_fm_fops_release,
 	.release	= wl1273_fm_fops_release,
 };
 };

+ 2 - 7
drivers/media/radio/si470x/radio-si470x-common.c

@@ -357,7 +357,8 @@ int si470x_start(struct si470x_device *radio)
 		goto done;
 		goto done;
 
 
 	/* sysconfig 1 */
 	/* sysconfig 1 */
-	radio->registers[SYSCONFIG1] = SYSCONFIG1_DE;
+	radio->registers[SYSCONFIG1] =
+		(de << 11) & SYSCONFIG1_DE;		/* DE*/
 	retval = si470x_set_register(radio, SYSCONFIG1);
 	retval = si470x_set_register(radio, SYSCONFIG1);
 	if (retval < 0)
 	if (retval < 0)
 		goto done;
 		goto done;
@@ -687,12 +688,8 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
 	/* driver constants */
 	/* driver constants */
 	strcpy(tuner->name, "FM");
 	strcpy(tuner->name, "FM");
 	tuner->type = V4L2_TUNER_RADIO;
 	tuner->type = V4L2_TUNER_RADIO;
-#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
 	tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
 	tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
 			    V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO;
 			    V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO;
-#else
-	tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
-#endif
 
 
 	/* range limits */
 	/* range limits */
 	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
 	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
@@ -718,12 +715,10 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
 		tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
 		tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
 	else
 	else
 		tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
 		tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
 	/* If there is a reliable method of detecting an RDS channel,
 	/* If there is a reliable method of detecting an RDS channel,
 	   then this code should check for that before setting this
 	   then this code should check for that before setting this
 	   RDS subchannel. */
 	   RDS subchannel. */
 	tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;
 	tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;
-#endif
 
 
 	/* mono/stereo selector */
 	/* mono/stereo selector */
 	if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)
 	if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)

+ 14 - 9
drivers/media/rc/ene_ir.c

@@ -446,27 +446,27 @@ static void ene_rx_setup(struct ene_device *dev)
 
 
 select_timeout:
 select_timeout:
 	if (dev->rx_fan_input_inuse) {
 	if (dev->rx_fan_input_inuse) {
-		dev->rdev->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
+		dev->rdev->rx_resolution = US_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
 
 
 		/* Fan input doesn't support timeouts, it just ends the
 		/* Fan input doesn't support timeouts, it just ends the
 			input with a maximum sample */
 			input with a maximum sample */
 		dev->rdev->min_timeout = dev->rdev->max_timeout =
 		dev->rdev->min_timeout = dev->rdev->max_timeout =
-			MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
+			US_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
 				ENE_FW_SAMPLE_PERIOD_FAN);
 				ENE_FW_SAMPLE_PERIOD_FAN);
 	} else {
 	} else {
-		dev->rdev->rx_resolution = MS_TO_NS(sample_period);
+		dev->rdev->rx_resolution = US_TO_NS(sample_period);
 
 
 		/* Theoreticly timeout is unlimited, but we cap it
 		/* Theoreticly timeout is unlimited, but we cap it
 		 * because it was seen that on one device, it
 		 * because it was seen that on one device, it
 		 * would stop sending spaces after around 250 msec.
 		 * would stop sending spaces after around 250 msec.
 		 * Besides, this is close to 2^32 anyway and timeout is u32.
 		 * Besides, this is close to 2^32 anyway and timeout is u32.
 		 */
 		 */
-		dev->rdev->min_timeout = MS_TO_NS(127 * sample_period);
-		dev->rdev->max_timeout = MS_TO_NS(200000);
+		dev->rdev->min_timeout = US_TO_NS(127 * sample_period);
+		dev->rdev->max_timeout = US_TO_NS(200000);
 	}
 	}
 
 
 	if (dev->hw_learning_and_tx_capable)
 	if (dev->hw_learning_and_tx_capable)
-		dev->rdev->tx_resolution = MS_TO_NS(sample_period);
+		dev->rdev->tx_resolution = US_TO_NS(sample_period);
 
 
 	if (dev->rdev->timeout > dev->rdev->max_timeout)
 	if (dev->rdev->timeout > dev->rdev->max_timeout)
 		dev->rdev->timeout = dev->rdev->max_timeout;
 		dev->rdev->timeout = dev->rdev->max_timeout;
@@ -801,7 +801,7 @@ static irqreturn_t ene_isr(int irq, void *data)
 
 
 		dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space");
 		dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space");
 
 
-		ev.duration = MS_TO_NS(hw_sample);
+		ev.duration = US_TO_NS(hw_sample);
 		ev.pulse = pulse;
 		ev.pulse = pulse;
 		ir_raw_event_store_with_filter(dev->rdev, &ev);
 		ir_raw_event_store_with_filter(dev->rdev, &ev);
 	}
 	}
@@ -821,7 +821,7 @@ static void ene_setup_default_settings(struct ene_device *dev)
 	dev->learning_mode_enabled = learning_mode_force;
 	dev->learning_mode_enabled = learning_mode_force;
 
 
 	/* Set reasonable default timeout */
 	/* Set reasonable default timeout */
-	dev->rdev->timeout = MS_TO_NS(150000);
+	dev->rdev->timeout = US_TO_NS(150000);
 }
 }
 
 
 /* Upload all hardware settings at once. Used at load and resume time */
 /* Upload all hardware settings at once. Used at load and resume time */
@@ -1004,6 +1004,10 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
 	/* validate resources */
 	/* validate resources */
 	error = -ENODEV;
 	error = -ENODEV;
 
 
+	/* init these to -1, as 0 is valid for both */
+	dev->hw_io = -1;
+	dev->irq = -1;
+
 	if (!pnp_port_valid(pnp_dev, 0) ||
 	if (!pnp_port_valid(pnp_dev, 0) ||
 	    pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE)
 	    pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE)
 		goto error;
 		goto error;
@@ -1072,6 +1076,8 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
 		rdev->input_name = "ENE eHome Infrared Remote Transceiver";
 		rdev->input_name = "ENE eHome Infrared Remote Transceiver";
 	}
 	}
 
 
+	dev->rdev = rdev;
+
 	ene_rx_setup_hw_buffer(dev);
 	ene_rx_setup_hw_buffer(dev);
 	ene_setup_default_settings(dev);
 	ene_setup_default_settings(dev);
 	ene_setup_hw_settings(dev);
 	ene_setup_hw_settings(dev);
@@ -1083,7 +1089,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
 	if (error < 0)
 	if (error < 0)
 		goto error;
 		goto error;
 
 
-	dev->rdev = rdev;
 	ene_notice("driver has been succesfully loaded");
 	ene_notice("driver has been succesfully loaded");
 	return 0;
 	return 0;
 error:
 error:

+ 0 - 2
drivers/media/rc/ene_ir.h

@@ -201,8 +201,6 @@
 #define dbg_verbose(format, ...)	__dbg(2, format, ## __VA_ARGS__)
 #define dbg_verbose(format, ...)	__dbg(2, format, ## __VA_ARGS__)
 #define dbg_regs(format, ...)		__dbg(3, format, ## __VA_ARGS__)
 #define dbg_regs(format, ...)		__dbg(3, format, ## __VA_ARGS__)
 
 
-#define MS_TO_NS(msec) ((msec) * 1000)
-
 struct ene_device {
 struct ene_device {
 	struct pnp_dev *pnp_dev;
 	struct pnp_dev *pnp_dev;
 	struct rc_dev *rdev;
 	struct rc_dev *rdev;

+ 26 - 34
drivers/media/rc/imon.c

@@ -988,7 +988,6 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
 	int retval;
 	int retval;
 	struct imon_context *ictx = rc->priv;
 	struct imon_context *ictx = rc->priv;
 	struct device *dev = ictx->dev;
 	struct device *dev = ictx->dev;
-	bool pad_mouse;
 	unsigned char ir_proto_packet[] = {
 	unsigned char ir_proto_packet[] = {
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
 
 
@@ -1000,29 +999,20 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
 	case RC_TYPE_RC6:
 	case RC_TYPE_RC6:
 		dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
 		dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
 		ir_proto_packet[0] = 0x01;
 		ir_proto_packet[0] = 0x01;
-		pad_mouse = false;
 		break;
 		break;
 	case RC_TYPE_UNKNOWN:
 	case RC_TYPE_UNKNOWN:
 	case RC_TYPE_OTHER:
 	case RC_TYPE_OTHER:
 		dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
 		dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
-		if (pad_stabilize && !nomouse)
-			pad_mouse = true;
-		else {
+		if (!pad_stabilize)
 			dev_dbg(dev, "PAD stabilize functionality disabled\n");
 			dev_dbg(dev, "PAD stabilize functionality disabled\n");
-			pad_mouse = false;
-		}
 		/* ir_proto_packet[0] = 0x00; // already the default */
 		/* ir_proto_packet[0] = 0x00; // already the default */
 		rc_type = RC_TYPE_OTHER;
 		rc_type = RC_TYPE_OTHER;
 		break;
 		break;
 	default:
 	default:
 		dev_warn(dev, "Unsupported IR protocol specified, overriding "
 		dev_warn(dev, "Unsupported IR protocol specified, overriding "
 			 "to iMON IR protocol\n");
 			 "to iMON IR protocol\n");
-		if (pad_stabilize && !nomouse)
-			pad_mouse = true;
-		else {
+		if (!pad_stabilize)
 			dev_dbg(dev, "PAD stabilize functionality disabled\n");
 			dev_dbg(dev, "PAD stabilize functionality disabled\n");
-			pad_mouse = false;
-		}
 		/* ir_proto_packet[0] = 0x00; // already the default */
 		/* ir_proto_packet[0] = 0x00; // already the default */
 		rc_type = RC_TYPE_OTHER;
 		rc_type = RC_TYPE_OTHER;
 		break;
 		break;
@@ -1035,7 +1025,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
 		goto out;
 		goto out;
 
 
 	ictx->rc_type = rc_type;
 	ictx->rc_type = rc_type;
-	ictx->pad_mouse = pad_mouse;
+	ictx->pad_mouse = false;
 
 
 out:
 out:
 	return retval;
 	return retval;
@@ -1517,7 +1507,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
 			spin_unlock_irqrestore(&ictx->kc_lock, flags);
 			spin_unlock_irqrestore(&ictx->kc_lock, flags);
 			return;
 			return;
 		} else {
 		} else {
-			ictx->pad_mouse = 0;
+			ictx->pad_mouse = false;
 			dev_dbg(dev, "mouse mode disabled, passing key value\n");
 			dev_dbg(dev, "mouse mode disabled, passing key value\n");
 		}
 		}
 	}
 	}
@@ -1756,7 +1746,6 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
 	printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
 	printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
 
 
 	ictx->display_type = detected_display_type;
 	ictx->display_type = detected_display_type;
-	ictx->rdev->allowed_protos = allowed_protos;
 	ictx->rc_type = allowed_protos;
 	ictx->rc_type = allowed_protos;
 }
 }
 
 
@@ -1839,10 +1828,6 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
 	rdev->allowed_protos = RC_TYPE_OTHER | RC_TYPE_RC6; /* iMON PAD or MCE */
 	rdev->allowed_protos = RC_TYPE_OTHER | RC_TYPE_RC6; /* iMON PAD or MCE */
 	rdev->change_protocol = imon_ir_change_protocol;
 	rdev->change_protocol = imon_ir_change_protocol;
 	rdev->driver_name = MOD_NAME;
 	rdev->driver_name = MOD_NAME;
-	if (ictx->rc_type == RC_TYPE_RC6)
-		rdev->map_name = RC_MAP_IMON_MCE;
-	else
-		rdev->map_name = RC_MAP_IMON_PAD;
 
 
 	/* Enable front-panel buttons and/or knobs */
 	/* Enable front-panel buttons and/or knobs */
 	memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
 	memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
@@ -1851,11 +1836,18 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
 	if (ret)
 	if (ret)
 		dev_info(ictx->dev, "panel buttons/knobs setup failed\n");
 		dev_info(ictx->dev, "panel buttons/knobs setup failed\n");
 
 
-	if (ictx->product == 0xffdc)
+	if (ictx->product == 0xffdc) {
 		imon_get_ffdc_type(ictx);
 		imon_get_ffdc_type(ictx);
+		rdev->allowed_protos = ictx->rc_type;
+	}
 
 
 	imon_set_display_type(ictx);
 	imon_set_display_type(ictx);
 
 
+	if (ictx->rc_type == RC_TYPE_RC6)
+		rdev->map_name = RC_MAP_IMON_MCE;
+	else
+		rdev->map_name = RC_MAP_IMON_PAD;
+
 	ret = rc_register_device(rdev);
 	ret = rc_register_device(rdev);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(ictx->dev, "remote input dev register failed\n");
 		dev_err(ictx->dev, "remote input dev register failed\n");
@@ -2108,18 +2100,6 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
 		goto find_endpoint_failed;
 		goto find_endpoint_failed;
 	}
 	}
 
 
-	ictx->idev = imon_init_idev(ictx);
-	if (!ictx->idev) {
-		dev_err(dev, "%s: input device setup failed\n", __func__);
-		goto idev_setup_failed;
-	}
-
-	ictx->rdev = imon_init_rdev(ictx);
-	if (!ictx->rdev) {
-		dev_err(dev, "%s: rc device setup failed\n", __func__);
-		goto rdev_setup_failed;
-	}
-
 	usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
 	usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
 		usb_rcvintpipe(ictx->usbdev_intf0,
 		usb_rcvintpipe(ictx->usbdev_intf0,
 			ictx->rx_endpoint_intf0->bEndpointAddress),
 			ictx->rx_endpoint_intf0->bEndpointAddress),
@@ -2133,13 +2113,25 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
 		goto urb_submit_failed;
 		goto urb_submit_failed;
 	}
 	}
 
 
+	ictx->idev = imon_init_idev(ictx);
+	if (!ictx->idev) {
+		dev_err(dev, "%s: input device setup failed\n", __func__);
+		goto idev_setup_failed;
+	}
+
+	ictx->rdev = imon_init_rdev(ictx);
+	if (!ictx->rdev) {
+		dev_err(dev, "%s: rc device setup failed\n", __func__);
+		goto rdev_setup_failed;
+	}
+
 	return ictx;
 	return ictx;
 
 
-urb_submit_failed:
-	rc_unregister_device(ictx->rdev);
 rdev_setup_failed:
 rdev_setup_failed:
 	input_unregister_device(ictx->idev);
 	input_unregister_device(ictx->idev);
 idev_setup_failed:
 idev_setup_failed:
+	usb_kill_urb(ictx->rx_urb_intf0);
+urb_submit_failed:
 find_endpoint_failed:
 find_endpoint_failed:
 	mutex_unlock(&ictx->lock);
 	mutex_unlock(&ictx->lock);
 	usb_free_urb(tx_urb);
 	usb_free_urb(tx_urb);

+ 1 - 1
drivers/media/rc/ir-raw.c

@@ -233,7 +233,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_handle);
 
 
 /* used internally by the sysfs interface */
 /* used internally by the sysfs interface */
 u64
 u64
-ir_raw_get_allowed_protocols()
+ir_raw_get_allowed_protocols(void)
 {
 {
 	u64 protocols;
 	u64 protocols;
 	mutex_lock(&ir_raw_handler_lock);
 	mutex_lock(&ir_raw_handler_lock);

+ 26 - 26
drivers/media/rc/keymaps/rc-dib0700-nec.c

@@ -19,35 +19,35 @@
 
 
 static struct rc_map_table dib0700_nec_table[] = {
 static struct rc_map_table dib0700_nec_table[] = {
 	/* Key codes for the Pixelview SBTVD remote */
 	/* Key codes for the Pixelview SBTVD remote */
-	{ 0x8613, KEY_MUTE },
-	{ 0x8612, KEY_POWER },
-	{ 0x8601, KEY_1 },
-	{ 0x8602, KEY_2 },
-	{ 0x8603, KEY_3 },
-	{ 0x8604, KEY_4 },
-	{ 0x8605, KEY_5 },
-	{ 0x8606, KEY_6 },
-	{ 0x8607, KEY_7 },
-	{ 0x8608, KEY_8 },
-	{ 0x8609, KEY_9 },
-	{ 0x8600, KEY_0 },
-	{ 0x860d, KEY_CHANNELUP },
-	{ 0x8619, KEY_CHANNELDOWN },
-	{ 0x8610, KEY_VOLUMEUP },
-	{ 0x860c, KEY_VOLUMEDOWN },
+	{ 0x866b13, KEY_MUTE },
+	{ 0x866b12, KEY_POWER },
+	{ 0x866b01, KEY_1 },
+	{ 0x866b02, KEY_2 },
+	{ 0x866b03, KEY_3 },
+	{ 0x866b04, KEY_4 },
+	{ 0x866b05, KEY_5 },
+	{ 0x866b06, KEY_6 },
+	{ 0x866b07, KEY_7 },
+	{ 0x866b08, KEY_8 },
+	{ 0x866b09, KEY_9 },
+	{ 0x866b00, KEY_0 },
+	{ 0x866b0d, KEY_CHANNELUP },
+	{ 0x866b19, KEY_CHANNELDOWN },
+	{ 0x866b10, KEY_VOLUMEUP },
+	{ 0x866b0c, KEY_VOLUMEDOWN },
 
 
-	{ 0x860a, KEY_CAMERA },
-	{ 0x860b, KEY_ZOOM },
-	{ 0x861b, KEY_BACKSPACE },
-	{ 0x8615, KEY_ENTER },
+	{ 0x866b0a, KEY_CAMERA },
+	{ 0x866b0b, KEY_ZOOM },
+	{ 0x866b1b, KEY_BACKSPACE },
+	{ 0x866b15, KEY_ENTER },
 
 
-	{ 0x861d, KEY_UP },
-	{ 0x861e, KEY_DOWN },
-	{ 0x860e, KEY_LEFT },
-	{ 0x860f, KEY_RIGHT },
+	{ 0x866b1d, KEY_UP },
+	{ 0x866b1e, KEY_DOWN },
+	{ 0x866b0e, KEY_LEFT },
+	{ 0x866b0f, KEY_RIGHT },
 
 
-	{ 0x8618, KEY_RECORD },
-	{ 0x861a, KEY_STOP },
+	{ 0x866b18, KEY_RECORD },
+	{ 0x866b1a, KEY_STOP },
 
 
 	/* Key codes for the EvolutePC TVWay+ remote */
 	/* Key codes for the EvolutePC TVWay+ remote */
 	{ 0x7a00, KEY_MENU },
 	{ 0x7a00, KEY_MENU },

+ 1 - 2
drivers/media/rc/mceusb.c

@@ -48,7 +48,6 @@
 #define USB_BUFLEN		32 /* USB reception buffer length */
 #define USB_BUFLEN		32 /* USB reception buffer length */
 #define USB_CTRL_MSG_SZ		2  /* Size of usb ctrl msg on gen1 hw */
 #define USB_CTRL_MSG_SZ		2  /* Size of usb ctrl msg on gen1 hw */
 #define MCE_G1_INIT_MSGS	40 /* Init messages on gen1 hw to throw out */
 #define MCE_G1_INIT_MSGS	40 /* Init messages on gen1 hw to throw out */
-#define MS_TO_NS(msec)		((msec) * 1000)
 
 
 /* MCE constants */
 /* MCE constants */
 #define MCE_CMDBUF_SIZE		384  /* MCE Command buffer length */
 #define MCE_CMDBUF_SIZE		384  /* MCE Command buffer length */
@@ -858,7 +857,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
 			ir->rem--;
 			ir->rem--;
 			rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
 			rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
 			rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
 			rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
-					 * MS_TO_NS(MCE_TIME_UNIT);
+					 * MS_TO_US(MCE_TIME_UNIT);
 
 
 			dev_dbg(ir->dev, "Storing %s with duration %d\n",
 			dev_dbg(ir->dev, "Storing %s with duration %d\n",
 				rawir.pulse ? "pulse" : "space",
 				rawir.pulse ? "pulse" : "space",

+ 0 - 9
drivers/media/video/Kconfig

@@ -141,15 +141,6 @@ config VIDEO_TDA9840
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called tda9840.
 	  module will be called tda9840.
 
 
-config VIDEO_TDA9875
-	tristate "Philips TDA9875 audio processor"
-	depends on VIDEO_V4L2 && I2C
-	---help---
-	  Support for tda9875 audio decoder chip found on some bt8xx boards.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called tda9875.
-
 config VIDEO_TEA6415C
 config VIDEO_TEA6415C
 	tristate "Philips TEA6415C audio processor"
 	tristate "Philips TEA6415C audio processor"
 	depends on I2C
 	depends on I2C

+ 0 - 1
drivers/media/video/Makefile

@@ -27,7 +27,6 @@ obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
 obj-$(CONFIG_VIDEO_TUNER) += tuner.o
 obj-$(CONFIG_VIDEO_TUNER) += tuner.o
 obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
 obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
 obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
 obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
-obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
 obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
 obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
 obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
 obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
 obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
 obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o

+ 11 - 0
drivers/media/video/adv7175.c

@@ -303,11 +303,22 @@ static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
 	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
 	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
 }
 }
 
 
+static int adv7175_s_power(struct v4l2_subdev *sd, int on)
+{
+	if (on)
+		adv7175_write(sd, 0x01, 0x00);
+	else
+		adv7175_write(sd, 0x01, 0x78);
+
+	return 0;
+}
+
 /* ----------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------- */
 
 
 static const struct v4l2_subdev_core_ops adv7175_core_ops = {
 static const struct v4l2_subdev_core_ops adv7175_core_ops = {
 	.g_chip_ident = adv7175_g_chip_ident,
 	.g_chip_ident = adv7175_g_chip_ident,
 	.init = adv7175_init,
 	.init = adv7175_init,
+	.s_power = adv7175_s_power,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops adv7175_video_ops = {
 static const struct v4l2_subdev_video_ops adv7175_video_ops = {

+ 0 - 39
drivers/media/video/bt8xx/bttv-cards.c

@@ -1373,7 +1373,6 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomute 	= 0x1800,
 		.gpiomute 	= 0x1800,
 		.audio_mode_gpio= fv2000s_audio,
 		.audio_mode_gpio= fv2000s_audio,
 		.no_msp34xx	= 1,
 		.no_msp34xx	= 1,
-		.no_tda9875	= 1,
 		.needs_tvaudio  = 1,
 		.needs_tvaudio  = 1,
 		.pll            = PLL_28,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_type     = TUNER_PHILIPS_PAL,
@@ -1511,7 +1510,6 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomute 	= 0x09,
 		.gpiomute 	= 0x09,
 		.needs_tvaudio  = 1,
 		.needs_tvaudio  = 1,
 		.no_msp34xx	= 1,
 		.no_msp34xx	= 1,
-		.no_tda9875	= 1,
 		.pll		= PLL_28,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -1550,7 +1548,6 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask2      = 0x07ff,
 		.gpiomask2      = 0x07ff,
 		.muxsel         = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
 		.muxsel         = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.muxsel_hook    = rv605_muxsel,
 		.muxsel_hook    = rv605_muxsel,
@@ -1686,7 +1683,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 	[BTTV_BOARD_OSPREY1x0_848] = {
 	[BTTV_BOARD_OSPREY1x0_848] = {
@@ -1699,7 +1695,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 
 
@@ -1714,7 +1709,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 	[BTTV_BOARD_OSPREY1x1] = {
 	[BTTV_BOARD_OSPREY1x1] = {
@@ -1727,7 +1721,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 	[BTTV_BOARD_OSPREY1x1_SVID] = {
 	[BTTV_BOARD_OSPREY1x1_SVID] = {
@@ -1740,7 +1733,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 	[BTTV_BOARD_OSPREY2xx] = {
 	[BTTV_BOARD_OSPREY2xx] = {
@@ -1753,7 +1745,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 
 
@@ -1768,7 +1759,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 	[BTTV_BOARD_OSPREY2x0] = {
 	[BTTV_BOARD_OSPREY2x0] = {
@@ -1781,7 +1771,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 	[BTTV_BOARD_OSPREY500] = {
 	[BTTV_BOARD_OSPREY500] = {
@@ -1794,7 +1783,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 	[BTTV_BOARD_OSPREY540] = {
 	[BTTV_BOARD_OSPREY540] = {
@@ -1805,7 +1793,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 
 
@@ -1820,7 +1807,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,      /* must avoid, conflicts with the bt860 */
 		.no_tda7432     = 1,      /* must avoid, conflicts with the bt860 */
 	},
 	},
 	[BTTV_BOARD_IDS_EAGLE] = {
 	[BTTV_BOARD_IDS_EAGLE] = {
@@ -1835,7 +1821,6 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel         = MUXSEL(2, 2, 2, 2),
 		.muxsel         = MUXSEL(2, 2, 2, 2),
 		.muxsel_hook    = eagle_muxsel,
 		.muxsel_hook    = eagle_muxsel,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.pll            = PLL_28,
 		.pll            = PLL_28,
 	},
 	},
 	[BTTV_BOARD_PINNACLESAT] = {
 	[BTTV_BOARD_PINNACLESAT] = {
@@ -1846,7 +1831,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.muxsel         = MUXSEL(3, 1),
 		.muxsel         = MUXSEL(3, 1),
 		.pll            = PLL_28,
 		.pll            = PLL_28,
@@ -1897,7 +1881,6 @@ struct tvcard bttv_tvcards[] = {
 		.svhs           = 2,
 		.svhs           = 2,
 		.gpiomask       = 0,
 		.gpiomask       = 0,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.muxsel         = MUXSEL(2, 0, 1),
 		.muxsel         = MUXSEL(2, 0, 1),
 		.pll            = PLL_28,
 		.pll            = PLL_28,
@@ -1970,7 +1953,6 @@ struct tvcard bttv_tvcards[] = {
 		/* Tuner, CVid, SVid, CVid over SVid connector */
 		/* Tuner, CVid, SVid, CVid over SVid connector */
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomask       = 0,
 		.gpiomask       = 0,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.tuner_type     = TUNER_PHILIPS_PAL_I,
 		.tuner_type     = TUNER_PHILIPS_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -2017,7 +1999,6 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel         = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0),
 		.muxsel         = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0),
 		.muxsel_hook    = xguard_muxsel,
 		.muxsel_hook    = xguard_muxsel,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.pll            = PLL_28,
 		.pll            = PLL_28,
 	},
 	},
@@ -2029,7 +2010,6 @@ struct tvcard bttv_tvcards[] = {
 		.svhs           = NO_SVHS,
 		.svhs           = NO_SVHS,
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.pll            = PLL_28,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
@@ -2134,7 +2114,6 @@ struct tvcard bttv_tvcards[] = {
 		.svhs           = NO_SVHS,   /* card has no svhs */
 		.svhs           = NO_SVHS,   /* card has no svhs */
 		.needs_tvaudio  = 0,
 		.needs_tvaudio  = 0,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.gpiomask       = 0x00,
 		.gpiomask       = 0x00,
 		.muxsel         = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
 		.muxsel         = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
@@ -2156,7 +2135,6 @@ struct tvcard bttv_tvcards[] = {
 	[BTTV_BOARD_TWINHAN_DST] = {
 	[BTTV_BOARD_TWINHAN_DST] = {
 		.name           = "Twinhan DST + clones",
 		.name           = "Twinhan DST + clones",
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -2171,7 +2149,6 @@ struct tvcard bttv_tvcards[] = {
 		/* Vid In, SVid In, Vid over SVid in connector */
 		/* Vid In, SVid In, Vid over SVid in connector */
 		.muxsel		= MUXSEL(3, 1, 1, 3),
 		.muxsel		= MUXSEL(3, 1, 1, 3),
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -2226,7 +2203,6 @@ struct tvcard bttv_tvcards[] = {
 		.svhs           = NO_SVHS,
 		.svhs           = NO_SVHS,
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.needs_tvaudio  = 0,
 		.needs_tvaudio  = 0,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
@@ -2278,7 +2254,6 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0,
 		.gpiomask       = 0,
 		.gpiomask2      = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
 		.gpiomask2      = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		/*878A input is always MUX0, see above.*/
 		/*878A input is always MUX0, see above.*/
 		.muxsel         = MUXSEL(2, 2, 2, 2),
 		.muxsel         = MUXSEL(2, 2, 2, 2),
@@ -2302,7 +2277,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_TEMIC_PAL,
 		.tuner_type     = TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 	},
 	},
 	[BTTV_BOARD_AVDVBT_771] = {
 	[BTTV_BOARD_AVDVBT_771] = {
 		/* Wolfram Joost <wojo@frokaschwei.de> */
 		/* Wolfram Joost <wojo@frokaschwei.de> */
@@ -2313,7 +2287,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.muxsel         = MUXSEL(3, 3),
 		.muxsel         = MUXSEL(3, 3),
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.pll            = PLL_28,
 		.pll            = PLL_28,
 		.has_dvb        = 1,
 		.has_dvb        = 1,
@@ -2329,7 +2302,6 @@ struct tvcard bttv_tvcards[] = {
 		.svhs           = 1,
 		.svhs           = 1,
 		.muxsel         = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */
 		.muxsel         = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.pll            = PLL_28,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
@@ -2393,7 +2365,6 @@ struct tvcard bttv_tvcards[] = {
 		/* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
 		/* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
 		.name           = "DViCO FusionHDTV DVB-T Lite",
 		.name           = "DViCO FusionHDTV DVB-T Lite",
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.pll            = PLL_28,
 		.pll            = PLL_28,
 		.no_video       = 1,
 		.no_video       = 1,
@@ -2440,7 +2411,6 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel         = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
 		.muxsel         = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
 		.pll		= PLL_28,
 		.pll		= PLL_28,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432	= 1,
 		.no_tda7432	= 1,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -2478,7 +2448,6 @@ struct tvcard bttv_tvcards[] = {
 		.pll		= PLL_28,
 		.pll		= PLL_28,
 		.no_msp34xx	= 1,
 		.no_msp34xx	= 1,
 		.no_tda7432	= 1,
 		.no_tda7432	= 1,
-		.no_tda9875	= 1,
 		.muxsel_hook	= kodicom4400r_muxsel,
 		.muxsel_hook	= kodicom4400r_muxsel,
 	},
 	},
 	[BTTV_BOARD_KODICOM_4400R_SL] = {
 	[BTTV_BOARD_KODICOM_4400R_SL] = {
@@ -2500,7 +2469,6 @@ struct tvcard bttv_tvcards[] = {
 		.pll		= PLL_28,
 		.pll		= PLL_28,
 		.no_msp34xx	= 1,
 		.no_msp34xx	= 1,
 		.no_tda7432	= 1,
 		.no_tda7432	= 1,
-		.no_tda9875	= 1,
 		.muxsel_hook	= kodicom4400r_muxsel,
 		.muxsel_hook	= kodicom4400r_muxsel,
 	},
 	},
 		/* ---- card 0x86---------------------------------- */
 		/* ---- card 0x86---------------------------------- */
@@ -2530,7 +2498,6 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomux        = { 0x00400005, 0, 0x00000001, 0 },
 		.gpiomux        = { 0x00400005, 0, 0x00000001, 0 },
 		.gpiomute 	= 0x00c00007,
 		.gpiomute 	= 0x00c00007,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.has_dvb        = 1,
 		.has_dvb        = 1,
 	},
 	},
@@ -2630,7 +2597,6 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr     = ADDR_UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 		/* ---- card 0x8d ---------------------------------- */
 		/* ---- card 0x8d ---------------------------------- */
@@ -2658,7 +2624,6 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux 	= { 100000, 100002, 100002, 100000 },
 		.gpiomux 	= { 100000, 100002, 100002, 100000 },
 		.no_msp34xx	= 1,
 		.no_msp34xx	= 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.pll		= PLL_28,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TNF_5335MF,
 		.tuner_type	= TUNER_TNF_5335MF,
@@ -2674,7 +2639,6 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask	= 0x0f, /* old: 7 */
 		.gpiomask	= 0x0f, /* old: 7 */
 		.muxsel		= MUXSEL(0, 1, 3, 2), /* Composite 0-3 */
 		.muxsel		= MUXSEL(0, 1, 3, 2), /* Composite 0-3 */
 		.no_msp34xx	= 1,
 		.no_msp34xx	= 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -2732,7 +2696,6 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomux        = { 0x00400005, 0, 0x00000001, 0 },
 		.gpiomux        = { 0x00400005, 0, 0x00000001, 0 },
 		.gpiomute 	= 0x00c00007,
 		.gpiomute 	= 0x00c00007,
 		.no_msp34xx     = 1,
 		.no_msp34xx     = 1,
-		.no_tda9875     = 1,
 		.no_tda7432     = 1,
 		.no_tda7432     = 1,
 	},
 	},
 	/* ---- card 0x95---------------------------------- */
 	/* ---- card 0x95---------------------------------- */
@@ -2874,7 +2837,6 @@ struct tvcard bttv_tvcards[] = {
 		.pll		= PLL_28,
 		.pll		= PLL_28,
 		.no_msp34xx	= 1,
 		.no_msp34xx	= 1,
 		.no_tda7432	= 1,
 		.no_tda7432	= 1,
-		.no_tda9875	= 1,
 		.muxsel_hook    = gv800s_muxsel,
 		.muxsel_hook    = gv800s_muxsel,
 	},
 	},
 		[BTTV_BOARD_GEOVISION_GV800S_SL] = {
 		[BTTV_BOARD_GEOVISION_GV800S_SL] = {
@@ -2899,7 +2861,6 @@ struct tvcard bttv_tvcards[] = {
 		.pll		= PLL_28,
 		.pll		= PLL_28,
 		.no_msp34xx	= 1,
 		.no_msp34xx	= 1,
 		.no_tda7432	= 1,
 		.no_tda7432	= 1,
-		.no_tda9875	= 1,
 		.muxsel_hook    = gv800s_muxsel,
 		.muxsel_hook    = gv800s_muxsel,
 	},
 	},
 	[BTTV_BOARD_PV183] = {
 	[BTTV_BOARD_PV183] = {

+ 0 - 1
drivers/media/video/bt8xx/bttv.h

@@ -234,7 +234,6 @@ struct tvcard {
 
 
 	/* i2c audio flags */
 	/* i2c audio flags */
 	unsigned int no_msp34xx:1;
 	unsigned int no_msp34xx:1;
-	unsigned int no_tda9875:1;
 	unsigned int no_tda7432:1;
 	unsigned int no_tda7432:1;
 	unsigned int needs_tvaudio:1;
 	unsigned int needs_tvaudio:1;
 	unsigned int msp34xx_alt:1;
 	unsigned int msp34xx_alt:1;

+ 8 - 3
drivers/media/video/cafe_ccic.c

@@ -2001,6 +2001,11 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 		.min_width = 320,
 		.min_width = 320,
 		.min_height = 240,
 		.min_height = 240,
 	};
 	};
+	struct i2c_board_info ov7670_info = {
+		.type = "ov7670",
+		.addr = 0x42,
+		.platform_data = &sensor_cfg,
+	};
 
 
 	/*
 	/*
 	 * Start putting together one of our big camera structures.
 	 * Start putting together one of our big camera structures.
@@ -2062,9 +2067,9 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 	if (dmi_check_system(olpc_xo1_dmi))
 	if (dmi_check_system(olpc_xo1_dmi))
 		sensor_cfg.clock_speed = 45;
 		sensor_cfg.clock_speed = 45;
 
 
-	cam->sensor_addr = 0x42;
-	cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter,
-			"ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL);
+	cam->sensor_addr = ov7670_info.addr;
+	cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev, &cam->i2c_adapter,
+			&ov7670_info, NULL);
 	if (cam->sensor == NULL) {
 	if (cam->sensor == NULL) {
 		ret = -ENODEV;
 		ret = -ENODEV;
 		goto out_smbus;
 		goto out_smbus;

+ 1 - 1
drivers/media/video/cpia2/cpia2.h

@@ -378,7 +378,7 @@ struct cpia2_fh {
 
 
 struct camera_data {
 struct camera_data {
 	/* locks */
 	/* locks */
-	struct mutex busy_lock;	/* guard against SMP multithreading */
+	struct mutex v4l2_lock;	/* serialize file operations */
 	struct v4l2_prio_state prio;
 	struct v4l2_prio_state prio;
 
 
 	/* camera status */
 	/* camera status */

+ 15 - 50
drivers/media/video/cpia2/cpia2_core.c

@@ -2247,7 +2247,7 @@ struct camera_data *cpia2_init_camera_struct(void)
 
 
 
 
 	cam->present = 1;
 	cam->present = 1;
-	mutex_init(&cam->busy_lock);
+	mutex_init(&cam->v4l2_lock);
 	init_waitqueue_head(&cam->wq_stream);
 	init_waitqueue_head(&cam->wq_stream);
 
 
 	return cam;
 	return cam;
@@ -2365,9 +2365,9 @@ long cpia2_read(struct camera_data *cam,
 		char __user *buf, unsigned long count, int noblock)
 		char __user *buf, unsigned long count, int noblock)
 {
 {
 	struct framebuf *frame;
 	struct framebuf *frame;
-	if (!count) {
+
+	if (!count)
 		return 0;
 		return 0;
-	}
 
 
 	if (!buf) {
 	if (!buf) {
 		ERR("%s: buffer NULL\n",__func__);
 		ERR("%s: buffer NULL\n",__func__);
@@ -2379,17 +2379,12 @@ long cpia2_read(struct camera_data *cam,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	/* make this _really_ smp and multithread-safe */
-	if (mutex_lock_interruptible(&cam->busy_lock))
-		return -ERESTARTSYS;
-
 	if (!cam->present) {
 	if (!cam->present) {
 		LOG("%s: camera removed\n",__func__);
 		LOG("%s: camera removed\n",__func__);
-		mutex_unlock(&cam->busy_lock);
 		return 0;	/* EOF */
 		return 0;	/* EOF */
 	}
 	}
 
 
-	if(!cam->streaming) {
+	if (!cam->streaming) {
 		/* Start streaming */
 		/* Start streaming */
 		cpia2_usb_stream_start(cam,
 		cpia2_usb_stream_start(cam,
 				       cam->params.camera_state.stream_mode);
 				       cam->params.camera_state.stream_mode);
@@ -2398,42 +2393,31 @@ long cpia2_read(struct camera_data *cam,
 	/* Copy cam->curbuff in case it changes while we're processing */
 	/* Copy cam->curbuff in case it changes while we're processing */
 	frame = cam->curbuff;
 	frame = cam->curbuff;
 	if (noblock && frame->status != FRAME_READY) {
 	if (noblock && frame->status != FRAME_READY) {
-		mutex_unlock(&cam->busy_lock);
 		return -EAGAIN;
 		return -EAGAIN;
 	}
 	}
 
 
-	if(frame->status != FRAME_READY) {
-		mutex_unlock(&cam->busy_lock);
+	if (frame->status != FRAME_READY) {
+		mutex_unlock(&cam->v4l2_lock);
 		wait_event_interruptible(cam->wq_stream,
 		wait_event_interruptible(cam->wq_stream,
 			       !cam->present ||
 			       !cam->present ||
 			       (frame = cam->curbuff)->status == FRAME_READY);
 			       (frame = cam->curbuff)->status == FRAME_READY);
+		mutex_lock(&cam->v4l2_lock);
 		if (signal_pending(current))
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 			return -ERESTARTSYS;
-		/* make this _really_ smp and multithread-safe */
-		if (mutex_lock_interruptible(&cam->busy_lock)) {
-			return -ERESTARTSYS;
-		}
-		if(!cam->present) {
-			mutex_unlock(&cam->busy_lock);
+		if (!cam->present)
 			return 0;
 			return 0;
-		}
 	}
 	}
 
 
 	/* copy data to user space */
 	/* copy data to user space */
-	if (frame->length > count) {
-		mutex_unlock(&cam->busy_lock);
+	if (frame->length > count)
 		return -EFAULT;
 		return -EFAULT;
-	}
-	if (copy_to_user(buf, frame->data, frame->length)) {
-		mutex_unlock(&cam->busy_lock);
+	if (copy_to_user(buf, frame->data, frame->length))
 		return -EFAULT;
 		return -EFAULT;
-	}
 
 
 	count = frame->length;
 	count = frame->length;
 
 
 	frame->status = FRAME_EMPTY;
 	frame->status = FRAME_EMPTY;
 
 
-	mutex_unlock(&cam->busy_lock);
 	return count;
 	return count;
 }
 }
 
 
@@ -2447,17 +2431,13 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
 {
 {
 	unsigned int status=0;
 	unsigned int status=0;
 
 
-	if(!cam) {
+	if (!cam) {
 		ERR("%s: Internal error, camera_data not found!\n",__func__);
 		ERR("%s: Internal error, camera_data not found!\n",__func__);
 		return POLLERR;
 		return POLLERR;
 	}
 	}
 
 
-	mutex_lock(&cam->busy_lock);
-
-	if(!cam->present) {
-		mutex_unlock(&cam->busy_lock);
+	if (!cam->present)
 		return POLLHUP;
 		return POLLHUP;
-	}
 
 
 	if(!cam->streaming) {
 	if(!cam->streaming) {
 		/* Start streaming */
 		/* Start streaming */
@@ -2465,16 +2445,13 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
 				       cam->params.camera_state.stream_mode);
 				       cam->params.camera_state.stream_mode);
 	}
 	}
 
 
-	mutex_unlock(&cam->busy_lock);
 	poll_wait(filp, &cam->wq_stream, wait);
 	poll_wait(filp, &cam->wq_stream, wait);
-	mutex_lock(&cam->busy_lock);
 
 
 	if(!cam->present)
 	if(!cam->present)
 		status = POLLHUP;
 		status = POLLHUP;
 	else if(cam->curbuff->status == FRAME_READY)
 	else if(cam->curbuff->status == FRAME_READY)
 		status = POLLIN | POLLRDNORM;
 		status = POLLIN | POLLRDNORM;
 
 
-	mutex_unlock(&cam->busy_lock);
 	return status;
 	return status;
 }
 }
 
 
@@ -2496,29 +2473,19 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
 
 
 	DBG("mmap offset:%ld size:%ld\n", start_offset, size);
 	DBG("mmap offset:%ld size:%ld\n", start_offset, size);
 
 
-	/* make this _really_ smp-safe */
-	if (mutex_lock_interruptible(&cam->busy_lock))
-		return -ERESTARTSYS;
-
-	if (!cam->present) {
-		mutex_unlock(&cam->busy_lock);
+	if (!cam->present)
 		return -ENODEV;
 		return -ENODEV;
-	}
 
 
 	if (size > cam->frame_size*cam->num_frames  ||
 	if (size > cam->frame_size*cam->num_frames  ||
 	    (start_offset % cam->frame_size) != 0 ||
 	    (start_offset % cam->frame_size) != 0 ||
-	    (start_offset+size > cam->frame_size*cam->num_frames)) {
-		mutex_unlock(&cam->busy_lock);
+	    (start_offset+size > cam->frame_size*cam->num_frames))
 		return -EINVAL;
 		return -EINVAL;
-	}
 
 
 	pos = ((unsigned long) (cam->frame_buffer)) + start_offset;
 	pos = ((unsigned long) (cam->frame_buffer)) + start_offset;
 	while (size > 0) {
 	while (size > 0) {
 		page = kvirt_to_pa(pos);
 		page = kvirt_to_pa(pos);
-		if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) {
-			mutex_unlock(&cam->busy_lock);
+		if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED))
 			return -EAGAIN;
 			return -EAGAIN;
-		}
 		start += PAGE_SIZE;
 		start += PAGE_SIZE;
 		pos += PAGE_SIZE;
 		pos += PAGE_SIZE;
 		if (size > PAGE_SIZE)
 		if (size > PAGE_SIZE)
@@ -2528,7 +2495,5 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
 	}
 	}
 
 
 	cam->mmapped = true;
 	cam->mmapped = true;
-	mutex_unlock(&cam->busy_lock);
 	return 0;
 	return 0;
 }
 }
-

+ 34 - 70
drivers/media/video/cpia2/cpia2_v4l.c

@@ -238,59 +238,40 @@ static struct v4l2_queryctrl controls[] = {
 static int cpia2_open(struct file *file)
 static int cpia2_open(struct file *file)
 {
 {
 	struct camera_data *cam = video_drvdata(file);
 	struct camera_data *cam = video_drvdata(file);
-	int retval = 0;
+	struct cpia2_fh *fh;
 
 
 	if (!cam) {
 	if (!cam) {
 		ERR("Internal error, camera_data not found!\n");
 		ERR("Internal error, camera_data not found!\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	if(mutex_lock_interruptible(&cam->busy_lock))
-		return -ERESTARTSYS;
-
-	if(!cam->present) {
-		retval = -ENODEV;
-		goto err_return;
-	}
+	if (!cam->present)
+		return -ENODEV;
 
 
-	if (cam->open_count > 0) {
-		goto skip_init;
-	}
+	if (cam->open_count == 0) {
+		if (cpia2_allocate_buffers(cam))
+			return -ENOMEM;
 
 
-	if (cpia2_allocate_buffers(cam)) {
-		retval = -ENOMEM;
-		goto err_return;
-	}
+		/* reset the camera */
+		if (cpia2_reset_camera(cam) < 0)
+			return -EIO;
 
 
-	/* reset the camera */
-	if (cpia2_reset_camera(cam) < 0) {
-		retval = -EIO;
-		goto err_return;
+		cam->APP_len = 0;
+		cam->COM_len = 0;
 	}
 	}
 
 
-	cam->APP_len = 0;
-	cam->COM_len = 0;
-
-skip_init:
-	{
-		struct cpia2_fh *fh = kmalloc(sizeof(*fh),GFP_KERNEL);
-		if(!fh) {
-			retval = -ENOMEM;
-			goto err_return;
-		}
-		file->private_data = fh;
-		fh->prio = V4L2_PRIORITY_UNSET;
-		v4l2_prio_open(&cam->prio, &fh->prio);
-		fh->mmapped = 0;
-	}
+	fh = kmalloc(sizeof(*fh), GFP_KERNEL);
+	if (!fh)
+		return -ENOMEM;
+	file->private_data = fh;
+	fh->prio = V4L2_PRIORITY_UNSET;
+	v4l2_prio_open(&cam->prio, &fh->prio);
+	fh->mmapped = 0;
 
 
 	++cam->open_count;
 	++cam->open_count;
 
 
 	cpia2_dbg_dump_registers(cam);
 	cpia2_dbg_dump_registers(cam);
-
-err_return:
-	mutex_unlock(&cam->busy_lock);
-	return retval;
+	return 0;
 }
 }
 
 
 /******************************************************************************
 /******************************************************************************
@@ -304,15 +285,11 @@ static int cpia2_close(struct file *file)
 	struct camera_data *cam = video_get_drvdata(dev);
 	struct camera_data *cam = video_get_drvdata(dev);
 	struct cpia2_fh *fh = file->private_data;
 	struct cpia2_fh *fh = file->private_data;
 
 
-	mutex_lock(&cam->busy_lock);
-
 	if (cam->present &&
 	if (cam->present &&
-	    (cam->open_count == 1
-	     || fh->prio == V4L2_PRIORITY_RECORD
-	    )) {
+	    (cam->open_count == 1 || fh->prio == V4L2_PRIORITY_RECORD)) {
 		cpia2_usb_stream_stop(cam);
 		cpia2_usb_stream_stop(cam);
 
 
-		if(cam->open_count == 1) {
+		if (cam->open_count == 1) {
 			/* save camera state for later open */
 			/* save camera state for later open */
 			cpia2_save_camera_state(cam);
 			cpia2_save_camera_state(cam);
 
 
@@ -321,26 +298,21 @@ static int cpia2_close(struct file *file)
 		}
 		}
 	}
 	}
 
 
-	{
-		if(fh->mmapped)
-			cam->mmapped = 0;
-		v4l2_prio_close(&cam->prio, fh->prio);
-		file->private_data = NULL;
-		kfree(fh);
-	}
+	if (fh->mmapped)
+		cam->mmapped = 0;
+	v4l2_prio_close(&cam->prio, fh->prio);
+	file->private_data = NULL;
+	kfree(fh);
 
 
 	if (--cam->open_count == 0) {
 	if (--cam->open_count == 0) {
 		cpia2_free_buffers(cam);
 		cpia2_free_buffers(cam);
 		if (!cam->present) {
 		if (!cam->present) {
 			video_unregister_device(dev);
 			video_unregister_device(dev);
-			mutex_unlock(&cam->busy_lock);
 			kfree(cam);
 			kfree(cam);
 			return 0;
 			return 0;
 		}
 		}
 	}
 	}
 
 
-	mutex_unlock(&cam->busy_lock);
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -405,11 +377,11 @@ static int sync(struct camera_data *cam, int frame_nr)
 			return 0;
 			return 0;
 		}
 		}
 
 
-		mutex_unlock(&cam->busy_lock);
+		mutex_unlock(&cam->v4l2_lock);
 		wait_event_interruptible(cam->wq_stream,
 		wait_event_interruptible(cam->wq_stream,
 					 !cam->streaming ||
 					 !cam->streaming ||
 					 frame->status == FRAME_READY);
 					 frame->status == FRAME_READY);
-		mutex_lock(&cam->busy_lock);
+		mutex_lock(&cam->v4l2_lock);
 		if (signal_pending(current))
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 			return -ERESTARTSYS;
 		if(!cam->present)
 		if(!cam->present)
@@ -1293,11 +1265,11 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
 	if(frame < 0) {
 	if(frame < 0) {
 		/* Wait for a frame to become available */
 		/* Wait for a frame to become available */
 		struct framebuf *cb=cam->curbuff;
 		struct framebuf *cb=cam->curbuff;
-		mutex_unlock(&cam->busy_lock);
+		mutex_unlock(&cam->v4l2_lock);
 		wait_event_interruptible(cam->wq_stream,
 		wait_event_interruptible(cam->wq_stream,
 					 !cam->present ||
 					 !cam->present ||
 					 (cb=cam->curbuff)->status == FRAME_READY);
 					 (cb=cam->curbuff)->status == FRAME_READY);
-		mutex_lock(&cam->busy_lock);
+		mutex_lock(&cam->v4l2_lock);
 		if (signal_pending(current))
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 			return -ERESTARTSYS;
 		if(!cam->present)
 		if(!cam->present)
@@ -1337,14 +1309,8 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	if (!cam)
 	if (!cam)
 		return -ENOTTY;
 		return -ENOTTY;
 
 
-	/* make this _really_ smp-safe */
-	if (mutex_lock_interruptible(&cam->busy_lock))
-		return -ERESTARTSYS;
-
-	if (!cam->present) {
-		mutex_unlock(&cam->busy_lock);
+	if (!cam->present)
 		return -ENODEV;
 		return -ENODEV;
-	}
 
 
 	/* Priority check */
 	/* Priority check */
 	switch (cmd) {
 	switch (cmd) {
@@ -1352,10 +1318,8 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	{
 	{
 		struct cpia2_fh *fh = file->private_data;
 		struct cpia2_fh *fh = file->private_data;
 		retval = v4l2_prio_check(&cam->prio, fh->prio);
 		retval = v4l2_prio_check(&cam->prio, fh->prio);
-		if(retval) {
-			mutex_unlock(&cam->busy_lock);
+		if (retval)
 			return retval;
 			return retval;
-		}
 		break;
 		break;
 	}
 	}
 	default:
 	default:
@@ -1529,7 +1493,6 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		break;
 		break;
 	}
 	}
 
 
-	mutex_unlock(&cam->busy_lock);
 	return retval;
 	return retval;
 }
 }
 
 
@@ -1596,7 +1559,7 @@ static const struct v4l2_file_operations cpia2_fops = {
 	.release	= cpia2_close,
 	.release	= cpia2_close,
 	.read		= cpia2_v4l_read,
 	.read		= cpia2_v4l_read,
 	.poll		= cpia2_v4l_poll,
 	.poll		= cpia2_v4l_poll,
-	.ioctl		= cpia2_ioctl,
+	.unlocked_ioctl	= cpia2_ioctl,
 	.mmap		= cpia2_mmap,
 	.mmap		= cpia2_mmap,
 };
 };
 
 
@@ -1620,6 +1583,7 @@ int cpia2_register_camera(struct camera_data *cam)
 
 
 	memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template));
 	memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template));
 	video_set_drvdata(cam->vdev, cam);
 	video_set_drvdata(cam->vdev, cam);
+	cam->vdev->lock = &cam->v4l2_lock;
 
 
 	reset_camera_struct_v4l(cam);
 	reset_camera_struct_v4l(cam);
 
 

+ 2 - 22
drivers/media/video/cx18/cx18-driver.c

@@ -664,7 +664,7 @@ static int __devinit cx18_create_in_workq(struct cx18 *cx)
 {
 {
 	snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
 	snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
 		 cx->v4l2_dev.name);
 		 cx->v4l2_dev.name);
-	cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name);
+	cx->in_work_queue = alloc_ordered_workqueue(cx->in_workq_name, 0);
 	if (cx->in_work_queue == NULL) {
 	if (cx->in_work_queue == NULL) {
 		CX18_ERR("Unable to create incoming mailbox handler thread\n");
 		CX18_ERR("Unable to create incoming mailbox handler thread\n");
 		return -ENOMEM;
 		return -ENOMEM;
@@ -672,18 +672,6 @@ static int __devinit cx18_create_in_workq(struct cx18 *cx)
 	return 0;
 	return 0;
 }
 }
 
 
-static int __devinit cx18_create_out_workq(struct cx18 *cx)
-{
-	snprintf(cx->out_workq_name, sizeof(cx->out_workq_name), "%s-out",
-		 cx->v4l2_dev.name);
-	cx->out_work_queue = create_workqueue(cx->out_workq_name);
-	if (cx->out_work_queue == NULL) {
-		CX18_ERR("Unable to create outgoing mailbox handler threads\n");
-		return -ENOMEM;
-	}
-	return 0;
-}
-
 static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
 static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
 {
 {
 	int i;
 	int i;
@@ -710,15 +698,9 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
 	mutex_init(&cx->epu2apu_mb_lock);
 	mutex_init(&cx->epu2apu_mb_lock);
 	mutex_init(&cx->epu2cpu_mb_lock);
 	mutex_init(&cx->epu2cpu_mb_lock);
 
 
-	ret = cx18_create_out_workq(cx);
-	if (ret)
-		return ret;
-
 	ret = cx18_create_in_workq(cx);
 	ret = cx18_create_in_workq(cx);
-	if (ret) {
-		destroy_workqueue(cx->out_work_queue);
+	if (ret)
 		return ret;
 		return ret;
-	}
 
 
 	cx18_init_in_work_orders(cx);
 	cx18_init_in_work_orders(cx);
 
 
@@ -1107,7 +1089,6 @@ free_mem:
 	release_mem_region(cx->base_addr, CX18_MEM_SIZE);
 	release_mem_region(cx->base_addr, CX18_MEM_SIZE);
 free_workqueues:
 free_workqueues:
 	destroy_workqueue(cx->in_work_queue);
 	destroy_workqueue(cx->in_work_queue);
-	destroy_workqueue(cx->out_work_queue);
 err:
 err:
 	if (retval == 0)
 	if (retval == 0)
 		retval = -ENODEV;
 		retval = -ENODEV;
@@ -1259,7 +1240,6 @@ static void cx18_remove(struct pci_dev *pci_dev)
 	cx18_halt_firmware(cx);
 	cx18_halt_firmware(cx);
 
 
 	destroy_workqueue(cx->in_work_queue);
 	destroy_workqueue(cx->in_work_queue);
-	destroy_workqueue(cx->out_work_queue);
 
 
 	cx18_streams_cleanup(cx, 1);
 	cx18_streams_cleanup(cx, 1);
 
 

+ 0 - 3
drivers/media/video/cx18/cx18-driver.h

@@ -617,9 +617,6 @@ struct cx18 {
 	struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
 	struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
 	char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
 	char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
 
 
-	struct workqueue_struct *out_work_queue;
-	char out_workq_name[12]; /* "cx18-NN-out" */
-
 	/* i2c */
 	/* i2c */
 	struct i2c_adapter i2c_adap[2];
 	struct i2c_adapter i2c_adap[2];
 	struct i2c_algo_bit_data i2c_algo[2];
 	struct i2c_algo_bit_data i2c_algo[2];

+ 1 - 2
drivers/media/video/cx18/cx18-streams.h

@@ -42,8 +42,7 @@ static inline bool cx18_stream_enabled(struct cx18_stream *s)
 /* Related to submission of mdls to firmware */
 /* Related to submission of mdls to firmware */
 static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
 static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
 {
 {
-	struct cx18 *cx = s->cx;
-	queue_work(cx->out_work_queue, &s->out_work_order);
+	schedule_work(&s->out_work_order);
 }
 }
 
 
 static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,
 static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,

+ 2 - 3
drivers/media/video/cx231xx/cx231xx-dvb.c

@@ -28,7 +28,6 @@
 #include <media/videobuf-vmalloc.h>
 #include <media/videobuf-vmalloc.h>
 
 
 #include "xc5000.h"
 #include "xc5000.h"
-#include "dvb_dummy_fe.h"
 #include "s5h1432.h"
 #include "s5h1432.h"
 #include "tda18271.h"
 #include "tda18271.h"
 #include "s5h1411.h"
 #include "s5h1411.h"
@@ -619,7 +618,7 @@ static int dvb_init(struct cx231xx *dev)
 
 
 		if (dev->dvb->frontend == NULL) {
 		if (dev->dvb->frontend == NULL) {
 			printk(DRIVER_NAME
 			printk(DRIVER_NAME
-			       ": Failed to attach dummy front end\n");
+			       ": Failed to attach s5h1411 front end\n");
 			result = -EINVAL;
 			result = -EINVAL;
 			goto out_free;
 			goto out_free;
 		}
 		}
@@ -665,7 +664,7 @@ static int dvb_init(struct cx231xx *dev)
 
 
 		if (dev->dvb->frontend == NULL) {
 		if (dev->dvb->frontend == NULL) {
 			printk(DRIVER_NAME
 			printk(DRIVER_NAME
-			       ": Failed to attach dummy front end\n");
+			       ": Failed to attach s5h1411 front end\n");
 			result = -EINVAL;
 			result = -EINVAL;
 			goto out_free;
 			goto out_free;
 		}
 		}

+ 6 - 16
drivers/media/video/cx25840/cx25840-core.c

@@ -1682,20 +1682,6 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
 	return 0;
 	return 0;
 }
 }
 
 
-static int cx25840_s_config(struct v4l2_subdev *sd, int irq, void *platform_data)
-{
-	struct cx25840_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (platform_data) {
-		struct cx25840_platform_data *pdata = platform_data;
-
-		state->pvr150_workaround = pdata->pvr150_workaround;
-		set_input(client, state->vid_input, state->aud_input);
-	}
-	return 0;
-}
-
 static int cx23885_irq_handler(struct v4l2_subdev *sd, u32 status,
 static int cx23885_irq_handler(struct v4l2_subdev *sd, u32 status,
 			       bool *handled)
 			       bool *handled)
 {
 {
@@ -1787,7 +1773,6 @@ static const struct v4l2_ctrl_ops cx25840_ctrl_ops = {
 
 
 static const struct v4l2_subdev_core_ops cx25840_core_ops = {
 static const struct v4l2_subdev_core_ops cx25840_core_ops = {
 	.log_status = cx25840_log_status,
 	.log_status = cx25840_log_status,
-	.s_config = cx25840_s_config,
 	.g_chip_ident = cx25840_g_chip_ident,
 	.g_chip_ident = cx25840_g_chip_ident,
 	.g_ctrl = v4l2_subdev_g_ctrl,
 	.g_ctrl = v4l2_subdev_g_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
@@ -1974,7 +1959,6 @@ static int cx25840_probe(struct i2c_client *client,
 	state->vid_input = CX25840_COMPOSITE7;
 	state->vid_input = CX25840_COMPOSITE7;
 	state->aud_input = CX25840_AUDIO8;
 	state->aud_input = CX25840_AUDIO8;
 	state->audclk_freq = 48000;
 	state->audclk_freq = 48000;
-	state->pvr150_workaround = 0;
 	state->audmode = V4L2_TUNER_MODE_LANG1;
 	state->audmode = V4L2_TUNER_MODE_LANG1;
 	state->vbi_line_offset = 8;
 	state->vbi_line_offset = 8;
 	state->id = id;
 	state->id = id;
@@ -2034,6 +2018,12 @@ static int cx25840_probe(struct i2c_client *client,
 	v4l2_ctrl_cluster(2, &state->volume);
 	v4l2_ctrl_cluster(2, &state->volume);
 	v4l2_ctrl_handler_setup(&state->hdl);
 	v4l2_ctrl_handler_setup(&state->hdl);
 
 
+	if (client->dev.platform_data) {
+		struct cx25840_platform_data *pdata = client->dev.platform_data;
+
+		state->pvr150_workaround = pdata->pvr150_workaround;
+	}
+
 	cx25840_ir_probe(sd);
 	cx25840_ir_probe(sd);
 	return 0;
 	return 0;
 }
 }

+ 177 - 0
drivers/media/video/davinci/vpif.c

@@ -41,6 +41,183 @@ spinlock_t vpif_lock;
 
 
 void __iomem *vpif_base;
 void __iomem *vpif_base;
 
 
+/**
+ * ch_params: video standard configuration parameters for vpif
+ * The table must include all presets from supported subdevices.
+ */
+const struct vpif_channel_config_params ch_params[] = {
+	/* HDTV formats */
+	{
+		.name = "480p59_94",
+		.width = 720,
+		.height = 480,
+		.frm_fmt = 1,
+		.ycmux_mode = 0,
+		.eav2sav = 138-8,
+		.sav2eav = 720,
+		.l1 = 1,
+		.l3 = 43,
+		.l5 = 523,
+		.vsize = 525,
+		.capture_format = 0,
+		.vbi_supported = 0,
+		.hd_sd = 1,
+		.dv_preset = V4L2_DV_480P59_94,
+	},
+	{
+		.name = "576p50",
+		.width = 720,
+		.height = 576,
+		.frm_fmt = 1,
+		.ycmux_mode = 0,
+		.eav2sav = 144-8,
+		.sav2eav = 720,
+		.l1 = 1,
+		.l3 = 45,
+		.l5 = 621,
+		.vsize = 625,
+		.capture_format = 0,
+		.vbi_supported = 0,
+		.hd_sd = 1,
+		.dv_preset = V4L2_DV_576P50,
+	},
+	{
+		.name = "720p50",
+		.width = 1280,
+		.height = 720,
+		.frm_fmt = 1,
+		.ycmux_mode = 0,
+		.eav2sav = 700-8,
+		.sav2eav = 1280,
+		.l1 = 1,
+		.l3 = 26,
+		.l5 = 746,
+		.vsize = 750,
+		.capture_format = 0,
+		.vbi_supported = 0,
+		.hd_sd = 1,
+		.dv_preset = V4L2_DV_720P50,
+	},
+	{
+		.name = "720p60",
+		.width = 1280,
+		.height = 720,
+		.frm_fmt = 1,
+		.ycmux_mode = 0,
+		.eav2sav = 370 - 8,
+		.sav2eav = 1280,
+		.l1 = 1,
+		.l3 = 26,
+		.l5 = 746,
+		.vsize = 750,
+		.capture_format = 0,
+		.vbi_supported = 0,
+		.hd_sd = 1,
+		.dv_preset = V4L2_DV_720P60,
+	},
+	{
+		.name = "1080I50",
+		.width = 1920,
+		.height = 1080,
+		.frm_fmt = 0,
+		.ycmux_mode = 0,
+		.eav2sav = 720 - 8,
+		.sav2eav = 1920,
+		.l1 = 1,
+		.l3 = 21,
+		.l5 = 561,
+		.l7 = 563,
+		.l9 = 584,
+		.l11 = 1124,
+		.vsize = 1125,
+		.capture_format = 0,
+		.vbi_supported = 0,
+		.hd_sd = 1,
+		.dv_preset = V4L2_DV_1080I50,
+	},
+	{
+		.name = "1080I60",
+		.width = 1920,
+		.height = 1080,
+		.frm_fmt = 0,
+		.ycmux_mode = 0,
+		.eav2sav = 280 - 8,
+		.sav2eav = 1920,
+		.l1 = 1,
+		.l3 = 21,
+		.l5 = 561,
+		.l7 = 563,
+		.l9 = 584,
+		.l11 = 1124,
+		.vsize = 1125,
+		.capture_format = 0,
+		.vbi_supported = 0,
+		.hd_sd = 1,
+		.dv_preset = V4L2_DV_1080I60,
+	},
+	{
+		.name = "1080p60",
+		.width = 1920,
+		.height = 1080,
+		.frm_fmt = 1,
+		.ycmux_mode = 0,
+		.eav2sav = 280 - 8,
+		.sav2eav = 1920,
+		.l1 = 1,
+		.l3 = 42,
+		.l5 = 1122,
+		.vsize = 1125,
+		.capture_format = 0,
+		.vbi_supported = 0,
+		.hd_sd = 1,
+		.dv_preset = V4L2_DV_1080P60,
+	},
+
+	/* SDTV formats */
+	{
+		.name = "NTSC_M",
+		.width = 720,
+		.height = 480,
+		.frm_fmt = 0,
+		.ycmux_mode = 1,
+		.eav2sav = 268,
+		.sav2eav = 1440,
+		.l1 = 1,
+		.l3 = 23,
+		.l5 = 263,
+		.l7 = 266,
+		.l9 = 286,
+		.l11 = 525,
+		.vsize = 525,
+		.capture_format = 0,
+		.vbi_supported = 1,
+		.hd_sd = 0,
+		.stdid = V4L2_STD_525_60,
+	},
+	{
+		.name = "PAL_BDGHIK",
+		.width = 720,
+		.height = 576,
+		.frm_fmt = 0,
+		.ycmux_mode = 1,
+		.eav2sav = 280,
+		.sav2eav = 1440,
+		.l1 = 1,
+		.l3 = 23,
+		.l5 = 311,
+		.l7 = 313,
+		.l9 = 336,
+		.l11 = 624,
+		.vsize = 625,
+		.capture_format = 0,
+		.vbi_supported = 1,
+		.hd_sd = 0,
+		.stdid = V4L2_STD_625_50,
+	},
+};
+
+const unsigned int vpif_ch_params_count = ARRAY_SIZE(ch_params);
+
 static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
 static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
 {
 {
 	if (val)
 	if (val)

+ 10 - 8
drivers/media/video/davinci/vpif.h

@@ -577,12 +577,10 @@ struct vpif_channel_config_params {
 	char name[VPIF_MAX_NAME];	/* Name of the mode */
 	char name[VPIF_MAX_NAME];	/* Name of the mode */
 	u16 width;			/* Indicates width of the image */
 	u16 width;			/* Indicates width of the image */
 	u16 height;			/* Indicates height of the image */
 	u16 height;			/* Indicates height of the image */
-	u8 fps;
-	u8 frm_fmt;			/* Indicates whether this is interlaced
-					 * or progressive format */
-	u8 ycmux_mode;			/* Indicates whether this mode requires
-					 * single or two channels */
-	u16 eav2sav;			/* length of sav 2 eav */
+	u8 frm_fmt;			/* Interlaced (0) or progressive (1) */
+	u8 ycmux_mode;			/* This mode requires one (0) or two (1)
+					   channels */
+	u16 eav2sav;			/* length of eav 2 sav */
 	u16 sav2eav;			/* length of sav 2 eav */
 	u16 sav2eav;			/* length of sav 2 eav */
 	u16 l1, l3, l5, l7, l9, l11;	/* Other parameter configurations */
 	u16 l1, l3, l5, l7, l9, l11;	/* Other parameter configurations */
 	u16 vsize;			/* Vertical size of the image */
 	u16 vsize;			/* Vertical size of the image */
@@ -590,10 +588,14 @@ struct vpif_channel_config_params {
 					 * is in BT or in CCD/CMOS */
 					 * is in BT or in CCD/CMOS */
 	u8  vbi_supported;		/* Indicates whether this mode
 	u8  vbi_supported;		/* Indicates whether this mode
 					 * supports capturing vbi or not */
 					 * supports capturing vbi or not */
-	u8 hd_sd;
-	v4l2_std_id stdid;
+	u8 hd_sd;			/* HDTV (1) or SDTV (0) format */
+	v4l2_std_id stdid;		/* SDTV format */
+	u32 dv_preset;			/* HDTV format */
 };
 };
 
 
+extern const unsigned int vpif_ch_params_count;
+extern const struct vpif_channel_config_params ch_params[];
+
 struct vpif_video_params;
 struct vpif_video_params;
 struct vpif_params;
 struct vpif_params;
 struct vpif_vbi_params;
 struct vpif_vbi_params;

+ 349 - 102
drivers/media/video/davinci/vpif_capture.c

@@ -37,6 +37,7 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
 
 
 #include "vpif_capture.h"
 #include "vpif_capture.h"
 #include "vpif.h"
 #include "vpif.h"
@@ -80,20 +81,6 @@ static struct vpif_config_params config_params = {
 static struct vpif_device vpif_obj = { {NULL} };
 static struct vpif_device vpif_obj = { {NULL} };
 static struct device *vpif_dev;
 static struct device *vpif_dev;
 
 
-/**
- * ch_params: video standard configuration parameters for vpif
- */
-static const struct vpif_channel_config_params ch_params[] = {
-	{
-		"NTSC_M", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
-		286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
-	},
-	{
-		"PAL_BDGHIK", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
-		336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
-	},
-};
-
 /**
 /**
  * vpif_uservirt_to_phys : translate user/virtual address to phy address
  * vpif_uservirt_to_phys : translate user/virtual address to phy address
  * @virtp: user/virtual address
  * @virtp: user/virtual address
@@ -342,7 +329,7 @@ static void vpif_schedule_next_buffer(struct common_obj *common)
  * @dev_id: dev_id ptr
  * @dev_id: dev_id ptr
  *
  *
  * It changes status of the captured buffer, takes next buffer from the queue
  * It changes status of the captured buffer, takes next buffer from the queue
- * and sets its address in VPIF  registers
+ * and sets its address in VPIF registers
  */
  */
 static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
 static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
 {
 {
@@ -435,24 +422,31 @@ static int vpif_update_std_info(struct channel_obj *ch)
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct vpif_params *vpifparams = &ch->vpifparams;
 	struct vpif_params *vpifparams = &ch->vpifparams;
 	const struct vpif_channel_config_params *config;
 	const struct vpif_channel_config_params *config;
-	struct vpif_channel_config_params *std_info;
+	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
 	struct video_obj *vid_ch = &ch->video;
 	struct video_obj *vid_ch = &ch->video;
 	int index;
 	int index;
 
 
 	vpif_dbg(2, debug, "vpif_update_std_info\n");
 	vpif_dbg(2, debug, "vpif_update_std_info\n");
 
 
-	std_info = &vpifparams->std_info;
-
-	for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
+	for (index = 0; index < vpif_ch_params_count; index++) {
 		config = &ch_params[index];
 		config = &ch_params[index];
-		if (config->stdid & vid_ch->stdid) {
-			memcpy(std_info, config, sizeof(*config));
-			break;
+		if (config->hd_sd == 0) {
+			vpif_dbg(2, debug, "SD format\n");
+			if (config->stdid & vid_ch->stdid) {
+				memcpy(std_info, config, sizeof(*config));
+				break;
+			}
+		} else {
+			vpif_dbg(2, debug, "HD format\n");
+			if (config->dv_preset == vid_ch->dv_preset) {
+				memcpy(std_info, config, sizeof(*config));
+				break;
+			}
 		}
 		}
 	}
 	}
 
 
 	/* standard not found */
 	/* standard not found */
-	if (index == ARRAY_SIZE(ch_params))
+	if (index == vpif_ch_params_count)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	common->fmt.fmt.pix.width = std_info->width;
 	common->fmt.fmt.pix.width = std_info->width;
@@ -462,6 +456,7 @@ static int vpif_update_std_info(struct channel_obj *ch)
 	common->fmt.fmt.pix.bytesperline = std_info->width;
 	common->fmt.fmt.pix.bytesperline = std_info->width;
 	vpifparams->video_params.hpitch = std_info->width;
 	vpifparams->video_params.hpitch = std_info->width;
 	vpifparams->video_params.storage_mode = std_info->frm_fmt;
 	vpifparams->video_params.storage_mode = std_info->frm_fmt;
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -757,7 +752,7 @@ static int vpif_open(struct file *filep)
 	struct video_obj *vid_ch;
 	struct video_obj *vid_ch;
 	struct channel_obj *ch;
 	struct channel_obj *ch;
 	struct vpif_fh *fh;
 	struct vpif_fh *fh;
-	int i, ret = 0;
+	int i;
 
 
 	vpif_dbg(2, debug, "vpif_open\n");
 	vpif_dbg(2, debug, "vpif_open\n");
 
 
@@ -766,9 +761,6 @@ static int vpif_open(struct file *filep)
 	vid_ch = &ch->video;
 	vid_ch = &ch->video;
 	common = &ch->common[VPIF_VIDEO_INDEX];
 	common = &ch->common[VPIF_VIDEO_INDEX];
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	if (NULL == ch->curr_subdev_info) {
 	if (NULL == ch->curr_subdev_info) {
 		/**
 		/**
 		 * search through the sub device to see a registered
 		 * search through the sub device to see a registered
@@ -785,8 +777,7 @@ static int vpif_open(struct file *filep)
 		}
 		}
 		if (i == config->subdev_count) {
 		if (i == config->subdev_count) {
 			vpif_err("No sub device registered\n");
 			vpif_err("No sub device registered\n");
-			ret = -ENOENT;
-			goto exit;
+			return -ENOENT;
 		}
 		}
 	}
 	}
 
 
@@ -794,8 +785,7 @@ static int vpif_open(struct file *filep)
 	fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
 	fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
 	if (NULL == fh) {
 	if (NULL == fh) {
 		vpif_err("unable to allocate memory for file handle object\n");
 		vpif_err("unable to allocate memory for file handle object\n");
-		ret = -ENOMEM;
-		goto exit;
+		return -ENOMEM;
 	}
 	}
 
 
 	/* store pointer to fh in private_data member of filep */
 	/* store pointer to fh in private_data member of filep */
@@ -815,9 +805,7 @@ static int vpif_open(struct file *filep)
 	/* Initialize priority of this instance to default priority */
 	/* Initialize priority of this instance to default priority */
 	fh->prio = V4L2_PRIORITY_UNSET;
 	fh->prio = V4L2_PRIORITY_UNSET;
 	v4l2_prio_open(&ch->prio, &fh->prio);
 	v4l2_prio_open(&ch->prio, &fh->prio);
-exit:
-	mutex_unlock(&common->lock);
-	return ret;
+	return 0;
 }
 }
 
 
 /**
 /**
@@ -837,9 +825,6 @@ static int vpif_release(struct file *filep)
 
 
 	common = &ch->common[VPIF_VIDEO_INDEX];
 	common = &ch->common[VPIF_VIDEO_INDEX];
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	/* if this instance is doing IO */
 	/* if this instance is doing IO */
 	if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
 	if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
 		/* Reset io_usrs member of channel object */
 		/* Reset io_usrs member of channel object */
@@ -863,9 +848,6 @@ static int vpif_release(struct file *filep)
 	/* Decrement channel usrs counter */
 	/* Decrement channel usrs counter */
 	ch->usrs--;
 	ch->usrs--;
 
 
-	/* unlock mutex on channel object */
-	mutex_unlock(&common->lock);
-
 	/* Close the priority */
 	/* Close the priority */
 	v4l2_prio_close(&ch->prio, fh->prio);
 	v4l2_prio_close(&ch->prio, fh->prio);
 
 
@@ -890,7 +872,6 @@ static int vpif_reqbufs(struct file *file, void *priv,
 	struct channel_obj *ch = fh->channel;
 	struct channel_obj *ch = fh->channel;
 	struct common_obj *common;
 	struct common_obj *common;
 	u8 index = 0;
 	u8 index = 0;
-	int ret = 0;
 
 
 	vpif_dbg(2, debug, "vpif_reqbufs\n");
 	vpif_dbg(2, debug, "vpif_reqbufs\n");
 
 
@@ -913,13 +894,8 @@ static int vpif_reqbufs(struct file *file, void *priv,
 
 
 	common = &ch->common[index];
 	common = &ch->common[index];
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
-	if (0 != common->io_usrs) {
-		ret = -EBUSY;
-		goto reqbuf_exit;
-	}
+	if (0 != common->io_usrs)
+		return -EBUSY;
 
 
 	/* Initialize videobuf queue as per the buffer type */
 	/* Initialize videobuf queue as per the buffer type */
 	videobuf_queue_dma_contig_init(&common->buffer_queue,
 	videobuf_queue_dma_contig_init(&common->buffer_queue,
@@ -928,7 +904,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
 					    reqbuf->type,
 					    reqbuf->type,
 					    common->fmt.fmt.pix.field,
 					    common->fmt.fmt.pix.field,
 					    sizeof(struct videobuf_buffer), fh,
 					    sizeof(struct videobuf_buffer), fh,
-					    NULL);
+					    &common->lock);
 
 
 	/* Set io allowed member of file handle to TRUE */
 	/* Set io allowed member of file handle to TRUE */
 	fh->io_allowed[index] = 1;
 	fh->io_allowed[index] = 1;
@@ -939,11 +915,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
 	INIT_LIST_HEAD(&common->dma_queue);
 	INIT_LIST_HEAD(&common->dma_queue);
 
 
 	/* Allocate buffers */
 	/* Allocate buffers */
-	ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
-
-reqbuf_exit:
-	mutex_unlock(&common->lock);
-	return ret;
+	return videobuf_reqbufs(&common->buffer_queue, reqbuf);
 }
 }
 
 
 /**
 /**
@@ -1157,11 +1129,6 @@ static int vpif_streamon(struct file *file, void *priv,
 		return ret;
 		return ret;
 	}
 	}
 
 
-	if (mutex_lock_interruptible(&common->lock)) {
-		ret = -ERESTARTSYS;
-		goto streamoff_exit;
-	}
-
 	/* If buffer queue is empty, return error */
 	/* If buffer queue is empty, return error */
 	if (list_empty(&common->dma_queue)) {
 	if (list_empty(&common->dma_queue)) {
 		vpif_dbg(1, debug, "buffer queue is empty\n");
 		vpif_dbg(1, debug, "buffer queue is empty\n");
@@ -1240,13 +1207,10 @@ static int vpif_streamon(struct file *file, void *priv,
 		enable_channel1(1);
 		enable_channel1(1);
 	}
 	}
 	channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
 	channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
-	mutex_unlock(&common->lock);
 	return ret;
 	return ret;
 
 
 exit:
 exit:
-	mutex_unlock(&common->lock);
-streamoff_exit:
-	ret = videobuf_streamoff(&common->buffer_queue);
+	videobuf_streamoff(&common->buffer_queue);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1284,9 +1248,6 @@ static int vpif_streamoff(struct file *file, void *priv,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	/* disable channel */
 	/* disable channel */
 	if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
 	if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
 		enable_channel0(0);
 		enable_channel0(0);
@@ -1304,8 +1265,6 @@ static int vpif_streamoff(struct file *file, void *priv,
 	if (ret && (ret != -ENOIOCTLCMD))
 	if (ret && (ret != -ENOIOCTLCMD))
 		vpif_dbg(1, debug, "stream off failed in subdev\n");
 		vpif_dbg(1, debug, "stream off failed in subdev\n");
 
 
-	mutex_unlock(&common->lock);
-
 	return videobuf_streamoff(&common->buffer_queue);
 	return videobuf_streamoff(&common->buffer_queue);
 }
 }
 
 
@@ -1381,21 +1340,16 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
 {
 {
 	struct vpif_fh *fh = priv;
 	struct vpif_fh *fh = priv;
 	struct channel_obj *ch = fh->channel;
 	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	int ret = 0;
 	int ret = 0;
 
 
 	vpif_dbg(2, debug, "vpif_querystd\n");
 	vpif_dbg(2, debug, "vpif_querystd\n");
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	/* Call querystd function of decoder device */
 	/* Call querystd function of decoder device */
 	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
 	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
 				querystd, std_id);
 				querystd, std_id);
 	if (ret < 0)
 	if (ret < 0)
 		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
 		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
 
 
-	mutex_unlock(&common->lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1451,16 +1405,14 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
 	fh->initialized = 1;
 	fh->initialized = 1;
 
 
 	/* Call encoder subdevice function to set the standard */
 	/* Call encoder subdevice function to set the standard */
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	ch->video.stdid = *std_id;
 	ch->video.stdid = *std_id;
+	ch->video.dv_preset = V4L2_DV_INVALID;
+	memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
 
 
 	/* Get the information about the standard */
 	/* Get the information about the standard */
 	if (vpif_update_std_info(ch)) {
 	if (vpif_update_std_info(ch)) {
-		ret = -EINVAL;
 		vpif_err("Error getting the standard info\n");
 		vpif_err("Error getting the standard info\n");
-		goto s_std_exit;
+		return -EINVAL;
 	}
 	}
 
 
 	/* Configure the default format information */
 	/* Configure the default format information */
@@ -1471,9 +1423,6 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
 				s_std, *std_id);
 				s_std, *std_id);
 	if (ret < 0)
 	if (ret < 0)
 		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
 		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
-
-s_std_exit:
-	mutex_unlock(&common->lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1567,9 +1516,6 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	/* first setup input path from sub device to vpif */
 	/* first setup input path from sub device to vpif */
 	if (config->setup_input_path) {
 	if (config->setup_input_path) {
 		ret = config->setup_input_path(ch->channel_id,
 		ret = config->setup_input_path(ch->channel_id,
@@ -1578,7 +1524,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
 			vpif_dbg(1, debug, "couldn't setup input path for the"
 			vpif_dbg(1, debug, "couldn't setup input path for the"
 				" sub device %s, for input index %d\n",
 				" sub device %s, for input index %d\n",
 				subdev_info->name, index);
 				subdev_info->name, index);
-			goto exit;
+			return ret;
 		}
 		}
 	}
 	}
 
 
@@ -1589,7 +1535,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
 					input, output, 0);
 					input, output, 0);
 		if (ret < 0) {
 		if (ret < 0) {
 			vpif_dbg(1, debug, "Failed to set input\n");
 			vpif_dbg(1, debug, "Failed to set input\n");
-			goto exit;
+			return ret;
 		}
 		}
 	}
 	}
 	vid_ch->input_idx = index;
 	vid_ch->input_idx = index;
@@ -1600,9 +1546,6 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
 
 
 	/* update tvnorms from the sub device input info */
 	/* update tvnorms from the sub device input info */
 	ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
 	ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
-
-exit:
-	mutex_unlock(&common->lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1671,11 +1614,7 @@ static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
 		return -EINVAL;
 		return -EINVAL;
 
 
 	/* Fill in the information about format */
 	/* Fill in the information about format */
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	*fmt = common->fmt;
 	*fmt = common->fmt;
-	mutex_unlock(&common->lock);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1694,7 +1633,7 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
 	struct v4l2_pix_format *pixfmt;
 	struct v4l2_pix_format *pixfmt;
 	int ret = 0;
 	int ret = 0;
 
 
-	vpif_dbg(2, debug, "VIDIOC_S_FMT\n");
+	vpif_dbg(2, debug, "%s\n", __func__);
 
 
 	/* If streaming is started, return error */
 	/* If streaming is started, return error */
 	if (common->started) {
 	if (common->started) {
@@ -1723,12 +1662,7 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 	/* store the format in the channel object */
 	/* store the format in the channel object */
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	common->fmt = *fmt;
 	common->fmt = *fmt;
-	mutex_unlock(&common->lock);
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1807,6 +1741,306 @@ static int vpif_cropcap(struct file *file, void *priv,
 	return 0;
 	return 0;
 }
 }
 
 
+/**
+ * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @preset: input preset
+ */
+static int vpif_enum_dv_presets(struct file *file, void *priv,
+		struct v4l2_dv_enum_preset *preset)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
+			video, enum_dv_presets, preset);
+}
+
+/**
+ * vpif_query_dv_presets() - QUERY_DV_PRESET handler
+ * @file: file ptr
+ * @priv: file handle
+ * @preset: input preset
+ */
+static int vpif_query_dv_preset(struct file *file, void *priv,
+		struct v4l2_dv_preset *preset)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
+		       video, query_dv_preset, preset);
+}
+/**
+ * vpif_s_dv_presets() - S_DV_PRESETS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @preset: input preset
+ */
+static int vpif_s_dv_preset(struct file *file, void *priv,
+		struct v4l2_dv_preset *preset)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	int ret = 0;
+
+	if (common->started) {
+		vpif_dbg(1, debug, "streaming in progress\n");
+		return -EBUSY;
+	}
+
+	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
+	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
+		if (!fh->initialized) {
+			vpif_dbg(1, debug, "Channel Busy\n");
+			return -EBUSY;
+		}
+	}
+
+	ret = v4l2_prio_check(&ch->prio, fh->prio);
+	if (ret)
+		return ret;
+
+	fh->initialized = 1;
+
+	/* Call encoder subdevice function to set the standard */
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	ch->video.dv_preset = preset->preset;
+	ch->video.stdid = V4L2_STD_UNKNOWN;
+	memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
+
+	/* Get the information about the standard */
+	if (vpif_update_std_info(ch)) {
+		vpif_dbg(1, debug, "Error getting the standard info\n");
+		ret = -EINVAL;
+	} else {
+		/* Configure the default format information */
+		vpif_config_format(ch);
+
+		ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
+				video, s_dv_preset, preset);
+	}
+
+	mutex_unlock(&common->lock);
+
+	return ret;
+}
+/**
+ * vpif_g_dv_presets() - G_DV_PRESETS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @preset: input preset
+ */
+static int vpif_g_dv_preset(struct file *file, void *priv,
+		struct v4l2_dv_preset *preset)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	preset->preset = ch->video.dv_preset;
+
+	return 0;
+}
+
+/**
+ * vpif_s_dv_timings() - S_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: digital video timings
+ */
+static int vpif_s_dv_timings(struct file *file, void *priv,
+		struct v4l2_dv_timings *timings)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct vpif_params *vpifparams = &ch->vpifparams;
+	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+	struct video_obj *vid_ch = &ch->video;
+	struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
+	int ret;
+
+	if (timings->type != V4L2_DV_BT_656_1120) {
+		vpif_dbg(2, debug, "Timing type not defined\n");
+		return -EINVAL;
+	}
+
+	/* Configure subdevice timings, if any */
+	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
+			video, s_dv_timings, timings);
+	if (ret == -ENOIOCTLCMD) {
+		vpif_dbg(2, debug, "Custom DV timings not supported by "
+				"subdevice\n");
+		return -EINVAL;
+	}
+	if (ret < 0) {
+		vpif_dbg(2, debug, "Error setting custom DV timings\n");
+		return ret;
+	}
+
+	if (!(timings->bt.width && timings->bt.height &&
+				(timings->bt.hbackporch ||
+				 timings->bt.hfrontporch ||
+				 timings->bt.hsync) &&
+				timings->bt.vfrontporch &&
+				(timings->bt.vbackporch ||
+				 timings->bt.vsync))) {
+		vpif_dbg(2, debug, "Timings for width, height, "
+				"horizontal back porch, horizontal sync, "
+				"horizontal front porch, vertical back porch, "
+				"vertical sync and vertical back porch "
+				"must be defined\n");
+		return -EINVAL;
+	}
+
+	*bt = timings->bt;
+
+	/* Configure video port timings */
+
+	std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
+		bt->hsync - 8;
+	std_info->sav2eav = bt->width;
+
+	std_info->l1 = 1;
+	std_info->l3 = bt->vsync + bt->vbackporch + 1;
+
+	if (bt->interlaced) {
+		if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
+			std_info->vsize = bt->height * 2 +
+				bt->vfrontporch + bt->vsync + bt->vbackporch +
+				bt->il_vfrontporch + bt->il_vsync +
+				bt->il_vbackporch;
+			std_info->l5 = std_info->vsize/2 -
+				(bt->vfrontporch - 1);
+			std_info->l7 = std_info->vsize/2 + 1;
+			std_info->l9 = std_info->l7 + bt->il_vsync +
+				bt->il_vbackporch + 1;
+			std_info->l11 = std_info->vsize -
+				(bt->il_vfrontporch - 1);
+		} else {
+			vpif_dbg(2, debug, "Required timing values for "
+					"interlaced BT format missing\n");
+			return -EINVAL;
+		}
+	} else {
+		std_info->vsize = bt->height + bt->vfrontporch +
+			bt->vsync + bt->vbackporch;
+		std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
+	}
+	strncpy(std_info->name, "Custom timings BT656/1120", VPIF_MAX_NAME);
+	std_info->width = bt->width;
+	std_info->height = bt->height;
+	std_info->frm_fmt = bt->interlaced ? 0 : 1;
+	std_info->ycmux_mode = 0;
+	std_info->capture_format = 0;
+	std_info->vbi_supported = 0;
+	std_info->hd_sd = 1;
+	std_info->stdid = 0;
+	std_info->dv_preset = V4L2_DV_INVALID;
+
+	vid_ch->stdid = 0;
+	vid_ch->dv_preset = V4L2_DV_INVALID;
+	return 0;
+}
+
+/**
+ * vpif_g_dv_timings() - G_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: digital video timings
+ */
+static int vpif_g_dv_timings(struct file *file, void *priv,
+		struct v4l2_dv_timings *timings)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct video_obj *vid_ch = &ch->video;
+	struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
+
+	timings->bt = *bt;
+
+	return 0;
+}
+
+/*
+ * vpif_g_chip_ident() - Identify the chip
+ * @file: file ptr
+ * @priv: file handle
+ * @chip: chip identity
+ *
+ * Returns zero or -EINVAL if read operations fails.
+ */
+static int vpif_g_chip_ident(struct file *file, void *priv,
+		struct v4l2_dbg_chip_ident *chip)
+{
+	chip->ident = V4L2_IDENT_NONE;
+	chip->revision = 0;
+	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
+			chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
+		vpif_dbg(2, debug, "match_type is invalid.\n");
+		return -EINVAL;
+	}
+
+	return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
+			g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+/*
+ * vpif_dbg_g_register() - Read register
+ * @file: file ptr
+ * @priv: file handle
+ * @reg: register to be read
+ *
+ * Debugging only
+ * Returns zero or -EINVAL if read operations fails.
+ */
+static int vpif_dbg_g_register(struct file *file, void *priv,
+		struct v4l2_dbg_register *reg){
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
+			g_register, reg);
+}
+
+/*
+ * vpif_dbg_s_register() - Write to register
+ * @file: file ptr
+ * @priv: file handle
+ * @reg: register to be modified
+ *
+ * Debugging only
+ * Returns zero or -EINVAL if write operations fails.
+ */
+static int vpif_dbg_s_register(struct file *file, void *priv,
+		struct v4l2_dbg_register *reg){
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
+			s_register, reg);
+}
+#endif
+
+/*
+ * vpif_log_status() - Status information
+ * @file: file ptr
+ * @priv: file handle
+ *
+ * Returns zero.
+ */
+static int vpif_log_status(struct file *filep, void *priv)
+{
+	/* status for sub devices */
+	v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
+
+	return 0;
+}
+
 /* vpif capture ioctl operations */
 /* vpif capture ioctl operations */
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
 	.vidioc_querycap        	= vpif_querycap,
 	.vidioc_querycap        	= vpif_querycap,
@@ -1829,6 +2063,18 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
 	.vidioc_streamon        	= vpif_streamon,
 	.vidioc_streamon        	= vpif_streamon,
 	.vidioc_streamoff       	= vpif_streamoff,
 	.vidioc_streamoff       	= vpif_streamoff,
 	.vidioc_cropcap         	= vpif_cropcap,
 	.vidioc_cropcap         	= vpif_cropcap,
+	.vidioc_enum_dv_presets         = vpif_enum_dv_presets,
+	.vidioc_s_dv_preset             = vpif_s_dv_preset,
+	.vidioc_g_dv_preset             = vpif_g_dv_preset,
+	.vidioc_query_dv_preset         = vpif_query_dv_preset,
+	.vidioc_s_dv_timings            = vpif_s_dv_timings,
+	.vidioc_g_dv_timings            = vpif_g_dv_timings,
+	.vidioc_g_chip_ident		= vpif_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register		= vpif_dbg_g_register,
+	.vidioc_s_register		= vpif_dbg_s_register,
+#endif
+	.vidioc_log_status		= vpif_log_status,
 };
 };
 
 
 /* vpif file operations */
 /* vpif file operations */
@@ -1836,7 +2082,7 @@ static struct v4l2_file_operations vpif_fops = {
 	.owner = THIS_MODULE,
 	.owner = THIS_MODULE,
 	.open = vpif_open,
 	.open = vpif_open,
 	.release = vpif_release,
 	.release = vpif_release,
-	.ioctl = video_ioctl2,
+	.unlocked_ioctl = video_ioctl2,
 	.mmap = vpif_mmap,
 	.mmap = vpif_mmap,
 	.poll = vpif_poll
 	.poll = vpif_poll
 };
 };
@@ -1979,6 +2225,7 @@ static __init int vpif_probe(struct platform_device *pdev)
 		common = &(ch->common[VPIF_VIDEO_INDEX]);
 		common = &(ch->common[VPIF_VIDEO_INDEX]);
 		spin_lock_init(&common->irqlock);
 		spin_lock_init(&common->irqlock);
 		mutex_init(&common->lock);
 		mutex_init(&common->lock);
+		ch->video_dev->lock = &common->lock;
 		/* Initialize prio member of channel object */
 		/* Initialize prio member of channel object */
 		v4l2_prio_init(&ch->prio);
 		v4l2_prio_init(&ch->prio);
 		err = video_register_device(ch->video_dev,
 		err = video_register_device(ch->video_dev,
@@ -2026,9 +2273,9 @@ static __init int vpif_probe(struct platform_device *pdev)
 		if (vpif_obj.sd[i])
 		if (vpif_obj.sd[i])
 			vpif_obj.sd[i]->grp_id = 1 << i;
 			vpif_obj.sd[i]->grp_id = 1 << i;
 	}
 	}
-	v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF Capture driver"
-		  " initialized\n");
 
 
+	v4l2_info(&vpif_obj.v4l2_dev,
+			"DM646x VPIF capture driver initialized\n");
 	return 0;
 	return 0;
 
 
 probe_subdev_out:
 probe_subdev_out:

+ 2 - 0
drivers/media/video/davinci/vpif_capture.h

@@ -59,6 +59,8 @@ struct video_obj {
 	enum v4l2_field buf_field;
 	enum v4l2_field buf_field;
 	/* Currently selected or default standard */
 	/* Currently selected or default standard */
 	v4l2_std_id stdid;
 	v4l2_std_id stdid;
+	u32 dv_preset;
+	struct v4l2_bt_timings bt_timings;
 	/* This is to track the last input that is passed to application */
 	/* This is to track the last input that is passed to application */
 	u32 input_idx;
 	u32 input_idx;
 };
 };

+ 367 - 107
drivers/media/video/davinci/vpif_display.c

@@ -38,6 +38,7 @@
 #include <media/adv7343.h>
 #include <media/adv7343.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
 
 
 #include <mach/dm646x.h>
 #include <mach/dm646x.h>
 
 
@@ -84,17 +85,6 @@ static struct vpif_config_params config_params = {
 static struct vpif_device vpif_obj = { {NULL} };
 static struct vpif_device vpif_obj = { {NULL} };
 static struct device *vpif_dev;
 static struct device *vpif_dev;
 
 
-static const struct vpif_channel_config_params ch_params[] = {
-	{
-		"NTSC", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
-		286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
-	},
-	{
-		"PAL", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
-		336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
-	},
-};
-
 /*
 /*
  * vpif_uservirt_to_phys: This function is used to convert user
  * vpif_uservirt_to_phys: This function is used to convert user
  * space virtual address to physical address.
  * space virtual address to physical address.
@@ -373,30 +363,54 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-static int vpif_get_std_info(struct channel_obj *ch)
+static int vpif_update_std_info(struct channel_obj *ch)
 {
 {
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct video_obj *vid_ch = &ch->video;
 	struct video_obj *vid_ch = &ch->video;
 	struct vpif_params *vpifparams = &ch->vpifparams;
 	struct vpif_params *vpifparams = &ch->vpifparams;
 	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
 	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
 	const struct vpif_channel_config_params *config;
 	const struct vpif_channel_config_params *config;
 
 
-	int index;
-
-	std_info->stdid = vid_ch->stdid;
-	if (!std_info->stdid)
-		return -1;
+	int i;
 
 
-	for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
-		config = &ch_params[index];
-		if (config->stdid & std_info->stdid) {
-			memcpy(std_info, config, sizeof(*config));
-			break;
+	for (i = 0; i < vpif_ch_params_count; i++) {
+		config = &ch_params[i];
+		if (config->hd_sd == 0) {
+			vpif_dbg(2, debug, "SD format\n");
+			if (config->stdid & vid_ch->stdid) {
+				memcpy(std_info, config, sizeof(*config));
+				break;
+			}
+		} else {
+			vpif_dbg(2, debug, "HD format\n");
+			if (config->dv_preset == vid_ch->dv_preset) {
+				memcpy(std_info, config, sizeof(*config));
+				break;
+			}
 		}
 		}
 	}
 	}
 
 
-	if (index == ARRAY_SIZE(ch_params))
-		return -1;
+	if (i == vpif_ch_params_count) {
+		vpif_dbg(1, debug, "Format not found\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vpif_update_resolution(struct channel_obj *ch)
+{
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct video_obj *vid_ch = &ch->video;
+	struct vpif_params *vpifparams = &ch->vpifparams;
+	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+
+	if (!vid_ch->stdid && !vid_ch->dv_preset && !vid_ch->bt_timings.height)
+		return -EINVAL;
+
+	if (vid_ch->stdid || vid_ch->dv_preset) {
+		if (vpif_update_std_info(ch))
+			return -EINVAL;
+	}
 
 
 	common->fmt.fmt.pix.width = std_info->width;
 	common->fmt.fmt.pix.width = std_info->width;
 	common->fmt.fmt.pix.height = std_info->height;
 	common->fmt.fmt.pix.height = std_info->height;
@@ -404,8 +418,8 @@ static int vpif_get_std_info(struct channel_obj *ch)
 			common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
 			common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
 
 
 	/* Set height and width paramateres */
 	/* Set height and width paramateres */
-	ch->common[VPIF_VIDEO_INDEX].height = std_info->height;
-	ch->common[VPIF_VIDEO_INDEX].width = std_info->width;
+	common->height = std_info->height;
+	common->width = std_info->width;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -516,10 +530,8 @@ static int vpif_check_format(struct channel_obj *ch,
 	else
 	else
 		sizeimage = config_params.channel_bufsize[ch->channel_id];
 		sizeimage = config_params.channel_bufsize[ch->channel_id];
 
 
-	if (vpif_get_std_info(ch)) {
-		vpif_err("Error getting the standard info\n");
+	if (vpif_update_resolution(ch))
 		return -EINVAL;
 		return -EINVAL;
-	}
 
 
 	hpitch = pixfmt->bytesperline;
 	hpitch = pixfmt->bytesperline;
 	vpitch = sizeimage / (hpitch * 2);
 	vpitch = sizeimage / (hpitch * 2);
@@ -568,7 +580,10 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
 static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
 static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
 {
 {
 	struct vpif_fh *fh = filep->private_data;
 	struct vpif_fh *fh = filep->private_data;
-	struct common_obj *common = &fh->channel->common[VPIF_VIDEO_INDEX];
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
+
+	vpif_dbg(2, debug, "vpif_mmap\n");
 
 
 	return videobuf_mmap_mapper(&common->buffer_queue, vma);
 	return videobuf_mmap_mapper(&common->buffer_queue, vma);
 }
 }
@@ -637,9 +652,6 @@ static int vpif_release(struct file *filep)
 	struct channel_obj *ch = fh->channel;
 	struct channel_obj *ch = fh->channel;
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	/* if this instance is doing IO */
 	/* if this instance is doing IO */
 	if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
 	if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
 		/* Reset io_usrs member of channel object */
 		/* Reset io_usrs member of channel object */
@@ -662,8 +674,6 @@ static int vpif_release(struct file *filep)
 		    config_params.numbuffers[ch->channel_id];
 		    config_params.numbuffers[ch->channel_id];
 	}
 	}
 
 
-	mutex_unlock(&common->lock);
-
 	/* Decrement channel usrs counter */
 	/* Decrement channel usrs counter */
 	atomic_dec(&ch->usrs);
 	atomic_dec(&ch->usrs);
 	/* If this file handle has initialize encoder device, reset it */
 	/* If this file handle has initialize encoder device, reset it */
@@ -680,7 +690,12 @@ static int vpif_release(struct file *filep)
 }
 }
 
 
 /* functions implementing ioctls */
 /* functions implementing ioctls */
-
+/**
+ * vpif_querycap() - QUERYCAP handler
+ * @file: file ptr
+ * @priv: file handle
+ * @cap: ptr to v4l2_capability structure
+ */
 static int vpif_querycap(struct file *file, void  *priv,
 static int vpif_querycap(struct file *file, void  *priv,
 				struct v4l2_capability *cap)
 				struct v4l2_capability *cap)
 {
 {
@@ -722,17 +737,9 @@ static int vpif_g_fmt_vid_out(struct file *file, void *priv,
 	if (common->fmt.type != fmt->type)
 	if (common->fmt.type != fmt->type)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	/* Fill in the information about format */
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
-	if (vpif_get_std_info(ch)) {
-		vpif_err("Error getting the standard info\n");
+	if (vpif_update_resolution(ch))
 		return -EINVAL;
 		return -EINVAL;
-	}
-
 	*fmt = common->fmt;
 	*fmt = common->fmt;
-	mutex_unlock(&common->lock);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -773,12 +780,7 @@ static int vpif_s_fmt_vid_out(struct file *file, void *priv,
 	/* store the pix format in the channel object */
 	/* store the pix format in the channel object */
 	common->fmt.fmt.pix = *pixfmt;
 	common->fmt.fmt.pix = *pixfmt;
 	/* store the format in the channel object */
 	/* store the format in the channel object */
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	common->fmt = *fmt;
 	common->fmt = *fmt;
-	mutex_unlock(&common->lock);
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -808,7 +810,6 @@ static int vpif_reqbufs(struct file *file, void *priv,
 	struct common_obj *common;
 	struct common_obj *common;
 	enum v4l2_field field;
 	enum v4l2_field field;
 	u8 index = 0;
 	u8 index = 0;
-	int ret = 0;
 
 
 	/* This file handle has not initialized the channel,
 	/* This file handle has not initialized the channel,
 	   It is not allowed to do settings */
 	   It is not allowed to do settings */
@@ -826,18 +827,12 @@ static int vpif_reqbufs(struct file *file, void *priv,
 	index = VPIF_VIDEO_INDEX;
 	index = VPIF_VIDEO_INDEX;
 
 
 	common = &ch->common[index];
 	common = &ch->common[index];
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
 
 
-	if (common->fmt.type != reqbuf->type) {
-		ret = -EINVAL;
-		goto reqbuf_exit;
-	}
+	if (common->fmt.type != reqbuf->type)
+		return -EINVAL;
 
 
-	if (0 != common->io_usrs) {
-		ret = -EBUSY;
-		goto reqbuf_exit;
-	}
+	if (0 != common->io_usrs)
+		return -EBUSY;
 
 
 	if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
 	if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
 		if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
 		if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
@@ -854,7 +849,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
 					    &common->irqlock,
 					    &common->irqlock,
 					    reqbuf->type, field,
 					    reqbuf->type, field,
 					    sizeof(struct videobuf_buffer), fh,
 					    sizeof(struct videobuf_buffer), fh,
-					    NULL);
+					    &common->lock);
 
 
 	/* Set io allowed member of file handle to TRUE */
 	/* Set io allowed member of file handle to TRUE */
 	fh->io_allowed[index] = 1;
 	fh->io_allowed[index] = 1;
@@ -865,11 +860,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
 	INIT_LIST_HEAD(&common->dma_queue);
 	INIT_LIST_HEAD(&common->dma_queue);
 
 
 	/* Allocate buffers */
 	/* Allocate buffers */
-	ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
-
-reqbuf_exit:
-	mutex_unlock(&common->lock);
-	return ret;
+	return videobuf_reqbufs(&common->buffer_queue, reqbuf);
 }
 }
 
 
 static int vpif_querybuf(struct file *file, void *priv,
 static int vpif_querybuf(struct file *file, void *priv,
@@ -990,22 +981,19 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
 	}
 	}
 
 
 	/* Call encoder subdevice function to set the standard */
 	/* Call encoder subdevice function to set the standard */
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	ch->video.stdid = *std_id;
 	ch->video.stdid = *std_id;
+	ch->video.dv_preset = V4L2_DV_INVALID;
+	memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
+
 	/* Get the information about the standard */
 	/* Get the information about the standard */
-	if (vpif_get_std_info(ch)) {
-		vpif_err("Error getting the standard info\n");
+	if (vpif_update_resolution(ch))
 		return -EINVAL;
 		return -EINVAL;
-	}
 
 
 	if ((ch->vpifparams.std_info.width *
 	if ((ch->vpifparams.std_info.width *
 		ch->vpifparams.std_info.height * 2) >
 		ch->vpifparams.std_info.height * 2) >
 		config_params.channel_bufsize[ch->channel_id]) {
 		config_params.channel_bufsize[ch->channel_id]) {
 		vpif_err("invalid std for this size\n");
 		vpif_err("invalid std for this size\n");
-		ret = -EINVAL;
-		goto s_std_exit;
+		return -EINVAL;
 	}
 	}
 
 
 	common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
 	common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
@@ -1016,16 +1004,13 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
 						s_std_output, *std_id);
 						s_std_output, *std_id);
 	if (ret < 0) {
 	if (ret < 0) {
 		vpif_err("Failed to set output standard\n");
 		vpif_err("Failed to set output standard\n");
-		goto s_std_exit;
+		return ret;
 	}
 	}
 
 
 	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
 	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
 							s_std, *std_id);
 							s_std, *std_id);
 	if (ret < 0)
 	if (ret < 0)
 		vpif_err("Failed to set standard for sub devices\n");
 		vpif_err("Failed to set standard for sub devices\n");
-
-s_std_exit:
-	mutex_unlock(&common->lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1090,21 +1075,17 @@ static int vpif_streamon(struct file *file, void *priv,
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
-	/* Call videobuf_streamon to start streaming  in videobuf */
+	/* Call videobuf_streamon to start streaming in videobuf */
 	ret = videobuf_streamon(&common->buffer_queue);
 	ret = videobuf_streamon(&common->buffer_queue);
 	if (ret < 0) {
 	if (ret < 0) {
 		vpif_err("videobuf_streamon\n");
 		vpif_err("videobuf_streamon\n");
 		return ret;
 		return ret;
 	}
 	}
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	/* If buffer queue is empty, return error */
 	/* If buffer queue is empty, return error */
 	if (list_empty(&common->dma_queue)) {
 	if (list_empty(&common->dma_queue)) {
 		vpif_err("buffer queue is empty\n");
 		vpif_err("buffer queue is empty\n");
-		ret = -EIO;
-		goto streamon_exit;
+		return -EIO;
 	}
 	}
 
 
 	/* Get the next frame from the buffer queue */
 	/* Get the next frame from the buffer queue */
@@ -1130,8 +1111,7 @@ static int vpif_streamon(struct file *file, void *priv,
 			|| (!ch->vpifparams.std_info.frm_fmt
 			|| (!ch->vpifparams.std_info.frm_fmt
 			&& (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
 			&& (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
 			vpif_err("conflict in field format and std format\n");
 			vpif_err("conflict in field format and std format\n");
-			ret = -EINVAL;
-			goto streamon_exit;
+			return -EINVAL;
 		}
 		}
 
 
 		/* clock settings */
 		/* clock settings */
@@ -1140,13 +1120,13 @@ static int vpif_streamon(struct file *file, void *priv,
 						ch->vpifparams.std_info.hd_sd);
 						ch->vpifparams.std_info.hd_sd);
 		if (ret < 0) {
 		if (ret < 0) {
 			vpif_err("can't set clock\n");
 			vpif_err("can't set clock\n");
-			goto streamon_exit;
+			return ret;
 		}
 		}
 
 
 		/* set the parameters and addresses */
 		/* set the parameters and addresses */
 		ret = vpif_set_video_params(vpif, ch->channel_id + 2);
 		ret = vpif_set_video_params(vpif, ch->channel_id + 2);
 		if (ret < 0)
 		if (ret < 0)
-			goto streamon_exit;
+			return ret;
 
 
 		common->started = ret;
 		common->started = ret;
 		vpif_config_addr(ch, ret);
 		vpif_config_addr(ch, ret);
@@ -1171,9 +1151,6 @@ static int vpif_streamon(struct file *file, void *priv,
 		}
 		}
 		channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
 		channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
 	}
 	}
-
-streamon_exit:
-	mutex_unlock(&common->lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1199,9 +1176,6 @@ static int vpif_streamoff(struct file *file, void *priv,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
 	if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
 		/* disable channel */
 		/* disable channel */
 		if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
 		if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
@@ -1216,8 +1190,6 @@ static int vpif_streamoff(struct file *file, void *priv,
 	}
 	}
 
 
 	common->started = 0;
 	common->started = 0;
-	mutex_unlock(&common->lock);
-
 	return videobuf_streamoff(&common->buffer_queue);
 	return videobuf_streamoff(&common->buffer_queue);
 }
 }
 
 
@@ -1264,13 +1236,9 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i)
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	int ret = 0;
 	int ret = 0;
 
 
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-
 	if (common->started) {
 	if (common->started) {
 		vpif_err("Streaming in progress\n");
 		vpif_err("Streaming in progress\n");
-		ret = -EBUSY;
-		goto s_output_exit;
+		return -EBUSY;
 	}
 	}
 
 
 	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
 	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
@@ -1280,9 +1248,6 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i)
 		vpif_err("Failed to set output standard\n");
 		vpif_err("Failed to set output standard\n");
 
 
 	vid_ch->output_id = i;
 	vid_ch->output_id = i;
-
-s_output_exit:
-	mutex_unlock(&common->lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1315,6 +1280,287 @@ static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
 	return v4l2_prio_change(&ch->prio, &fh->prio, p);
 	return v4l2_prio_change(&ch->prio, &fh->prio, p);
 }
 }
 
 
+/**
+ * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @preset: input preset
+ */
+static int vpif_enum_dv_presets(struct file *file, void *priv,
+		struct v4l2_dv_enum_preset *preset)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct video_obj *vid_ch = &ch->video;
+
+	return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
+			video, enum_dv_presets, preset);
+}
+
+/**
+ * vpif_s_dv_presets() - S_DV_PRESETS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @preset: input preset
+ */
+static int vpif_s_dv_preset(struct file *file, void *priv,
+		struct v4l2_dv_preset *preset)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct video_obj *vid_ch = &ch->video;
+	int ret = 0;
+
+	if (common->started) {
+		vpif_dbg(1, debug, "streaming in progress\n");
+		return -EBUSY;
+	}
+
+	ret = v4l2_prio_check(&ch->prio, fh->prio);
+	if (ret != 0)
+		return ret;
+
+	fh->initialized = 1;
+
+	/* Call encoder subdevice function to set the standard */
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	ch->video.dv_preset = preset->preset;
+	ch->video.stdid = V4L2_STD_UNKNOWN;
+	memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
+
+	/* Get the information about the standard */
+	if (vpif_update_resolution(ch)) {
+		ret = -EINVAL;
+	} else {
+		/* Configure the default format information */
+		vpif_config_format(ch);
+
+		ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
+				video, s_dv_preset, preset);
+	}
+
+	mutex_unlock(&common->lock);
+
+	return ret;
+}
+/**
+ * vpif_g_dv_presets() - G_DV_PRESETS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @preset: input preset
+ */
+static int vpif_g_dv_preset(struct file *file, void *priv,
+		struct v4l2_dv_preset *preset)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	preset->preset = ch->video.dv_preset;
+
+	return 0;
+}
+/**
+ * vpif_s_dv_timings() - S_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: digital video timings
+ */
+static int vpif_s_dv_timings(struct file *file, void *priv,
+		struct v4l2_dv_timings *timings)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct vpif_params *vpifparams = &ch->vpifparams;
+	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+	struct video_obj *vid_ch = &ch->video;
+	struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
+	int ret;
+
+	if (timings->type != V4L2_DV_BT_656_1120) {
+		vpif_dbg(2, debug, "Timing type not defined\n");
+		return -EINVAL;
+	}
+
+	/* Configure subdevice timings, if any */
+	ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
+			video, s_dv_timings, timings);
+	if (ret == -ENOIOCTLCMD) {
+		vpif_dbg(2, debug, "Custom DV timings not supported by "
+				"subdevice\n");
+		return -EINVAL;
+	}
+	if (ret < 0) {
+		vpif_dbg(2, debug, "Error setting custom DV timings\n");
+		return ret;
+	}
+
+	if (!(timings->bt.width && timings->bt.height &&
+				(timings->bt.hbackporch ||
+				 timings->bt.hfrontporch ||
+				 timings->bt.hsync) &&
+				timings->bt.vfrontporch &&
+				(timings->bt.vbackporch ||
+				 timings->bt.vsync))) {
+		vpif_dbg(2, debug, "Timings for width, height, "
+				"horizontal back porch, horizontal sync, "
+				"horizontal front porch, vertical back porch, "
+				"vertical sync and vertical back porch "
+				"must be defined\n");
+		return -EINVAL;
+	}
+
+	*bt = timings->bt;
+
+	/* Configure video port timings */
+
+	std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
+		bt->hsync - 8;
+	std_info->sav2eav = bt->width;
+
+	std_info->l1 = 1;
+	std_info->l3 = bt->vsync + bt->vbackporch + 1;
+
+	if (bt->interlaced) {
+		if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
+			std_info->vsize = bt->height * 2 +
+				bt->vfrontporch + bt->vsync + bt->vbackporch +
+				bt->il_vfrontporch + bt->il_vsync +
+				bt->il_vbackporch;
+			std_info->l5 = std_info->vsize/2 -
+				(bt->vfrontporch - 1);
+			std_info->l7 = std_info->vsize/2 + 1;
+			std_info->l9 = std_info->l7 + bt->il_vsync +
+				bt->il_vbackporch + 1;
+			std_info->l11 = std_info->vsize -
+				(bt->il_vfrontporch - 1);
+		} else {
+			vpif_dbg(2, debug, "Required timing values for "
+					"interlaced BT format missing\n");
+			return -EINVAL;
+		}
+	} else {
+		std_info->vsize = bt->height + bt->vfrontporch +
+			bt->vsync + bt->vbackporch;
+		std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
+	}
+	strncpy(std_info->name, "Custom timings BT656/1120",
+			VPIF_MAX_NAME);
+	std_info->width = bt->width;
+	std_info->height = bt->height;
+	std_info->frm_fmt = bt->interlaced ? 0 : 1;
+	std_info->ycmux_mode = 0;
+	std_info->capture_format = 0;
+	std_info->vbi_supported = 0;
+	std_info->hd_sd = 1;
+	std_info->stdid = 0;
+	std_info->dv_preset = V4L2_DV_INVALID;
+
+	vid_ch->stdid = 0;
+	vid_ch->dv_preset = V4L2_DV_INVALID;
+
+	return 0;
+}
+
+/**
+ * vpif_g_dv_timings() - G_DV_TIMINGS handler
+ * @file: file ptr
+ * @priv: file handle
+ * @timings: digital video timings
+ */
+static int vpif_g_dv_timings(struct file *file, void *priv,
+		struct v4l2_dv_timings *timings)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct video_obj *vid_ch = &ch->video;
+	struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
+
+	timings->bt = *bt;
+
+	return 0;
+}
+
+/*
+ * vpif_g_chip_ident() - Identify the chip
+ * @file: file ptr
+ * @priv: file handle
+ * @chip: chip identity
+ *
+ * Returns zero or -EINVAL if read operations fails.
+ */
+static int vpif_g_chip_ident(struct file *file, void *priv,
+		struct v4l2_dbg_chip_ident *chip)
+{
+	chip->ident = V4L2_IDENT_NONE;
+	chip->revision = 0;
+	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
+			chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
+		vpif_dbg(2, debug, "match_type is invalid.\n");
+		return -EINVAL;
+	}
+
+	return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
+			g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+/*
+ * vpif_dbg_g_register() - Read register
+ * @file: file ptr
+ * @priv: file handle
+ * @reg: register to be read
+ *
+ * Debugging only
+ * Returns zero or -EINVAL if read operations fails.
+ */
+static int vpif_dbg_g_register(struct file *file, void *priv,
+		struct v4l2_dbg_register *reg){
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct video_obj *vid_ch = &ch->video;
+
+	return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
+			g_register, reg);
+}
+
+/*
+ * vpif_dbg_s_register() - Write to register
+ * @file: file ptr
+ * @priv: file handle
+ * @reg: register to be modified
+ *
+ * Debugging only
+ * Returns zero or -EINVAL if write operations fails.
+ */
+static int vpif_dbg_s_register(struct file *file, void *priv,
+		struct v4l2_dbg_register *reg){
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct video_obj *vid_ch = &ch->video;
+
+	return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
+			s_register, reg);
+}
+#endif
+
+/*
+ * vpif_log_status() - Status information
+ * @file: file ptr
+ * @priv: file handle
+ *
+ * Returns zero.
+ */
+static int vpif_log_status(struct file *filep, void *priv)
+{
+	/* status for sub devices */
+	v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
+
+	return 0;
+}
+
 /* vpif display ioctl operations */
 /* vpif display ioctl operations */
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
 	.vidioc_querycap        	= vpif_querycap,
 	.vidioc_querycap        	= vpif_querycap,
@@ -1336,13 +1582,24 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
 	.vidioc_s_output		= vpif_s_output,
 	.vidioc_s_output		= vpif_s_output,
 	.vidioc_g_output		= vpif_g_output,
 	.vidioc_g_output		= vpif_g_output,
 	.vidioc_cropcap         	= vpif_cropcap,
 	.vidioc_cropcap         	= vpif_cropcap,
+	.vidioc_enum_dv_presets         = vpif_enum_dv_presets,
+	.vidioc_s_dv_preset             = vpif_s_dv_preset,
+	.vidioc_g_dv_preset             = vpif_g_dv_preset,
+	.vidioc_s_dv_timings            = vpif_s_dv_timings,
+	.vidioc_g_dv_timings            = vpif_g_dv_timings,
+	.vidioc_g_chip_ident		= vpif_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register		= vpif_dbg_g_register,
+	.vidioc_s_register		= vpif_dbg_s_register,
+#endif
+	.vidioc_log_status		= vpif_log_status,
 };
 };
 
 
 static const struct v4l2_file_operations vpif_fops = {
 static const struct v4l2_file_operations vpif_fops = {
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
 	.open		= vpif_open,
 	.open		= vpif_open,
 	.release	= vpif_release,
 	.release	= vpif_release,
-	.ioctl		= video_ioctl2,
+	.unlocked_ioctl	= video_ioctl2,
 	.mmap		= vpif_mmap,
 	.mmap		= vpif_mmap,
 	.poll		= vpif_poll
 	.poll		= vpif_poll
 };
 };
@@ -1526,6 +1783,7 @@ static __init int vpif_probe(struct platform_device *pdev)
 		v4l2_prio_init(&ch->prio);
 		v4l2_prio_init(&ch->prio);
 		ch->common[VPIF_VIDEO_INDEX].fmt.type =
 		ch->common[VPIF_VIDEO_INDEX].fmt.type =
 						V4L2_BUF_TYPE_VIDEO_OUTPUT;
 						V4L2_BUF_TYPE_VIDEO_OUTPUT;
+		ch->video_dev->lock = &common->lock;
 
 
 		/* register video device */
 		/* register video device */
 		vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
 		vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
@@ -1565,6 +1823,8 @@ static __init int vpif_probe(struct platform_device *pdev)
 			vpif_obj.sd[i]->grp_id = 1 << i;
 			vpif_obj.sd[i]->grp_id = 1 << i;
 	}
 	}
 
 
+	v4l2_info(&vpif_obj.v4l2_dev,
+			"DM646x VPIF display driver initialized\n");
 	return 0;
 	return 0;
 
 
 probe_subdev_out:
 probe_subdev_out:

+ 2 - 0
drivers/media/video/davinci/vpif_display.h

@@ -67,6 +67,8 @@ struct video_obj {
 					 * most recent displayed frame only */
 					 * most recent displayed frame only */
 	v4l2_std_id stdid;		/* Currently selected or default
 	v4l2_std_id stdid;		/* Currently selected or default
 					 * standard */
 					 * standard */
+	u32 dv_preset;
+	struct v4l2_bt_timings bt_timings;
 	u32 output_id;			/* Current output id */
 	u32 output_id;			/* Current output id */
 };
 };
 
 

+ 11 - 8
drivers/media/video/em28xx/em28xx-cards.c

@@ -33,6 +33,7 @@
 #include <media/saa7115.h>
 #include <media/saa7115.h>
 #include <media/tvp5150.h>
 #include <media/tvp5150.h>
 #include <media/tvaudio.h>
 #include <media/tvaudio.h>
+#include <media/mt9v011.h>
 #include <media/i2c-addr.h>
 #include <media/i2c-addr.h>
 #include <media/tveeprom.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
@@ -1917,11 +1918,6 @@ static unsigned short tvp5150_addrs[] = {
 	I2C_CLIENT_END
 	I2C_CLIENT_END
 };
 };
 
 
-static unsigned short mt9v011_addrs[] = {
-	0xba >> 1,
-	I2C_CLIENT_END
-};
-
 static unsigned short msp3400_addrs[] = {
 static unsigned short msp3400_addrs[] = {
 	0x80 >> 1,
 	0x80 >> 1,
 	0x88 >> 1,
 	0x88 >> 1,
@@ -2437,6 +2433,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
 		dev->init_data.ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW;
 		dev->init_data.ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW;
 		dev->init_data.get_key = em28xx_get_key_em_haup;
 		dev->init_data.get_key = em28xx_get_key_em_haup;
 		dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
 		dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
+		break;
 	case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
 	case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
 		dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
 		dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
 		dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
 		dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
@@ -2623,11 +2620,17 @@ void em28xx_card_setup(struct em28xx *dev)
 			"tvp5150", 0, tvp5150_addrs);
 			"tvp5150", 0, tvp5150_addrs);
 
 
 	if (dev->em28xx_sensor == EM28XX_MT9V011) {
 	if (dev->em28xx_sensor == EM28XX_MT9V011) {
+		struct mt9v011_platform_data pdata;
+		struct i2c_board_info mt9v011_info = {
+			.type = "mt9v011",
+			.addr = 0xba >> 1,
+			.platform_data = &pdata,
+		};
 		struct v4l2_subdev *sd;
 		struct v4l2_subdev *sd;
 
 
-		sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
-			 &dev->i2c_adap, "mt9v011", 0, mt9v011_addrs);
-		v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
+		pdata.xtal = dev->sensor_xtal;
+		sd = v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap,
+				&mt9v011_info, NULL);
 	}
 	}
 
 
 
 

+ 0 - 24
drivers/media/video/et61x251/et61x251.h

@@ -59,31 +59,7 @@
 /*****************************************************************************/
 /*****************************************************************************/
 
 
 static const struct usb_device_id et61x251_id_table[] = {
 static const struct usb_device_id et61x251_id_table[] = {
-	{ USB_DEVICE(0x102c, 0x6151), },
 	{ USB_DEVICE(0x102c, 0x6251), },
 	{ USB_DEVICE(0x102c, 0x6251), },
-	{ USB_DEVICE(0x102c, 0x6253), },
-	{ USB_DEVICE(0x102c, 0x6254), },
-	{ USB_DEVICE(0x102c, 0x6255), },
-	{ USB_DEVICE(0x102c, 0x6256), },
-	{ USB_DEVICE(0x102c, 0x6257), },
-	{ USB_DEVICE(0x102c, 0x6258), },
-	{ USB_DEVICE(0x102c, 0x6259), },
-	{ USB_DEVICE(0x102c, 0x625a), },
-	{ USB_DEVICE(0x102c, 0x625b), },
-	{ USB_DEVICE(0x102c, 0x625c), },
-	{ USB_DEVICE(0x102c, 0x625d), },
-	{ USB_DEVICE(0x102c, 0x625e), },
-	{ USB_DEVICE(0x102c, 0x625f), },
-	{ USB_DEVICE(0x102c, 0x6260), },
-	{ USB_DEVICE(0x102c, 0x6261), },
-	{ USB_DEVICE(0x102c, 0x6262), },
-	{ USB_DEVICE(0x102c, 0x6263), },
-	{ USB_DEVICE(0x102c, 0x6264), },
-	{ USB_DEVICE(0x102c, 0x6265), },
-	{ USB_DEVICE(0x102c, 0x6266), },
-	{ USB_DEVICE(0x102c, 0x6267), },
-	{ USB_DEVICE(0x102c, 0x6268), },
-	{ USB_DEVICE(0x102c, 0x6269), },
 	{ }
 	{ }
 };
 };
 
 

+ 1 - 1
drivers/media/video/gspca/benq.c

@@ -276,7 +276,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x04a5, 0x3035)},
 	{USB_DEVICE(0x04a5, 0x3035)},
 	{}
 	{}
 };
 };

+ 2 - 2
drivers/media/video/gspca/conex.c

@@ -1040,14 +1040,14 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0572, 0x0041)},
 	{USB_DEVICE(0x0572, 0x0041)},
 	{}
 	{}
 };
 };
 MODULE_DEVICE_TABLE(usb, device_table);
 MODULE_DEVICE_TABLE(usb, device_table);
 
 
 /* -- device connect -- */
 /* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 			const struct usb_device_id *id)
 {
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

+ 1 - 1
drivers/media/video/gspca/cpia1.c

@@ -2088,7 +2088,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0553, 0x0002)},
 	{USB_DEVICE(0x0553, 0x0002)},
 	{USB_DEVICE(0x0813, 0x0001)},
 	{USB_DEVICE(0x0813, 0x0001)},
 	{}
 	{}

+ 2 - 2
drivers/media/video/gspca/etoms.c

@@ -864,7 +864,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
 	{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
 #if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
 #if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
 	{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
 	{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
@@ -875,7 +875,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
 MODULE_DEVICE_TABLE(usb, device_table);
 MODULE_DEVICE_TABLE(usb, device_table);
 
 
 /* -- device connect -- */
 /* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
 		    const struct usb_device_id *id)
 		    const struct usb_device_id *id)
 {
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

+ 1 - 1
drivers/media/video/gspca/finepix.c

@@ -229,7 +229,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
 }
 }
 
 
 /* Table of supported USB devices */
 /* Table of supported USB devices */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x04cb, 0x0104)},
 	{USB_DEVICE(0x04cb, 0x0104)},
 	{USB_DEVICE(0x04cb, 0x0109)},
 	{USB_DEVICE(0x04cb, 0x0109)},
 	{USB_DEVICE(0x04cb, 0x010b)},
 	{USB_DEVICE(0x04cb, 0x010b)},

+ 1 - 1
drivers/media/video/gspca/gl860/gl860.c

@@ -488,7 +488,7 @@ static void sd_callback(struct gspca_dev *gspca_dev)
 
 
 /*=================== USB driver structure initialisation ==================*/
 /*=================== USB driver structure initialisation ==================*/
 
 
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x05e3, 0x0503)},
 	{USB_DEVICE(0x05e3, 0x0503)},
 	{USB_DEVICE(0x05e3, 0xf191)},
 	{USB_DEVICE(0x05e3, 0xf191)},
 	{}
 	{}

+ 95 - 115
drivers/media/video/gspca/gspca.c

@@ -55,7 +55,7 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 11, 0)
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 12, 0)
 
 
 #ifdef GSPCA_DEBUG
 #ifdef GSPCA_DEBUG
 int gspca_debug = D_ERR | D_PROBE;
 int gspca_debug = D_ERR | D_PROBE;
@@ -508,8 +508,8 @@ static int gspca_is_compressed(__u32 format)
 	return 0;
 	return 0;
 }
 }
 
 
-static int frame_alloc(struct gspca_dev *gspca_dev,
-			unsigned int count)
+static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file,
+			enum v4l2_memory memory, unsigned int count)
 {
 {
 	struct gspca_frame *frame;
 	struct gspca_frame *frame;
 	unsigned int frsz;
 	unsigned int frsz;
@@ -519,7 +519,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
 	frsz = gspca_dev->cam.cam_mode[i].sizeimage;
 	frsz = gspca_dev->cam.cam_mode[i].sizeimage;
 	PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
 	PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
 	frsz = PAGE_ALIGN(frsz);
 	frsz = PAGE_ALIGN(frsz);
-	gspca_dev->frsz = frsz;
 	if (count >= GSPCA_MAX_FRAMES)
 	if (count >= GSPCA_MAX_FRAMES)
 		count = GSPCA_MAX_FRAMES - 1;
 		count = GSPCA_MAX_FRAMES - 1;
 	gspca_dev->frbuf = vmalloc_32(frsz * count);
 	gspca_dev->frbuf = vmalloc_32(frsz * count);
@@ -527,6 +526,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
 		err("frame alloc failed");
 		err("frame alloc failed");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
+	gspca_dev->capt_file = file;
+	gspca_dev->memory = memory;
+	gspca_dev->frsz = frsz;
 	gspca_dev->nframes = count;
 	gspca_dev->nframes = count;
 	for (i = 0; i < count; i++) {
 	for (i = 0; i < count; i++) {
 		frame = &gspca_dev->frame[i];
 		frame = &gspca_dev->frame[i];
@@ -535,7 +537,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
 		frame->v4l2_buf.flags = 0;
 		frame->v4l2_buf.flags = 0;
 		frame->v4l2_buf.field = V4L2_FIELD_NONE;
 		frame->v4l2_buf.field = V4L2_FIELD_NONE;
 		frame->v4l2_buf.length = frsz;
 		frame->v4l2_buf.length = frsz;
-		frame->v4l2_buf.memory = gspca_dev->memory;
+		frame->v4l2_buf.memory = memory;
 		frame->v4l2_buf.sequence = 0;
 		frame->v4l2_buf.sequence = 0;
 		frame->data = gspca_dev->frbuf + i * frsz;
 		frame->data = gspca_dev->frbuf + i * frsz;
 		frame->v4l2_buf.m.offset = i * frsz;
 		frame->v4l2_buf.m.offset = i * frsz;
@@ -558,6 +560,9 @@ static void frame_free(struct gspca_dev *gspca_dev)
 			gspca_dev->frame[i].data = NULL;
 			gspca_dev->frame[i].data = NULL;
 	}
 	}
 	gspca_dev->nframes = 0;
 	gspca_dev->nframes = 0;
+	gspca_dev->frsz = 0;
+	gspca_dev->capt_file = NULL;
+	gspca_dev->memory = GSPCA_MEMORY_NO;
 }
 }
 
 
 static void destroy_urbs(struct gspca_dev *gspca_dev)
 static void destroy_urbs(struct gspca_dev *gspca_dev)
@@ -1210,29 +1215,15 @@ static void gspca_release(struct video_device *vfd)
 static int dev_open(struct file *file)
 static int dev_open(struct file *file)
 {
 {
 	struct gspca_dev *gspca_dev;
 	struct gspca_dev *gspca_dev;
-	int ret;
 
 
 	PDEBUG(D_STREAM, "[%s] open", current->comm);
 	PDEBUG(D_STREAM, "[%s] open", current->comm);
 	gspca_dev = (struct gspca_dev *) video_devdata(file);
 	gspca_dev = (struct gspca_dev *) video_devdata(file);
-	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
-		return -ERESTARTSYS;
-	if (!gspca_dev->present) {
-		ret = -ENODEV;
-		goto out;
-	}
-
-	if (gspca_dev->users > 4) {	/* (arbitrary value) */
-		ret = -EBUSY;
-		goto out;
-	}
+	if (!gspca_dev->present)
+		return -ENODEV;
 
 
 	/* protect the subdriver against rmmod */
 	/* protect the subdriver against rmmod */
-	if (!try_module_get(gspca_dev->module)) {
-		ret = -ENODEV;
-		goto out;
-	}
-
-	gspca_dev->users++;
+	if (!try_module_get(gspca_dev->module))
+		return -ENODEV;
 
 
 	file->private_data = gspca_dev;
 	file->private_data = gspca_dev;
 #ifdef GSPCA_DEBUG
 #ifdef GSPCA_DEBUG
@@ -1244,14 +1235,7 @@ static int dev_open(struct file *file)
 		gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
 		gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
 					| V4L2_DEBUG_IOCTL_ARG);
 					| V4L2_DEBUG_IOCTL_ARG);
 #endif
 #endif
-	ret = 0;
-out:
-	mutex_unlock(&gspca_dev->queue_lock);
-	if (ret != 0)
-		PDEBUG(D_ERR|D_STREAM, "open failed err %d", ret);
-	else
-		PDEBUG(D_STREAM, "open done");
-	return ret;
+	return 0;
 }
 }
 
 
 static int dev_close(struct file *file)
 static int dev_close(struct file *file)
@@ -1261,7 +1245,6 @@ static int dev_close(struct file *file)
 	PDEBUG(D_STREAM, "[%s] close", current->comm);
 	PDEBUG(D_STREAM, "[%s] close", current->comm);
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
 		return -ERESTARTSYS;
-	gspca_dev->users--;
 
 
 	/* if the file did the capture, free the streaming resources */
 	/* if the file did the capture, free the streaming resources */
 	if (gspca_dev->capt_file == file) {
 	if (gspca_dev->capt_file == file) {
@@ -1272,8 +1255,6 @@ static int dev_close(struct file *file)
 			mutex_unlock(&gspca_dev->usb_lock);
 			mutex_unlock(&gspca_dev->usb_lock);
 		}
 		}
 		frame_free(gspca_dev);
 		frame_free(gspca_dev);
-		gspca_dev->capt_file = NULL;
-		gspca_dev->memory = GSPCA_MEMORY_NO;
 	}
 	}
 	file->private_data = NULL;
 	file->private_data = NULL;
 	module_put(gspca_dev->module);
 	module_put(gspca_dev->module);
@@ -1516,6 +1497,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 		return -ERESTARTSYS;
 		return -ERESTARTSYS;
 
 
 	if (gspca_dev->memory != GSPCA_MEMORY_NO
 	if (gspca_dev->memory != GSPCA_MEMORY_NO
+	    && gspca_dev->memory != GSPCA_MEMORY_READ
 	    && gspca_dev->memory != rb->memory) {
 	    && gspca_dev->memory != rb->memory) {
 		ret = -EBUSY;
 		ret = -EBUSY;
 		goto out;
 		goto out;
@@ -1544,19 +1526,18 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 		gspca_stream_off(gspca_dev);
 		gspca_stream_off(gspca_dev);
 		mutex_unlock(&gspca_dev->usb_lock);
 		mutex_unlock(&gspca_dev->usb_lock);
 	}
 	}
+	/* Don't restart the stream when switching from read to mmap mode */
+	if (gspca_dev->memory == GSPCA_MEMORY_READ)
+		streaming = 0;
 
 
 	/* free the previous allocated buffers, if any */
 	/* free the previous allocated buffers, if any */
-	if (gspca_dev->nframes != 0) {
+	if (gspca_dev->nframes != 0)
 		frame_free(gspca_dev);
 		frame_free(gspca_dev);
-		gspca_dev->capt_file = NULL;
-	}
 	if (rb->count == 0)			/* unrequest */
 	if (rb->count == 0)			/* unrequest */
 		goto out;
 		goto out;
-	gspca_dev->memory = rb->memory;
-	ret = frame_alloc(gspca_dev, rb->count);
+	ret = frame_alloc(gspca_dev, file, rb->memory, rb->count);
 	if (ret == 0) {
 	if (ret == 0) {
 		rb->count = gspca_dev->nframes;
 		rb->count = gspca_dev->nframes;
-		gspca_dev->capt_file = file;
 		if (streaming)
 		if (streaming)
 			ret = gspca_init_transfer(gspca_dev);
 			ret = gspca_init_transfer(gspca_dev);
 	}
 	}
@@ -1630,11 +1611,15 @@ static int vidioc_streamoff(struct file *file, void *priv,
 
 
 	if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 	if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 		return -EINVAL;
-	if (!gspca_dev->streaming)
-		return 0;
+
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
 		return -ERESTARTSYS;
 
 
+	if (!gspca_dev->streaming) {
+		ret = 0;
+		goto out;
+	}
+
 	/* check the capture file */
 	/* check the capture file */
 	if (gspca_dev->capt_file != file) {
 	if (gspca_dev->capt_file != file) {
 		ret = -EBUSY;
 		ret = -EBUSY;
@@ -1649,6 +1634,8 @@ static int vidioc_streamoff(struct file *file, void *priv,
 	gspca_dev->usb_err = 0;
 	gspca_dev->usb_err = 0;
 	gspca_stream_off(gspca_dev);
 	gspca_stream_off(gspca_dev);
 	mutex_unlock(&gspca_dev->usb_lock);
 	mutex_unlock(&gspca_dev->usb_lock);
+	/* In case another thread is waiting in dqbuf */
+	wake_up_interruptible(&gspca_dev->wq);
 
 
 	/* empty the transfer queues */
 	/* empty the transfer queues */
 	atomic_set(&gspca_dev->fr_q, 0);
 	atomic_set(&gspca_dev->fr_q, 0);
@@ -1827,33 +1814,77 @@ out:
 	return ret;
 	return ret;
 }
 }
 
 
+static int frame_ready_nolock(struct gspca_dev *gspca_dev, struct file *file,
+				enum v4l2_memory memory)
+{
+	if (!gspca_dev->present)
+		return -ENODEV;
+	if (gspca_dev->capt_file != file || gspca_dev->memory != memory ||
+			!gspca_dev->streaming)
+		return -EINVAL;
+
+	/* check if a frame is ready */
+	return gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i);
+}
+
+static int frame_ready(struct gspca_dev *gspca_dev, struct file *file,
+			enum v4l2_memory memory)
+{
+	int ret;
+
+	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+		return -ERESTARTSYS;
+	ret = frame_ready_nolock(gspca_dev, file, memory);
+	mutex_unlock(&gspca_dev->queue_lock);
+	return ret;
+}
+
 /*
 /*
- * wait for a video frame
+ * dequeue a video buffer
  *
  *
- * If a frame is ready, its index is returned.
+ * If nonblock_ing is false, block until a buffer is available.
  */
  */
-static int frame_wait(struct gspca_dev *gspca_dev,
-			int nonblock_ing)
+static int vidioc_dqbuf(struct file *file, void *priv,
+			struct v4l2_buffer *v4l2_buf)
 {
 {
-	int i, ret;
+	struct gspca_dev *gspca_dev = priv;
+	struct gspca_frame *frame;
+	int i, j, ret;
 
 
-	/* check if a frame is ready */
-	i = gspca_dev->fr_o;
-	if (i == atomic_read(&gspca_dev->fr_i)) {
-		if (nonblock_ing)
+	PDEBUG(D_FRAM, "dqbuf");
+
+	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+		return -ERESTARTSYS;
+
+	for (;;) {
+		ret = frame_ready_nolock(gspca_dev, file, v4l2_buf->memory);
+		if (ret < 0)
+			goto out;
+		if (ret > 0)
+			break;
+
+		mutex_unlock(&gspca_dev->queue_lock);
+
+		if (file->f_flags & O_NONBLOCK)
 			return -EAGAIN;
 			return -EAGAIN;
 
 
 		/* wait till a frame is ready */
 		/* wait till a frame is ready */
 		ret = wait_event_interruptible_timeout(gspca_dev->wq,
 		ret = wait_event_interruptible_timeout(gspca_dev->wq,
-			i != atomic_read(&gspca_dev->fr_i) ||
-			!gspca_dev->streaming || !gspca_dev->present,
+			frame_ready(gspca_dev, file, v4l2_buf->memory),
 			msecs_to_jiffies(3000));
 			msecs_to_jiffies(3000));
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			return ret;
-		if (ret == 0 || !gspca_dev->streaming || !gspca_dev->present)
+		if (ret == 0)
 			return -EIO;
 			return -EIO;
+
+		if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+			return -ERESTARTSYS;
 	}
 	}
 
 
+	i = gspca_dev->fr_o;
+	j = gspca_dev->fr_queue[i];
+	frame = &gspca_dev->frame[j];
+
 	gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES;
 	gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES;
 
 
 	if (gspca_dev->sd_desc->dq_callback) {
 	if (gspca_dev->sd_desc->dq_callback) {
@@ -1863,46 +1894,12 @@ static int frame_wait(struct gspca_dev *gspca_dev,
 			gspca_dev->sd_desc->dq_callback(gspca_dev);
 			gspca_dev->sd_desc->dq_callback(gspca_dev);
 		mutex_unlock(&gspca_dev->usb_lock);
 		mutex_unlock(&gspca_dev->usb_lock);
 	}
 	}
-	return gspca_dev->fr_queue[i];
-}
-
-/*
- * dequeue a video buffer
- *
- * If nonblock_ing is false, block until a buffer is available.
- */
-static int vidioc_dqbuf(struct file *file, void *priv,
-			struct v4l2_buffer *v4l2_buf)
-{
-	struct gspca_dev *gspca_dev = priv;
-	struct gspca_frame *frame;
-	int i, ret;
-
-	PDEBUG(D_FRAM, "dqbuf");
-	if (v4l2_buf->memory != gspca_dev->memory)
-		return -EINVAL;
-
-	if (!gspca_dev->present)
-		return -ENODEV;
-
-	/* if not streaming, be sure the application will not loop forever */
-	if (!(file->f_flags & O_NONBLOCK)
-	    && !gspca_dev->streaming && gspca_dev->users == 1)
-		return -EINVAL;
 
 
-	/* only the capturing file may dequeue */
-	if (gspca_dev->capt_file != file)
-		return -EINVAL;
-
-	/* only one dequeue / read at a time */
-	if (mutex_lock_interruptible(&gspca_dev->read_lock))
-		return -ERESTARTSYS;
+	frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
+	memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
+	PDEBUG(D_FRAM, "dqbuf %d", j);
+	ret = 0;
 
 
-	ret = frame_wait(gspca_dev, file->f_flags & O_NONBLOCK);
-	if (ret < 0)
-		goto out;
-	i = ret;				/* frame index */
-	frame = &gspca_dev->frame[i];
 	if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
 	if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
 		if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
 		if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
 				 frame->data,
 				 frame->data,
@@ -1910,15 +1907,10 @@ static int vidioc_dqbuf(struct file *file, void *priv,
 			PDEBUG(D_ERR|D_STREAM,
 			PDEBUG(D_ERR|D_STREAM,
 				"dqbuf cp to user failed");
 				"dqbuf cp to user failed");
 			ret = -EFAULT;
 			ret = -EFAULT;
-			goto out;
 		}
 		}
 	}
 	}
-	frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
-	memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
-	PDEBUG(D_FRAM, "dqbuf %d", i);
-	ret = 0;
 out:
 out:
-	mutex_unlock(&gspca_dev->read_lock);
+	mutex_unlock(&gspca_dev->queue_lock);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -2033,9 +2025,7 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
 	poll_wait(file, &gspca_dev->wq, wait);
 	poll_wait(file, &gspca_dev->wq, wait);
 
 
 	/* if reqbufs is not done, the user would use read() */
 	/* if reqbufs is not done, the user would use read() */
-	if (gspca_dev->nframes == 0) {
-		if (gspca_dev->memory != GSPCA_MEMORY_NO)
-			return POLLERR;		/* not the 1st time */
+	if (gspca_dev->memory == GSPCA_MEMORY_NO) {
 		ret = read_alloc(gspca_dev, file);
 		ret = read_alloc(gspca_dev, file);
 		if (ret != 0)
 		if (ret != 0)
 			return POLLERR;
 			return POLLERR;
@@ -2067,18 +2057,10 @@ static ssize_t dev_read(struct file *file, char __user *data,
 	PDEBUG(D_FRAM, "read (%zd)", count);
 	PDEBUG(D_FRAM, "read (%zd)", count);
 	if (!gspca_dev->present)
 	if (!gspca_dev->present)
 		return -ENODEV;
 		return -ENODEV;
-	switch (gspca_dev->memory) {
-	case GSPCA_MEMORY_NO:			/* first time */
+	if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */
 		ret = read_alloc(gspca_dev, file);
 		ret = read_alloc(gspca_dev, file);
 		if (ret != 0)
 		if (ret != 0)
 			return ret;
 			return ret;
-		break;
-	case GSPCA_MEMORY_READ:
-		if (gspca_dev->capt_file == file)
-			break;
-		/* fall thru */
-	default:
-		return -EINVAL;
 	}
 	}
 
 
 	/* get a frame */
 	/* get a frame */
@@ -2266,7 +2248,6 @@ int gspca_dev_probe2(struct usb_interface *intf,
 		goto out;
 		goto out;
 
 
 	mutex_init(&gspca_dev->usb_lock);
 	mutex_init(&gspca_dev->usb_lock);
-	mutex_init(&gspca_dev->read_lock);
 	mutex_init(&gspca_dev->queue_lock);
 	mutex_init(&gspca_dev->queue_lock);
 	init_waitqueue_head(&gspca_dev->wq);
 	init_waitqueue_head(&gspca_dev->wq);
 
 
@@ -2341,12 +2322,11 @@ void gspca_disconnect(struct usb_interface *intf)
 	PDEBUG(D_PROBE, "%s disconnect",
 	PDEBUG(D_PROBE, "%s disconnect",
 		video_device_node_name(&gspca_dev->vdev));
 		video_device_node_name(&gspca_dev->vdev));
 	mutex_lock(&gspca_dev->usb_lock);
 	mutex_lock(&gspca_dev->usb_lock);
+
 	gspca_dev->present = 0;
 	gspca_dev->present = 0;
+	wake_up_interruptible(&gspca_dev->wq);
 
 
-	if (gspca_dev->streaming) {
-		destroy_urbs(gspca_dev);
-		wake_up_interruptible(&gspca_dev->wq);
-	}
+	destroy_urbs(gspca_dev);
 
 
 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
 	gspca_input_destroy_urb(gspca_dev);
 	gspca_input_destroy_urb(gspca_dev);

+ 0 - 2
drivers/media/video/gspca/gspca.h

@@ -205,14 +205,12 @@ struct gspca_dev {
 
 
 	wait_queue_head_t wq;		/* wait queue */
 	wait_queue_head_t wq;		/* wait queue */
 	struct mutex usb_lock;		/* usb exchange protection */
 	struct mutex usb_lock;		/* usb exchange protection */
-	struct mutex read_lock;		/* read protection */
 	struct mutex queue_lock;	/* ISOC queue protection */
 	struct mutex queue_lock;	/* ISOC queue protection */
 	int usb_err;			/* USB error - protected by usb_lock */
 	int usb_err;			/* USB error - protected by usb_lock */
 	u16 pkt_size;			/* ISOC packet size */
 	u16 pkt_size;			/* ISOC packet size */
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
 	char frozen;			/* suspend - resume */
 	char frozen;			/* suspend - resume */
 #endif
 #endif
-	char users;			/* number of opens */
 	char present;			/* device connected */
 	char present;			/* device connected */
 	char nbufread;			/* number of buffers for read() */
 	char nbufread;			/* number of buffers for read() */
 	char memory;			/* memory type (V4L2_MEMORY_xxx) */
 	char memory;			/* memory type (V4L2_MEMORY_xxx) */

+ 1 - 1
drivers/media/video/gspca/jeilinj.c

@@ -314,7 +314,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 }
 }
 
 
 /* Table of supported USB devices */
 /* Table of supported USB devices */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0979, 0x0280)},
 	{USB_DEVICE(0x0979, 0x0280)},
 	{}
 	{}
 };
 };

+ 2 - 2
drivers/media/video/gspca/jpeg.h

@@ -141,9 +141,9 @@ static void jpeg_define(u8 *jpeg_hdr,
 	memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
 	memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
 #ifndef CONEX_CAM
 #ifndef CONEX_CAM
 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
-	jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height & 0xff;
+	jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height;
 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
-	jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width & 0xff;
+	jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width;
 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
 #endif
 #endif
 }
 }

+ 1 - 1
drivers/media/video/gspca/konica.c

@@ -607,7 +607,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x04c8, 0x0720)}, /* Intel YC 76 */
 	{USB_DEVICE(0x04c8, 0x0720)}, /* Intel YC 76 */
 	{}
 	{}
 };
 };

+ 1 - 1
drivers/media/video/gspca/m5602/m5602_core.c

@@ -28,7 +28,7 @@ int force_sensor;
 static int dump_bridge;
 static int dump_bridge;
 int dump_sensor;
 int dump_sensor;
 
 
-static const __devinitdata struct usb_device_id m5602_table[] = {
+static const struct usb_device_id m5602_table[] = {
 	{USB_DEVICE(0x0402, 0x5602)},
 	{USB_DEVICE(0x0402, 0x5602)},
 	{}
 	{}
 };
 };

+ 1 - 1
drivers/media/video/gspca/mars.c

@@ -490,7 +490,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x093a, 0x050f)},
 	{USB_DEVICE(0x093a, 0x050f)},
 	{}
 	{}
 };
 };

+ 1 - 1
drivers/media/video/gspca/mr97310a.c

@@ -1229,7 +1229,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x08ca, 0x0110)},	/* Trust Spyc@m 100 */
 	{USB_DEVICE(0x08ca, 0x0110)},	/* Trust Spyc@m 100 */
 	{USB_DEVICE(0x08ca, 0x0111)},	/* Aiptek Pencam VGA+ */
 	{USB_DEVICE(0x08ca, 0x0111)},	/* Aiptek Pencam VGA+ */
 	{USB_DEVICE(0x093a, 0x010f)},	/* All other known MR97310A VGA cams */
 	{USB_DEVICE(0x093a, 0x010f)},	/* All other known MR97310A VGA cams */

+ 3 - 5
drivers/media/video/gspca/ov519.c

@@ -488,7 +488,6 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
 #define R511_SNAP_PXDIV			0x1c
 #define R511_SNAP_PXDIV			0x1c
 #define R511_SNAP_LNDIV			0x1d
 #define R511_SNAP_LNDIV			0x1d
 #define R511_SNAP_UV_EN			0x1e
 #define R511_SNAP_UV_EN			0x1e
-#define R511_SNAP_UV_EN			0x1e
 #define R511_SNAP_OPTS			0x1f
 #define R511_SNAP_OPTS			0x1f
 
 
 #define R511_DRAM_FLOW_CTL		0x20
 #define R511_DRAM_FLOW_CTL		0x20
@@ -1847,8 +1846,7 @@ static const struct ov_i2c_regvals norm_7670[] = {
 	{ 0x6c, 0x0a },
 	{ 0x6c, 0x0a },
 	{ 0x6d, 0x55 },
 	{ 0x6d, 0x55 },
 	{ 0x6e, 0x11 },
 	{ 0x6e, 0x11 },
-	{ 0x6f, 0x9f },
-					/* "9e for advance AWB" */
+	{ 0x6f, 0x9f },			/* "9e for advance AWB" */
 	{ 0x6a, 0x40 },
 	{ 0x6a, 0x40 },
 	{ OV7670_R01_BLUE, 0x40 },
 	{ OV7670_R01_BLUE, 0x40 },
 	{ OV7670_R02_RED, 0x60 },
 	{ OV7670_R02_RED, 0x60 },
@@ -3054,7 +3052,7 @@ static void ov519_configure(struct sd *sd)
 {
 {
 	static const struct ov_regvals init_519[] = {
 	static const struct ov_regvals init_519[] = {
 		{ 0x5a, 0x6d }, /* EnableSystem */
 		{ 0x5a, 0x6d }, /* EnableSystem */
-		{ 0x53, 0x9b },
+		{ 0x53, 0x9b }, /* don't enable the microcontroller */
 		{ OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
 		{ OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
 		{ 0x5d, 0x03 },
 		{ 0x5d, 0x03 },
 		{ 0x49, 0x01 },
 		{ 0x49, 0x01 },
@@ -4747,7 +4745,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
 	{USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
 	{USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
 	{USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },

+ 20 - 9
drivers/media/video/gspca/ov534.c

@@ -479,15 +479,20 @@ static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
 	struct usb_device *udev = gspca_dev->dev;
 	struct usb_device *udev = gspca_dev->dev;
 	int ret;
 	int ret;
 
 
-	PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
+	if (gspca_dev->usb_err < 0)
+		return;
+
+	PDEBUG(D_USBO, "SET 01 0000 %04x %02x", reg, val);
 	gspca_dev->usb_buf[0] = val;
 	gspca_dev->usb_buf[0] = val;
 	ret = usb_control_msg(udev,
 	ret = usb_control_msg(udev,
 			      usb_sndctrlpipe(udev, 0),
 			      usb_sndctrlpipe(udev, 0),
 			      0x01,
 			      0x01,
 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
 			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
-	if (ret < 0)
+	if (ret < 0) {
 		err("write failed %d", ret);
 		err("write failed %d", ret);
+		gspca_dev->usb_err = ret;
+	}
 }
 }
 
 
 static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
 static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
@@ -495,14 +500,18 @@ static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
 	struct usb_device *udev = gspca_dev->dev;
 	struct usb_device *udev = gspca_dev->dev;
 	int ret;
 	int ret;
 
 
+	if (gspca_dev->usb_err < 0)
+		return 0;
 	ret = usb_control_msg(udev,
 	ret = usb_control_msg(udev,
 			      usb_rcvctrlpipe(udev, 0),
 			      usb_rcvctrlpipe(udev, 0),
 			      0x01,
 			      0x01,
 			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
 			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
-	PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
-	if (ret < 0)
+	PDEBUG(D_USBI, "GET 01 0000 %04x %02x", reg, gspca_dev->usb_buf[0]);
+	if (ret < 0) {
 		err("read failed %d", ret);
 		err("read failed %d", ret);
+		gspca_dev->usb_err = ret;
+	}
 	return gspca_dev->usb_buf[0];
 	return gspca_dev->usb_buf[0];
 }
 }
 
 
@@ -558,13 +567,15 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
 
 
 static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 {
 {
-	PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val);
+	PDEBUG(D_USBO, "sccb write: %02x %02x", reg, val);
 	ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
 	ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
 	ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
 	ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
 	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
 	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
 
 
-	if (!sccb_check_status(gspca_dev))
+	if (!sccb_check_status(gspca_dev)) {
 		err("sccb_reg_write failed");
 		err("sccb_reg_write failed");
+		gspca_dev->usb_err = -EIO;
+	}
 }
 }
 
 
 static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
 static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
@@ -885,7 +896,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	ov534_set_led(gspca_dev, 0);
 	ov534_set_led(gspca_dev, 0);
 	set_frame_rate(gspca_dev);
 	set_frame_rate(gspca_dev);
 
 
-	return 0;
+	return gspca_dev->usb_err;
 }
 }
 
 
 static int sd_start(struct gspca_dev *gspca_dev)
 static int sd_start(struct gspca_dev *gspca_dev)
@@ -920,7 +931,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 
 	ov534_set_led(gspca_dev, 1);
 	ov534_set_led(gspca_dev, 1);
 	ov534_reg_write(gspca_dev, 0xe0, 0x00);
 	ov534_reg_write(gspca_dev, 0xe0, 0x00);
-	return 0;
+	return gspca_dev->usb_err;
 }
 }
 
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -1289,7 +1300,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x1415, 0x2000)},
 	{USB_DEVICE(0x1415, 0x2000)},
 	{}
 	{}
 };
 };

+ 1 - 1
drivers/media/video/gspca/ov534_9.c

@@ -1429,7 +1429,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x06f8, 0x3003)},
 	{USB_DEVICE(0x06f8, 0x3003)},
 	{}
 	{}
 };
 };

+ 1 - 1
drivers/media/video/gspca/pac207.c

@@ -530,7 +530,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x4028)},
 	{USB_DEVICE(0x041e, 0x4028)},
 	{USB_DEVICE(0x093a, 0x2460)},
 	{USB_DEVICE(0x093a, 0x2460)},
 	{USB_DEVICE(0x093a, 0x2461)},
 	{USB_DEVICE(0x093a, 0x2461)},

+ 2 - 2
drivers/media/video/gspca/pac7302.c

@@ -1184,7 +1184,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x06f8, 0x3009)},
 	{USB_DEVICE(0x06f8, 0x3009)},
 	{USB_DEVICE(0x093a, 0x2620)},
 	{USB_DEVICE(0x093a, 0x2620)},
 	{USB_DEVICE(0x093a, 0x2621)},
 	{USB_DEVICE(0x093a, 0x2621)},
@@ -1201,7 +1201,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
 MODULE_DEVICE_TABLE(usb, device_table);
 MODULE_DEVICE_TABLE(usb, device_table);
 
 
 /* -- device connect -- */
 /* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 			const struct usb_device_id *id)
 {
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

+ 2 - 2
drivers/media/video/gspca/pac7311.c

@@ -837,7 +837,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const struct usb_device_id device_table[] __devinitconst = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x093a, 0x2600)},
 	{USB_DEVICE(0x093a, 0x2600)},
 	{USB_DEVICE(0x093a, 0x2601)},
 	{USB_DEVICE(0x093a, 0x2601)},
 	{USB_DEVICE(0x093a, 0x2603)},
 	{USB_DEVICE(0x093a, 0x2603)},
@@ -849,7 +849,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
 MODULE_DEVICE_TABLE(usb, device_table);
 MODULE_DEVICE_TABLE(usb, device_table);
 
 
 /* -- device connect -- */
 /* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 			const struct usb_device_id *id)
 {
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

+ 1 - 1
drivers/media/video/gspca/sn9c2028.c

@@ -703,7 +703,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */
 	{USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */
 	/* The Genius Smart is untested. I can't find an owner ! */
 	/* The Genius Smart is untested. I can't find an owner ! */
 	/* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */
 	/* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */

+ 1 - 1
drivers/media/video/gspca/sn9c20x.c

@@ -2470,7 +2470,7 @@ static const struct sd_desc sd_desc = {
 			| (SENSOR_ ## sensor << 8) \
 			| (SENSOR_ ## sensor << 8) \
 			| (i2c_addr)
 			| (i2c_addr)
 
 
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
 	{USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
 	{USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
 	{USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
 	{USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
 	{USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},

+ 157 - 113
drivers/media/video/gspca/sonixb.c

@@ -23,8 +23,15 @@
 /* Some documentation on known sonixb registers:
 /* Some documentation on known sonixb registers:
 
 
 Reg	Use
 Reg	Use
+sn9c101 / sn9c102:
 0x10	high nibble red gain low nibble blue gain
 0x10	high nibble red gain low nibble blue gain
 0x11	low nibble green gain
 0x11	low nibble green gain
+sn9c103:
+0x05	red gain 0-127
+0x06	blue gain 0-127
+0x07	green gain 0-127
+all:
+0x08-0x0f i2c / 3wire registers
 0x12	hstart
 0x12	hstart
 0x13	vstart
 0x13	vstart
 0x15	hsize (hsize = register-value * 16)
 0x15	hsize (hsize = register-value * 16)
@@ -88,12 +95,9 @@ struct sd {
 typedef const __u8 sensor_init_t[8];
 typedef const __u8 sensor_init_t[8];
 
 
 struct sensor_data {
 struct sensor_data {
-	const __u8 *bridge_init[2];
-	int bridge_init_size[2];
+	const __u8 *bridge_init;
 	sensor_init_t *sensor_init;
 	sensor_init_t *sensor_init;
 	int sensor_init_size;
 	int sensor_init_size;
-	sensor_init_t *sensor_bridge_init[2];
-	int sensor_bridge_init_size[2];
 	int flags;
 	int flags;
 	unsigned ctrl_dis;
 	unsigned ctrl_dis;
 	__u8 sensor_addr;
 	__u8 sensor_addr;
@@ -114,7 +118,6 @@ struct sensor_data {
 #define NO_FREQ (1 << FREQ_IDX)
 #define NO_FREQ (1 << FREQ_IDX)
 #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
 #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
 
 
-#define COMP2 0x8f
 #define COMP 0xc7		/* 0x87 //0x07 */
 #define COMP 0xc7		/* 0x87 //0x07 */
 #define COMP1 0xc9		/* 0x89 //0x09 */
 #define COMP1 0xc9		/* 0x89 //0x09 */
 
 
@@ -123,15 +126,11 @@ struct sensor_data {
 
 
 #define SYS_CLK 0x04
 #define SYS_CLK 0x04
 
 
-#define SENS(bridge_1, bridge_3, sensor, sensor_1, \
-	sensor_3, _flags, _ctrl_dis, _sensor_addr) \
+#define SENS(bridge, sensor, _flags, _ctrl_dis, _sensor_addr) \
 { \
 { \
-	.bridge_init = { bridge_1, bridge_3 }, \
-	.bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
+	.bridge_init = bridge, \
 	.sensor_init = sensor, \
 	.sensor_init = sensor, \
 	.sensor_init_size = sizeof(sensor), \
 	.sensor_init_size = sizeof(sensor), \
-	.sensor_bridge_init = { sensor_1, sensor_3,}, \
-	.sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
 	.flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
 	.flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
 }
 }
 
 
@@ -311,7 +310,6 @@ static const __u8 initHv7131d[] = {
 	0x00, 0x00,
 	0x00, 0x00,
 	0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
 	0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
 	0x28, 0x1e, 0x60, 0x8e, 0x42,
 	0x28, 0x1e, 0x60, 0x8e, 0x42,
-	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
 };
 };
 static const __u8 hv7131d_sensor_init[][8] = {
 static const __u8 hv7131d_sensor_init[][8] = {
 	{0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
 	{0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
@@ -326,7 +324,6 @@ static const __u8 initHv7131r[] = {
 	0x00, 0x00,
 	0x00, 0x00,
 	0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
 	0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
 	0x28, 0x1e, 0x60, 0x8a, 0x20,
 	0x28, 0x1e, 0x60, 0x8a, 0x20,
-	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
 };
 };
 static const __u8 hv7131r_sensor_init[][8] = {
 static const __u8 hv7131r_sensor_init[][8] = {
 	{0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
 	{0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
@@ -339,7 +336,7 @@ static const __u8 initOv6650[] = {
 	0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
 	0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
 	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
 	0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
-	0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
+	0x10,
 };
 };
 static const __u8 ov6650_sensor_init[][8] = {
 static const __u8 ov6650_sensor_init[][8] = {
 	/* Bright, contrast, etc are set through SCBB interface.
 	/* Bright, contrast, etc are set through SCBB interface.
@@ -378,24 +375,13 @@ static const __u8 initOv7630[] = {
 	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* r09 .. r10 */
 	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* r09 .. r10 */
 	0x00, 0x01, 0x01, 0x0a,				/* r11 .. r14 */
 	0x00, 0x01, 0x01, 0x0a,				/* r11 .. r14 */
 	0x28, 0x1e,			/* H & V sizes     r15 .. r16 */
 	0x28, 0x1e,			/* H & V sizes     r15 .. r16 */
-	0x68, COMP2, MCK_INIT1,				/* r17 .. r19 */
-	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c		/* r1a .. r1f */
-};
-static const __u8 initOv7630_3[] = {
-	0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80,	/* r01 .. r08 */
-	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* r09 .. r10 */
-	0x00, 0x02, 0x01, 0x0a,				/* r11 .. r14 */
-	0x28, 0x1e,			/* H & V sizes     r15 .. r16 */
 	0x68, 0x8f, MCK_INIT1,				/* r17 .. r19 */
 	0x68, 0x8f, MCK_INIT1,				/* r17 .. r19 */
-	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00,	/* r1a .. r20 */
-	0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
-	0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff  /* r29 .. r30 */
 };
 };
 static const __u8 ov7630_sensor_init[][8] = {
 static const __u8 ov7630_sensor_init[][8] = {
 	{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
 	{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
 	{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
 	{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
 /*	{0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},	   jfm */
 /*	{0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},	   jfm */
-	{0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10},	/* jfm */
+	{0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10},	/* jfm */
 	{0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
 	{0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
 	{0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
 	{0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
 	{0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
 	{0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
@@ -413,16 +399,11 @@ static const __u8 ov7630_sensor_init[][8] = {
 	{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
 	{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
 };
 };
 
 
-static const __u8 ov7630_sensor_init_3[][8] = {
-	{0xa0, 0x21, 0x13, 0x80, 0x00,	0x00, 0x00, 0x10},
-};
-
 static const __u8 initPas106[] = {
 static const __u8 initPas106[] = {
 	0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
 	0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
 	0x00, 0x00,
 	0x00, 0x00,
 	0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
 	0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
 	0x16, 0x12, 0x24, COMP1, MCK_INIT1,
 	0x16, 0x12, 0x24, COMP1, MCK_INIT1,
-	0x18, 0x10, 0x02, 0x02, 0x09, 0x07
 };
 };
 /* compression 0x86 mckinit1 0x2b */
 /* compression 0x86 mckinit1 0x2b */
 
 
@@ -496,7 +477,6 @@ static const __u8 initPas202[] = {
 	0x00, 0x00,
 	0x00, 0x00,
 	0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
 	0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
 	0x28, 0x1e, 0x20, 0x89, 0x20,
 	0x28, 0x1e, 0x20, 0x89, 0x20,
-	0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
 };
 };
 
 
 /* "Known" PAS202BCB registers:
 /* "Known" PAS202BCB registers:
@@ -537,7 +517,6 @@ static const __u8 initTas5110c[] = {
 	0x00, 0x00,
 	0x00, 0x00,
 	0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
 	0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
 	0x16, 0x12, 0x60, 0x86, 0x2b,
 	0x16, 0x12, 0x60, 0x86, 0x2b,
-	0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
 };
 };
 /* Same as above, except a different hstart */
 /* Same as above, except a different hstart */
 static const __u8 initTas5110d[] = {
 static const __u8 initTas5110d[] = {
@@ -545,12 +524,19 @@ static const __u8 initTas5110d[] = {
 	0x00, 0x00,
 	0x00, 0x00,
 	0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
 	0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
 	0x16, 0x12, 0x60, 0x86, 0x2b,
 	0x16, 0x12, 0x60, 0x86, 0x2b,
-	0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
 };
 };
-static const __u8 tas5110_sensor_init[][8] = {
+/* tas5110c is 3 wire, tas5110d is 2 wire (regular i2c) */
+static const __u8 tas5110c_sensor_init[][8] = {
 	{0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
 	{0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
 	{0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
 	{0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
-	{0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
+};
+/* Known TAS5110D registers
+ * reg02: gain, bit order reversed!! 0 == max gain, 255 == min gain
+ * reg03: bit3: vflip, bit4: ~hflip, bit7: ~gainboost (~ == inverted)
+ *        Note: writing reg03 seems to only work when written together with 02
+ */
+static const __u8 tas5110d_sensor_init[][8] = {
+	{0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, /* reset */
 };
 };
 
 
 static const __u8 initTas5130[] = {
 static const __u8 initTas5130[] = {
@@ -558,7 +544,6 @@ static const __u8 initTas5130[] = {
 	0x00, 0x00,
 	0x00, 0x00,
 	0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
 	0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
 	0x28, 0x1e, 0x60, COMP, MCK_INIT,
 	0x28, 0x1e, 0x60, COMP, MCK_INIT,
-	0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
 };
 };
 static const __u8 tas5130_sensor_init[][8] = {
 static const __u8 tas5130_sensor_init[][8] = {
 /*	{0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
 /*	{0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
@@ -569,21 +554,18 @@ static const __u8 tas5130_sensor_init[][8] = {
 };
 };
 
 
 static struct sensor_data sensor_data[] = {
 static struct sensor_data sensor_data[] = {
-SENS(initHv7131d, NULL, hv7131d_sensor_init, NULL, NULL, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
-SENS(initHv7131r, NULL, hv7131r_sensor_init, NULL, NULL, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
-SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
-SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
-	F_GAIN, 0, 0x21),
-SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ,
-	0),
-SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN,
-	NO_FREQ, 0),
-SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL,
-	F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
-SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL,
-	F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
-SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
-	0),
+SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
+SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
+SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60),
+SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21),
+SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0),
+SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0),
+SENS(initTas5110c, tas5110c_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
+	NO_BRIGHTNESS|NO_FREQ, 0),
+SENS(initTas5110d, tas5110d_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
+	NO_BRIGHTNESS|NO_FREQ, 0),
+SENS(initTas5130, tas5130_sensor_init, F_GAIN,
+	NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
 };
 };
 
 
 /* get one byte in gspca_dev->usb_buf */
 /* get one byte in gspca_dev->usb_buf */
@@ -655,7 +637,6 @@ static void i2c_w_vector(struct gspca_dev *gspca_dev,
 static void setbrightness(struct gspca_dev *gspca_dev)
 static void setbrightness(struct gspca_dev *gspca_dev)
 {
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 value;
 
 
 	switch (sd->sensor) {
 	switch (sd->sensor) {
 	case  SENSOR_OV6650:
 	case  SENSOR_OV6650:
@@ -697,17 +678,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
 			goto err;
 			goto err;
 		break;
 		break;
 	    }
 	    }
-	case SENSOR_TAS5130CXX: {
-		__u8 i2c[] =
-			{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
-
-		value = 0xff - sd->brightness;
-		i2c[4] = value;
-		PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
-		if (i2c_w(gspca_dev, i2c) < 0)
-			goto err;
-		break;
-	    }
 	}
 	}
 	return;
 	return;
 err:
 err:
@@ -733,7 +703,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
 		break;
 		break;
 	    }
 	    }
 	case SENSOR_TAS5110C:
 	case SENSOR_TAS5110C:
-	case SENSOR_TAS5110D: {
+	case SENSOR_TAS5130CXX: {
 		__u8 i2c[] =
 		__u8 i2c[] =
 			{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
 			{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
 
 
@@ -742,6 +712,23 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
 			goto err;
 			goto err;
 		break;
 		break;
 	    }
 	    }
+	case SENSOR_TAS5110D: {
+		__u8 i2c[] = {
+			0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 };
+		gain = 255 - gain;
+		/* The bits in the register are the wrong way around!! */
+		i2c[3] |= (gain & 0x80) >> 7;
+		i2c[3] |= (gain & 0x40) >> 5;
+		i2c[3] |= (gain & 0x20) >> 3;
+		i2c[3] |= (gain & 0x10) >> 1;
+		i2c[3] |= (gain & 0x08) << 1;
+		i2c[3] |= (gain & 0x04) << 3;
+		i2c[3] |= (gain & 0x02) << 5;
+		i2c[3] |= (gain & 0x01) << 7;
+		if (i2c_w(gspca_dev, i2c) < 0)
+			goto err;
+		break;
+	    }
 
 
 	case SENSOR_OV6650:
 	case SENSOR_OV6650:
 		gain >>= 1;
 		gain >>= 1;
@@ -796,7 +783,7 @@ static void setgain(struct gspca_dev *gspca_dev)
 {
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u8 gain;
 	__u8 gain;
-	__u8 buf[2] = { 0, 0 };
+	__u8 buf[3] = { 0, 0, 0 };
 
 
 	if (sensor_data[sd->sensor].flags & F_GAIN) {
 	if (sensor_data[sd->sensor].flags & F_GAIN) {
 		/* Use the sensor gain to do the actual gain */
 		/* Use the sensor gain to do the actual gain */
@@ -804,13 +791,18 @@ static void setgain(struct gspca_dev *gspca_dev)
 		return;
 		return;
 	}
 	}
 
 
-	gain = sd->gain >> 4;
-
-	/* red and blue gain */
-	buf[0] = gain << 4 | gain;
-	/* green gain */
-	buf[1] = gain;
-	reg_w(gspca_dev, 0x10, buf, 2);
+	if (sd->bridge == BRIDGE_103) {
+		gain = sd->gain >> 1;
+		buf[0] = gain; /* Red */
+		buf[1] = gain; /* Green */
+		buf[2] = gain; /* Blue */
+		reg_w(gspca_dev, 0x05, buf, 3);
+	} else {
+		gain = sd->gain >> 4;
+		buf[0] = gain << 4 | gain; /* Red and blue */
+		buf[1] = gain; /* Green */
+		reg_w(gspca_dev, 0x10, buf, 2);
+	}
 }
 }
 
 
 static void setexposure(struct gspca_dev *gspca_dev)
 static void setexposure(struct gspca_dev *gspca_dev)
@@ -1049,7 +1041,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
 		desired_avg_lum = 5000;
 		desired_avg_lum = 5000;
 	} else {
 	} else {
 		deadzone = 1500;
 		deadzone = 1500;
-		desired_avg_lum = 18000;
+		desired_avg_lum = 13000;
 	}
 	}
 
 
 	if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
 	if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
@@ -1127,53 +1119,91 @@ static int sd_start(struct gspca_dev *gspca_dev)
 {
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam = &gspca_dev->cam;
 	struct cam *cam = &gspca_dev->cam;
-	int mode, l;
-	const __u8 *sn9c10x;
-	__u8 reg12_19[8];
+	int i, mode;
+	__u8 regs[0x31];
 
 
 	mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
 	mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
-	sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
-	l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
-	memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
-	reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
-	/* Special cases where reg 17 and or 19 value depends on mode */
+	/* Copy registers 0x01 - 0x19 from the template */
+	memcpy(&regs[0x01], sensor_data[sd->sensor].bridge_init, 0x19);
+	/* Set the mode */
+	regs[0x18] |= mode << 4;
+
+	/* Set bridge gain to 1.0 */
+	if (sd->bridge == BRIDGE_103) {
+		regs[0x05] = 0x20; /* Red */
+		regs[0x06] = 0x20; /* Green */
+		regs[0x07] = 0x20; /* Blue */
+	} else {
+		regs[0x10] = 0x00; /* Red and blue */
+		regs[0x11] = 0x00; /* Green */
+	}
+
+	/* Setup pixel numbers and auto exposure window */
+	if (sensor_data[sd->sensor].flags & F_SIF) {
+		regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */
+		regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */
+		regs[0x1c] = 0x02; /* AE H-start 64 */
+		regs[0x1d] = 0x02; /* AE V-start 64 */
+		regs[0x1e] = 0x09; /* AE H-end 288 */
+		regs[0x1f] = 0x07; /* AE V-end 224 */
+	} else {
+		regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */
+		regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */
+		regs[0x1c] = 0x05; /* AE H-start 160 */
+		regs[0x1d] = 0x03; /* AE V-start 96 */
+		regs[0x1e] = 0x0f; /* AE H-end 480 */
+		regs[0x1f] = 0x0c; /* AE V-end 384 */
+	}
+
+	/* Setup the gamma table (only used with the sn9c103 bridge) */
+	for (i = 0; i < 16; i++)
+		regs[0x20 + i] = i * 16;
+	regs[0x20 + i] = 255;
+
+	/* Special cases where some regs depend on mode or bridge */
 	switch (sd->sensor) {
 	switch (sd->sensor) {
 	case SENSOR_TAS5130CXX:
 	case SENSOR_TAS5130CXX:
-		/* probably not mode specific at all most likely the upper
+		/* FIXME / TESTME
+		   probably not mode specific at all most likely the upper
 		   nibble of 0x19 is exposure (clock divider) just as with
 		   nibble of 0x19 is exposure (clock divider) just as with
 		   the tas5110, we need someone to test this. */
 		   the tas5110, we need someone to test this. */
-		reg12_19[7] = mode ? 0x23 : 0x43;
+		regs[0x19] = mode ? 0x23 : 0x43;
 		break;
 		break;
+	case SENSOR_OV7630:
+		/* FIXME / TESTME for some reason with the 101/102 bridge the
+		   clock is set to 12 Mhz (reg1 == 0x04), rather then 24.
+		   Also the hstart needs to go from 1 to 2 when using a 103,
+		   which is likely related. This does not seem right. */
+		if (sd->bridge == BRIDGE_103) {
+			regs[0x01] = 0x44; /* Select 24 Mhz clock */
+			regs[0x12] = 0x02; /* Set hstart to 2 */
+		}
 	}
 	}
 	/* Disable compression when the raw bayer format has been selected */
 	/* Disable compression when the raw bayer format has been selected */
 	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
 	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
-		reg12_19[6] &= ~0x80;
+		regs[0x18] &= ~0x80;
 
 
 	/* Vga mode emulation on SIF sensor? */
 	/* Vga mode emulation on SIF sensor? */
 	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
 	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
-		reg12_19[0] += 16; /* 0x12: hstart adjust */
-		reg12_19[1] += 24; /* 0x13: vstart adjust */
-		reg12_19[3] = 320 / 16; /* 0x15: hsize */
-		reg12_19[4] = 240 / 16; /* 0x16: vsize */
+		regs[0x12] += 16;	/* hstart adjust */
+		regs[0x13] += 24;	/* vstart adjust */
+		regs[0x15]  = 320 / 16; /* hsize */
+		regs[0x16]  = 240 / 16; /* vsize */
 	}
 	}
 
 
 	/* reg 0x01 bit 2 video transfert on */
 	/* reg 0x01 bit 2 video transfert on */
-	reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
+	reg_w(gspca_dev, 0x01, &regs[0x01], 1);
 	/* reg 0x17 SensorClk enable inv Clk 0x60 */
 	/* reg 0x17 SensorClk enable inv Clk 0x60 */
-	reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
+	reg_w(gspca_dev, 0x17, &regs[0x17], 1);
 	/* Set the registers from the template */
 	/* Set the registers from the template */
-	reg_w(gspca_dev, 0x01, sn9c10x, l);
+	reg_w(gspca_dev, 0x01, &regs[0x01],
+	      (sd->bridge == BRIDGE_103) ? 0x30 : 0x1f);
 
 
 	/* Init the sensor */
 	/* Init the sensor */
 	i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
 	i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
 			sensor_data[sd->sensor].sensor_init_size);
 			sensor_data[sd->sensor].sensor_init_size);
-	if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
-		i2c_w_vector(gspca_dev,
-			sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
-			sensor_data[sd->sensor].sensor_bridge_init_size[
-				sd->bridge]);
 
 
-	/* Mode specific sensor setup */
+	/* Mode / bridge specific sensor setup */
 	switch (sd->sensor) {
 	switch (sd->sensor) {
 	case SENSOR_PAS202: {
 	case SENSOR_PAS202: {
 		const __u8 i2cpclockdiv[] =
 		const __u8 i2cpclockdiv[] =
@@ -1181,27 +1211,37 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		/* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
 		/* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
 		if (mode)
 		if (mode)
 			i2c_w(gspca_dev, i2cpclockdiv);
 			i2c_w(gspca_dev, i2cpclockdiv);
+		break;
 	    }
 	    }
+	case SENSOR_OV7630:
+		/* FIXME / TESTME We should be able to handle this identical
+		   for the 101/102 and the 103 case */
+		if (sd->bridge == BRIDGE_103) {
+			const __u8 i2c[] = { 0xa0, 0x21, 0x13,
+					     0x80, 0x00, 0x00, 0x00, 0x10 };
+			i2c_w(gspca_dev, i2c);
+		}
+		break;
 	}
 	}
 	/* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
 	/* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
-	reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
+	reg_w(gspca_dev, 0x15, &regs[0x15], 2);
 	/* compression register */
 	/* compression register */
-	reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
+	reg_w(gspca_dev, 0x18, &regs[0x18], 1);
 	/* H_start */
 	/* H_start */
-	reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
+	reg_w(gspca_dev, 0x12, &regs[0x12], 1);
 	/* V_START */
 	/* V_START */
-	reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
+	reg_w(gspca_dev, 0x13, &regs[0x13], 1);
 	/* reset 0x17 SensorClk enable inv Clk 0x60 */
 	/* reset 0x17 SensorClk enable inv Clk 0x60 */
 				/*fixme: ov7630 [17]=68 8f (+20 if 102)*/
 				/*fixme: ov7630 [17]=68 8f (+20 if 102)*/
-	reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
+	reg_w(gspca_dev, 0x17, &regs[0x17], 1);
 	/*MCKSIZE ->3 */	/*fixme: not ov7630*/
 	/*MCKSIZE ->3 */	/*fixme: not ov7630*/
-	reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
+	reg_w(gspca_dev, 0x19, &regs[0x19], 1);
 	/* AE_STRX AE_STRY AE_ENDX AE_ENDY */
 	/* AE_STRX AE_STRY AE_ENDX AE_ENDY */
-	reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
+	reg_w(gspca_dev, 0x1c, &regs[0x1c], 4);
 	/* Enable video transfert */
 	/* Enable video transfert */
-	reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
+	reg_w(gspca_dev, 0x01, &regs[0x01], 1);
 	/* Compression */
 	/* Compression */
-	reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
+	reg_w(gspca_dev, 0x18, &regs[0x18], 2);
 	msleep(20);
 	msleep(20);
 
 
 	sd->reg11 = -1;
 	sd->reg11 = -1;
@@ -1525,15 +1565,15 @@ static const struct sd_desc sd_desc = {
 	.driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
 	.driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
 
 
 
 
-static const struct usb_device_id device_table[] __devinitconst = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
 	{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
 	{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
 	{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
 	{USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
 	{USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
 	{USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
 	{USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
 	{USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
 	{USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
 	{USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
 	{USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
 	{USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
+#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
 	{USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
 	{USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
 	{USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
 #endif
 #endif
@@ -1544,18 +1584,22 @@ static const struct usb_device_id device_table[] __devinitconst = {
 	{USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
 	{USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
 	{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
 	{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
 	{USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
 	{USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
-	/* {USB_DEVICE(0x0c45, 0x602b), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
+	/* {USB_DEVICE(0x0c45, 0x6030), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
+	/* {USB_DEVICE(0x0c45, 0x6082), SB(MI03XX, 103)}, */ /* MI0343 MI0360 */
+	{USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)},
+	{USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)},
+	/* {USB_DEVICE(0x0c45, 0x608e), SB(CISVF10, 103)}, */
 	{USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
 	{USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
+	{USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)},
+	{USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)},
 	{USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
 	{USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
-#endif
 	{USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
 	{USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
 	{}
 	{}
 };
 };
 MODULE_DEVICE_TABLE(usb, device_table);
 MODULE_DEVICE_TABLE(usb, device_table);
 
 
 /* -- device connect -- */
 /* -- device connect -- */
-static int __devinit sd_probe(struct usb_interface *intf,
+static int sd_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 			const struct usb_device_id *id)
 {
 {
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

+ 78 - 77
drivers/media/video/gspca/sonixj.c

@@ -25,12 +25,12 @@
 #include "gspca.h"
 #include "gspca.h"
 #include "jpeg.h"
 #include "jpeg.h"
 
 
-#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
-
 MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
 MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
+static int starcam;
+
 /* controls */
 /* controls */
 enum e_ctrl {
 enum e_ctrl {
 	BRIGHTNESS,
 	BRIGHTNESS,
@@ -43,7 +43,7 @@ enum e_ctrl {
 	HFLIP,
 	HFLIP,
 	VFLIP,
 	VFLIP,
 	SHARPNESS,
 	SHARPNESS,
-	INFRARED,
+	ILLUM,
 	FREQ,
 	FREQ,
 	NCTRLS		/* number of controls */
 	NCTRLS		/* number of controls */
 };
 };
@@ -100,7 +100,8 @@ enum sensors {
 };
 };
 
 
 /* device flags */
 /* device flags */
-#define PDN_INV	1		/* inverse pin S_PWR_DN / sn_xxx tables */
+#define F_PDN_INV	0x01	/* inverse pin S_PWR_DN / sn_xxx tables */
+#define F_ILLUM		0x02	/* presence of illuminator */
 
 
 /* sn9c1xx definitions */
 /* sn9c1xx definitions */
 /* register 0x01 */
 /* register 0x01 */
@@ -124,7 +125,7 @@ static void setgamma(struct gspca_dev *gspca_dev);
 static void setautogain(struct gspca_dev *gspca_dev);
 static void setautogain(struct gspca_dev *gspca_dev);
 static void sethvflip(struct gspca_dev *gspca_dev);
 static void sethvflip(struct gspca_dev *gspca_dev);
 static void setsharpness(struct gspca_dev *gspca_dev);
 static void setsharpness(struct gspca_dev *gspca_dev);
-static void setinfrared(struct gspca_dev *gspca_dev);
+static void setillum(struct gspca_dev *gspca_dev);
 static void setfreq(struct gspca_dev *gspca_dev);
 static void setfreq(struct gspca_dev *gspca_dev);
 
 
 static const struct ctrl sd_ctrls[NCTRLS] = {
 static const struct ctrl sd_ctrls[NCTRLS] = {
@@ -251,18 +252,17 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
 	    },
 	    },
 	    .set_control = setsharpness
 	    .set_control = setsharpness
 	},
 	},
-/* mt9v111 only */
-[INFRARED] = {
+[ILLUM] = {
 	    {
 	    {
-		.id      = V4L2_CID_INFRARED,
+		.id      = V4L2_CID_ILLUMINATORS_1,
 		.type    = V4L2_CTRL_TYPE_BOOLEAN,
 		.type    = V4L2_CTRL_TYPE_BOOLEAN,
-		.name    = "Infrared",
+		.name    = "Illuminator / infrared",
 		.minimum = 0,
 		.minimum = 0,
 		.maximum = 1,
 		.maximum = 1,
 		.step    = 1,
 		.step    = 1,
 		.default_value = 0,
 		.default_value = 0,
 	    },
 	    },
-	    .set_control = setinfrared
+	    .set_control = setillum
 	},
 	},
 /* ov7630/ov7648/ov7660 only */
 /* ov7630/ov7648/ov7660 only */
 [FREQ] = {
 [FREQ] = {
@@ -282,32 +282,26 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
 /* table of the disabled controls */
 /* table of the disabled controls */
 static const __u32 ctrl_dis[] = {
 static const __u32 ctrl_dis[] = {
 [SENSOR_ADCM1700] =	(1 << AUTOGAIN) |
 [SENSOR_ADCM1700] =	(1 << AUTOGAIN) |
-			(1 << INFRARED) |
 			(1 << HFLIP) |
 			(1 << HFLIP) |
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
-[SENSOR_GC0307] =	(1 << INFRARED) |
-			(1 << HFLIP) |
+[SENSOR_GC0307] =	(1 << HFLIP) |
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
-[SENSOR_HV7131R] =	(1 << INFRARED) |
-			(1 << HFLIP) |
+[SENSOR_HV7131R] =	(1 << HFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
-[SENSOR_MI0360] =	(1 << INFRARED) |
-			(1 << HFLIP) |
+[SENSOR_MI0360] =	(1 << HFLIP) |
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
-[SENSOR_MI0360B] =	(1 << INFRARED) |
-			(1 << HFLIP) |
+[SENSOR_MI0360B] =	(1 << HFLIP) |
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
-[SENSOR_MO4000] =	(1 << INFRARED) |
-			(1 << HFLIP) |
+[SENSOR_MO4000] =	(1 << HFLIP) |
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
@@ -315,40 +309,32 @@ static const __u32 ctrl_dis[] = {
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
-[SENSOR_OM6802] =	(1 << INFRARED) |
-			(1 << HFLIP) |
+[SENSOR_OM6802] =	(1 << HFLIP) |
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
-[SENSOR_OV7630] =	(1 << INFRARED) |
-			(1 << HFLIP),
+[SENSOR_OV7630] =	(1 << HFLIP),
 
 
-[SENSOR_OV7648] =	(1 << INFRARED) |
-			(1 << HFLIP),
+[SENSOR_OV7648] =	(1 << HFLIP),
 
 
 [SENSOR_OV7660] =	(1 << AUTOGAIN) |
 [SENSOR_OV7660] =	(1 << AUTOGAIN) |
-			(1 << INFRARED) |
 			(1 << HFLIP) |
 			(1 << HFLIP) |
 			(1 << VFLIP),
 			(1 << VFLIP),
 
 
 [SENSOR_PO1030] =	(1 << AUTOGAIN) |
 [SENSOR_PO1030] =	(1 << AUTOGAIN) |
-			(1 << INFRARED) |
 			(1 << HFLIP) |
 			(1 << HFLIP) |
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
 [SENSOR_PO2030N] =	(1 << AUTOGAIN) |
 [SENSOR_PO2030N] =	(1 << AUTOGAIN) |
-			(1 << INFRARED) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
 [SENSOR_SOI768] =	(1 << AUTOGAIN) |
 [SENSOR_SOI768] =	(1 << AUTOGAIN) |
-			(1 << INFRARED) |
 			(1 << HFLIP) |
 			(1 << HFLIP) |
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
 
 
 [SENSOR_SP80708] =	(1 << AUTOGAIN) |
 [SENSOR_SP80708] =	(1 << AUTOGAIN) |
-			(1 << INFRARED) |
 			(1 << HFLIP) |
 			(1 << HFLIP) |
 			(1 << VFLIP) |
 			(1 << VFLIP) |
 			(1 << FREQ),
 			(1 << FREQ),
@@ -1822,44 +1808,46 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
 	PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
 	switch (sd->bridge) {
 	switch (sd->bridge) {
 	case BRIDGE_SN9C102P:
 	case BRIDGE_SN9C102P:
+	case BRIDGE_SN9C105:
 		if (regF1 != 0x11)
 		if (regF1 != 0x11)
 			return -ENODEV;
 			return -ENODEV;
+		break;
+	default:
+/*	case BRIDGE_SN9C110: */
+/*	case BRIDGE_SN9C120: */
+		if (regF1 != 0x12)
+			return -ENODEV;
+	}
+
+	switch (sd->sensor) {
+	case SENSOR_MI0360:
+		mi0360_probe(gspca_dev);
+		break;
+	case SENSOR_OV7630:
+		ov7630_probe(gspca_dev);
+		break;
+	case SENSOR_OV7648:
+		ov7648_probe(gspca_dev);
+		break;
+	case SENSOR_PO2030N:
+		po2030n_probe(gspca_dev);
+		break;
+	}
+
+	switch (sd->bridge) {
+	case BRIDGE_SN9C102P:
 		reg_w1(gspca_dev, 0x02, regGpio[1]);
 		reg_w1(gspca_dev, 0x02, regGpio[1]);
 		break;
 		break;
 	case BRIDGE_SN9C105:
 	case BRIDGE_SN9C105:
-		if (regF1 != 0x11)
-			return -ENODEV;
-		if (sd->sensor == SENSOR_MI0360)
-			mi0360_probe(gspca_dev);
 		reg_w(gspca_dev, 0x01, regGpio, 2);
 		reg_w(gspca_dev, 0x01, regGpio, 2);
 		break;
 		break;
+	case BRIDGE_SN9C110:
+		reg_w1(gspca_dev, 0x02, 0x62);
+		break;
 	case BRIDGE_SN9C120:
 	case BRIDGE_SN9C120:
-		if (regF1 != 0x12)
-			return -ENODEV;
-		switch (sd->sensor) {
-		case SENSOR_MI0360:
-			mi0360_probe(gspca_dev);
-			break;
-		case SENSOR_OV7630:
-			ov7630_probe(gspca_dev);
-			break;
-		case SENSOR_OV7648:
-			ov7648_probe(gspca_dev);
-			break;
-		case SENSOR_PO2030N:
-			po2030n_probe(gspca_dev);
-			break;
-		}
 		regGpio[1] = 0x70;		/* no audio */
 		regGpio[1] = 0x70;		/* no audio */
 		reg_w(gspca_dev, 0x01, regGpio, 2);
 		reg_w(gspca_dev, 0x01, regGpio, 2);
 		break;
 		break;
-	default:
-/*	case BRIDGE_SN9C110: */
-/*	case BRIDGE_SN9C325: */
-		if (regF1 != 0x12)
-			return -ENODEV;
-		reg_w1(gspca_dev, 0x02, 0x62);
-		break;
 	}
 	}
 
 
 	if (sd->sensor == SENSOR_OM6802)
 	if (sd->sensor == SENSOR_OM6802)
@@ -1874,6 +1862,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	sd->i2c_addr = sn9c1xx[9];
 	sd->i2c_addr = sn9c1xx[9];
 
 
 	gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
 	gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
+	if (!(sd->flags & F_ILLUM))
+		gspca_dev->ctrl_dis |= (1 << ILLUM);
 
 
 	return gspca_dev->usb_err;
 	return gspca_dev->usb_err;
 }
 }
@@ -2197,16 +2187,28 @@ static void setsharpness(struct gspca_dev *gspca_dev)
 	reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
 	reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
 }
 }
 
 
-static void setinfrared(struct gspca_dev *gspca_dev)
+static void setillum(struct gspca_dev *gspca_dev)
 {
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct sd *sd = (struct sd *) gspca_dev;
 
 
-	if (gspca_dev->ctrl_dis & (1 << INFRARED))
+	if (gspca_dev->ctrl_dis & (1 << ILLUM))
 		return;
 		return;
-/*fixme: different sequence for StarCam Clip and StarCam 370i */
-/* Clip */
-	i2c_w1(gspca_dev, 0x02,				/* gpio */
-		sd->ctrls[INFRARED].val ? 0x66 : 0x64);
+	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
+		reg_w1(gspca_dev, 0x02,				/* gpio */
+			sd->ctrls[ILLUM].val ? 0x64 : 0x60);
+		break;
+	case SENSOR_MT9V111:
+		if (starcam)
+			reg_w1(gspca_dev, 0x02,
+				sd->ctrls[ILLUM].val ?
+						0x55 : 0x54);	/* 370i */
+		else
+			reg_w1(gspca_dev, 0x02,
+				sd->ctrls[ILLUM].val ?
+						0x66 : 0x64);	/* Clip */
+		break;
+	}
 }
 }
 
 
 static void setfreq(struct gspca_dev *gspca_dev)
 static void setfreq(struct gspca_dev *gspca_dev)
@@ -2344,7 +2346,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	/* sensor clock already enabled in sd_init */
 	/* sensor clock already enabled in sd_init */
 	/* reg_w1(gspca_dev, 0xf1, 0x00); */
 	/* reg_w1(gspca_dev, 0xf1, 0x00); */
 	reg01 = sn9c1xx[1];
 	reg01 = sn9c1xx[1];
-	if (sd->flags & PDN_INV)
+	if (sd->flags & F_PDN_INV)
 		reg01 ^= S_PDN_INV;		/* power down inverted */
 		reg01 ^= S_PDN_INV;		/* power down inverted */
 	reg_w1(gspca_dev, 0x01, reg01);
 	reg_w1(gspca_dev, 0x01, reg01);
 
 
@@ -2907,13 +2909,11 @@ static const struct sd_desc sd_desc = {
 	.driver_info = (BRIDGE_ ## bridge << 16) \
 	.driver_info = (BRIDGE_ ## bridge << 16) \
 			| (SENSOR_ ## sensor << 8) \
 			| (SENSOR_ ## sensor << 8) \
 			| (flags)
 			| (flags)
-static const __devinitdata struct usb_device_id device_table[] = {
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
 	{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
 	{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
 	{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
-#endif
-	{USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, PDN_INV)},
-	{USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)},
+	{USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)},
+	{USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)},
 	{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
 	{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
 	{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
 	{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
 	{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
 	{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
@@ -2925,7 +2925,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
 /*	{USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
 /*	{USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
 	{USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
 	{USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
 /*	{USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
 /*	{USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
-	{USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
+	{USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)},
 						/* or MT9V111 */
 						/* or MT9V111 */
 /*	{USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
 /*	{USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
 /*	{USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
 /*	{USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
@@ -2936,10 +2936,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
 /*	{USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
 /*	{USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
 /*	{USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
 /*	{USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
 	{USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
 	{USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
 	{USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
 	{USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
 	{USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
-#endif
 	{USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)},	/*sn9c128*/
 	{USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)},	/*sn9c128*/
 	{USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)},	/* /GC0305*/
 	{USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)},	/* /GC0305*/
 /*	{USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
 /*	{USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
@@ -2962,16 +2960,15 @@ static const __devinitdata struct usb_device_id device_table[] = {
 /*	{USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
 /*	{USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
 	{USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
 	{USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
 	{USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
 	{USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
 	{USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
-#endif
 	{USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
 	{USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
 	{USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
 	{USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
 	{USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)},	/*sn9c120b*/
 	{USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)},	/*sn9c120b*/
 						/* or GC0305 / GC0307 */
 						/* or GC0305 / GC0307 */
 	{USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)},	/*sn9c120b*/
 	{USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)},	/*sn9c120b*/
 	{USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},	/*sn9c120b*/
 	{USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},	/*sn9c120b*/
-	{USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)},	/*sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)},
+/*	{USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */	/*sn9c120b*/
 	{}
 	{}
 };
 };
 MODULE_DEVICE_TABLE(usb, device_table);
 MODULE_DEVICE_TABLE(usb, device_table);
@@ -3007,3 +3004,7 @@ static void __exit sd_mod_exit(void)
 
 
 module_init(sd_mod_init);
 module_init(sd_mod_init);
 module_exit(sd_mod_exit);
 module_exit(sd_mod_exit);
+
+module_param(starcam, int, 0644);
+MODULE_PARM_DESC(starcam,
+	"StarCam model. 0: Clip, 1: 370i");

+ 1 - 1
drivers/media/video/gspca/spca1528.c

@@ -555,7 +555,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x04fc, 0x1528)},
 	{USB_DEVICE(0x04fc, 0x1528)},
 	{}
 	{}
 };
 };

+ 1 - 1
drivers/media/video/gspca/spca500.c

@@ -1051,7 +1051,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
 	{USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
 	{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
 	{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
 	{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
 	{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},

+ 1 - 1
drivers/media/video/gspca/spca501.c

@@ -2155,7 +2155,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325},
 	{USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325},
 	{USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera},
 	{USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera},
 	{USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite},
 	{USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite},

+ 1 - 1
drivers/media/video/gspca/spca505.c

@@ -786,7 +786,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra},
 	{USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra},
 	{USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro},
 	{USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro},
 /*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */
 /*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */

+ 1 - 1
drivers/media/video/gspca/spca508.c

@@ -1509,7 +1509,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
 	{USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
 	{USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
 	{USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
 	{USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},
 	{USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},

+ 1 - 1
drivers/media/video/gspca/spca561.c

@@ -1061,7 +1061,7 @@ static const struct sd_desc *sd_desc[2] = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
 	{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
 	{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
 	{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
 	{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
 	{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},

+ 1 - 1
drivers/media/video/gspca/sq905.c

@@ -396,7 +396,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 }
 }
 
 
 /* Table of supported USB devices */
 /* Table of supported USB devices */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x2770, 0x9120)},
 	{USB_DEVICE(0x2770, 0x9120)},
 	{}
 	{}
 };
 };

+ 1 - 1
drivers/media/video/gspca/sq905c.c

@@ -298,7 +298,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 }
 }
 
 
 /* Table of supported USB devices */
 /* Table of supported USB devices */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x2770, 0x905c)},
 	{USB_DEVICE(0x2770, 0x905c)},
 	{USB_DEVICE(0x2770, 0x9050)},
 	{USB_DEVICE(0x2770, 0x9050)},
 	{USB_DEVICE(0x2770, 0x9051)},
 	{USB_DEVICE(0x2770, 0x9051)},

+ 1 - 1
drivers/media/video/gspca/sq930x.c

@@ -1163,7 +1163,7 @@ static const struct sd_desc sd_desc = {
 #define ST(sensor, type) \
 #define ST(sensor, type) \
 	.driver_info = (SENSOR_ ## sensor << 8) \
 	.driver_info = (SENSOR_ ## sensor << 8) \
 			| (type)
 			| (type)
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)},
 	{USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)},
 	{USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)},
 	{USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)},
 	{USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)},
 	{USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)},

+ 1 - 1
drivers/media/video/gspca/stk014.c

@@ -495,7 +495,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x05e1, 0x0893)},
 	{USB_DEVICE(0x05e1, 0x0893)},
 	{}
 	{}
 };
 };

+ 1 - 1
drivers/media/video/gspca/stv0680.c

@@ -327,7 +327,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0553, 0x0202)},
 	{USB_DEVICE(0x0553, 0x0202)},
 	{USB_DEVICE(0x041e, 0x4007)},
 	{USB_DEVICE(0x041e, 0x4007)},
 	{}
 	{}

+ 1 - 1
drivers/media/video/gspca/stv06xx/stv06xx.c

@@ -564,7 +564,7 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
 
 
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	/* QuickCam Express */
 	/* QuickCam Express */
 	{USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 },
 	{USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 },
 	/* LEGO cam / QuickCam Web */
 	/* LEGO cam / QuickCam Web */

+ 1 - 1
drivers/media/video/gspca/sunplus.c

@@ -1162,7 +1162,7 @@ static const struct sd_desc sd_desc = {
 #define BS(bridge, subtype) \
 #define BS(bridge, subtype) \
 	.driver_info = (BRIDGE_ ## bridge << 8) \
 	.driver_info = (BRIDGE_ ## bridge << 8) \
 			| (subtype)
 			| (subtype)
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
 	{USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
 	{USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
 	{USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
 	{USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
 	{USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},

+ 1 - 1
drivers/media/video/gspca/t613.c

@@ -1416,7 +1416,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x17a1, 0x0128)},
 	{USB_DEVICE(0x17a1, 0x0128)},
 	{}
 	{}
 };
 };

+ 1 - 1
drivers/media/video/gspca/tv8532.c

@@ -388,7 +388,7 @@ static const struct sd_desc sd_desc = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x046d, 0x0920)},
 	{USB_DEVICE(0x046d, 0x0920)},
 	{USB_DEVICE(0x046d, 0x0921)},
 	{USB_DEVICE(0x046d, 0x0921)},
 	{USB_DEVICE(0x0545, 0x808b)},
 	{USB_DEVICE(0x0545, 0x808b)},

+ 1 - 1
drivers/media/video/gspca/vc032x.c

@@ -4192,7 +4192,7 @@ static const struct sd_desc sd_desc = {
 #define BF(bridge, flags) \
 #define BF(bridge, flags) \
 	.driver_info = (BRIDGE_ ## bridge << 8) \
 	.driver_info = (BRIDGE_ ## bridge << 8) \
 		| (flags)
 		| (flags)
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)},
 	{USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)},
 	{USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)},
 	{USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)},
 	{USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)},
 	{USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)},

+ 1 - 1
drivers/media/video/gspca/xirlink_cit.c

@@ -3270,7 +3270,7 @@ static const struct sd_desc sd_desc_isoc_nego = {
 };
 };
 
 
 /* -- module initialisation -- */
 /* -- module initialisation -- */
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },

+ 1 - 1
drivers/media/video/gspca/zc3xx.c

@@ -6909,7 +6909,7 @@ static const struct sd_desc sd_desc = {
 #endif
 #endif
 };
 };
 
 
-static const __devinitdata struct usb_device_id device_table[] = {
+static const struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x041e, 0x041e)},
 	{USB_DEVICE(0x041e, 0x041e)},
 	{USB_DEVICE(0x041e, 0x4017)},
 	{USB_DEVICE(0x041e, 0x4017)},
 	{USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106},
 	{USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106},

+ 1 - 3
drivers/media/video/hdpvr/Makefile

@@ -1,6 +1,4 @@
-hdpvr-objs	:= hdpvr-control.o hdpvr-core.o hdpvr-video.o
-
-hdpvr-$(CONFIG_I2C) += hdpvr-i2c.o
+hdpvr-objs	:= hdpvr-control.o hdpvr-core.o hdpvr-video.o hdpvr-i2c.o
 
 
 obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o
 obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o
 
 

+ 4 - 6
drivers/media/video/hdpvr/hdpvr-core.c

@@ -378,19 +378,17 @@ static int hdpvr_probe(struct usb_interface *interface,
 		goto error;
 		goto error;
 	}
 	}
 
 
-#ifdef CONFIG_I2C
-	/* until i2c is working properly */
-	retval = 0; /* hdpvr_register_i2c_adapter(dev); */
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+	retval = hdpvr_register_i2c_adapter(dev);
 	if (retval < 0) {
 	if (retval < 0) {
 		v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
 		v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
 		goto error;
 		goto error;
 	}
 	}
 
 
-	/* until i2c is working properly */
-	retval = 0; /* hdpvr_register_i2c_ir(dev); */
+	retval = hdpvr_register_i2c_ir(dev);
 	if (retval < 0)
 	if (retval < 0)
 		v4l2_err(&dev->v4l2_dev, "registering i2c IR devices failed\n");
 		v4l2_err(&dev->v4l2_dev, "registering i2c IR devices failed\n");
-#endif /* CONFIG_I2C */
+#endif
 
 
 	/* let the user know what node this device is now attached to */
 	/* let the user know what node this device is now attached to */
 	v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",
 	v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",

+ 67 - 76
drivers/media/video/hdpvr/hdpvr-i2c.c

@@ -13,6 +13,8 @@
  *
  *
  */
  */
 
 
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 
 
@@ -28,106 +30,78 @@
 #define Z8F0811_IR_TX_I2C_ADDR	0x70
 #define Z8F0811_IR_TX_I2C_ADDR	0x70
 #define Z8F0811_IR_RX_I2C_ADDR	0x71
 #define Z8F0811_IR_RX_I2C_ADDR	0x71
 
 
-static const u8 ir_i2c_addrs[] = {
-	Z8F0811_IR_TX_I2C_ADDR,
-	Z8F0811_IR_RX_I2C_ADDR,
-};
 
 
-static const char * const ir_devicenames[] = {
-	"ir_tx_z8f0811_hdpvr",
-	"ir_rx_z8f0811_hdpvr",
+static struct i2c_board_info hdpvr_i2c_board_info = {
+	I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
+	I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
 };
 };
 
 
-static int hdpvr_new_i2c_ir(struct hdpvr_device *dev, struct i2c_adapter *adap,
-			    const char *type, u8 addr)
+int hdpvr_register_i2c_ir(struct hdpvr_device *dev)
 {
 {
-	struct i2c_board_info info;
+	struct i2c_client *c;
 	struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
 	struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
-	unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strlcpy(info.type, type, I2C_NAME_SIZE);
 
 
 	/* Our default information for ir-kbd-i2c.c to use */
 	/* Our default information for ir-kbd-i2c.c to use */
-	switch (addr) {
-	case Z8F0811_IR_RX_I2C_ADDR:
-		init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
-		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-		init_data->type = RC_TYPE_RC5;
-		init_data->name = "HD PVR";
-		info.platform_data = init_data;
-		break;
-	}
+	init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
+	init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
+	init_data->type = RC_TYPE_RC5;
+	init_data->name = "HD PVR";
+	hdpvr_i2c_board_info.platform_data = init_data;
 
 
-	return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
-	       -1 : 0;
-}
+	c = i2c_new_device(&dev->i2c_adapter, &hdpvr_i2c_board_info);
 
 
-int hdpvr_register_i2c_ir(struct hdpvr_device *dev)
-{
-	int i;
-	int ret = 0;
-
-	for (i = 0; i < ARRAY_SIZE(ir_i2c_addrs); i++)
-		ret += hdpvr_new_i2c_ir(dev, dev->i2c_adapter,
-					ir_devicenames[i], ir_i2c_addrs[i]);
-
-	return ret;
+	return (c == NULL) ? -ENODEV : 0;
 }
 }
 
 
-static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr,
-			  char *data, int len)
+static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
+			  unsigned char addr, char *data, int len)
 {
 {
 	int ret;
 	int ret;
-	char *buf = kmalloc(len, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
+
+	if (len > sizeof(dev->i2c_buf))
+		return -EINVAL;
 
 
 	ret = usb_control_msg(dev->udev,
 	ret = usb_control_msg(dev->udev,
 			      usb_rcvctrlpipe(dev->udev, 0),
 			      usb_rcvctrlpipe(dev->udev, 0),
 			      REQTYPE_I2C_READ, CTRL_READ_REQUEST,
 			      REQTYPE_I2C_READ, CTRL_READ_REQUEST,
-			      0x100|addr, 0, buf, len, 1000);
+			      (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
 
 
 	if (ret == len) {
 	if (ret == len) {
-		memcpy(data, buf, len);
+		memcpy(data, &dev->i2c_buf, len);
 		ret = 0;
 		ret = 0;
 	} else if (ret >= 0)
 	} else if (ret >= 0)
 		ret = -EIO;
 		ret = -EIO;
 
 
-	kfree(buf);
-
 	return ret;
 	return ret;
 }
 }
 
 
-static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr,
-			   char *data, int len)
+static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus,
+			   unsigned char addr, char *data, int len)
 {
 {
 	int ret;
 	int ret;
-	char *buf = kmalloc(len, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
 
 
-	memcpy(buf, data, len);
+	if (len > sizeof(dev->i2c_buf))
+		return -EINVAL;
+
+	memcpy(&dev->i2c_buf, data, len);
 	ret = usb_control_msg(dev->udev,
 	ret = usb_control_msg(dev->udev,
 			      usb_sndctrlpipe(dev->udev, 0),
 			      usb_sndctrlpipe(dev->udev, 0),
 			      REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
 			      REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
-			      0x100|addr, 0, buf, len, 1000);
+			      (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
 
 
 	if (ret < 0)
 	if (ret < 0)
-		goto error;
+		return ret;
 
 
 	ret = usb_control_msg(dev->udev,
 	ret = usb_control_msg(dev->udev,
 			      usb_rcvctrlpipe(dev->udev, 0),
 			      usb_rcvctrlpipe(dev->udev, 0),
 			      REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
 			      REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
-			      0, 0, buf, 2, 1000);
+			      0, 0, &dev->i2c_buf, 2, 1000);
 
 
-	if (ret == 2)
+	if ((ret == 2) && (dev->i2c_buf[1] == (len - 1)))
 		ret = 0;
 		ret = 0;
 	else if (ret >= 0)
 	else if (ret >= 0)
 		ret = -EIO;
 		ret = -EIO;
 
 
-error:
-	kfree(buf);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -146,10 +120,10 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
 		addr = msgs[i].addr << 1;
 		addr = msgs[i].addr << 1;
 
 
 		if (msgs[i].flags & I2C_M_RD)
 		if (msgs[i].flags & I2C_M_RD)
-			retval = hdpvr_i2c_read(dev, addr, msgs[i].buf,
+			retval = hdpvr_i2c_read(dev, 1, addr, msgs[i].buf,
 						msgs[i].len);
 						msgs[i].len);
 		else
 		else
-			retval = hdpvr_i2c_write(dev, addr, msgs[i].buf,
+			retval = hdpvr_i2c_write(dev, 1, addr, msgs[i].buf,
 						 msgs[i].len);
 						 msgs[i].len);
 	}
 	}
 
 
@@ -168,30 +142,47 @@ static struct i2c_algorithm hdpvr_algo = {
 	.functionality = hdpvr_functionality,
 	.functionality = hdpvr_functionality,
 };
 };
 
 
+static struct i2c_adapter hdpvr_i2c_adapter_template = {
+	.name   = "Hauppage HD PVR I2C",
+	.owner  = THIS_MODULE,
+	.algo   = &hdpvr_algo,
+};
+
+static int hdpvr_activate_ir(struct hdpvr_device *dev)
+{
+	char buffer[8];
+
+	mutex_lock(&dev->i2c_mutex);
+
+	hdpvr_i2c_read(dev, 0, 0x54, buffer, 1);
+
+	buffer[0] = 0;
+	buffer[1] = 0x8;
+	hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
+
+	buffer[1] = 0x18;
+	hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
+
+	mutex_unlock(&dev->i2c_mutex);
+
+	return 0;
+}
+
 int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
 int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
 {
 {
-	struct i2c_adapter *i2c_adap;
 	int retval = -ENOMEM;
 	int retval = -ENOMEM;
 
 
-	i2c_adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (i2c_adap == NULL)
-		goto error;
-
-	strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C",
-		sizeof(i2c_adap->name));
-	i2c_adap->algo  = &hdpvr_algo;
-	i2c_adap->owner = THIS_MODULE;
-	i2c_adap->dev.parent = &dev->udev->dev;
+	hdpvr_activate_ir(dev);
 
 
-	i2c_set_adapdata(i2c_adap, dev);
+	memcpy(&dev->i2c_adapter, &hdpvr_i2c_adapter_template,
+	       sizeof(struct i2c_adapter));
+	dev->i2c_adapter.dev.parent = &dev->udev->dev;
 
 
-	retval = i2c_add_adapter(i2c_adap);
+	i2c_set_adapdata(&dev->i2c_adapter, dev);
 
 
-	if (!retval)
-		dev->i2c_adapter = i2c_adap;
-	else
-		kfree(i2c_adap);
+	retval = i2c_add_adapter(&dev->i2c_adapter);
 
 
-error:
 	return retval;
 	return retval;
 }
 }
+
+#endif

+ 2 - 5
drivers/media/video/hdpvr/hdpvr-video.c

@@ -1220,12 +1220,9 @@ static void hdpvr_device_release(struct video_device *vdev)
 	v4l2_device_unregister(&dev->v4l2_dev);
 	v4l2_device_unregister(&dev->v4l2_dev);
 
 
 	/* deregister I2C adapter */
 	/* deregister I2C adapter */
-#ifdef CONFIG_I2C
+#if defined(CONFIG_I2C) || (CONFIG_I2C_MODULE)
 	mutex_lock(&dev->i2c_mutex);
 	mutex_lock(&dev->i2c_mutex);
-	if (dev->i2c_adapter)
-		i2c_del_adapter(dev->i2c_adapter);
-	kfree(dev->i2c_adapter);
-	dev->i2c_adapter = NULL;
+	i2c_del_adapter(&dev->i2c_adapter);
 	mutex_unlock(&dev->i2c_mutex);
 	mutex_unlock(&dev->i2c_mutex);
 #endif /* CONFIG_I2C */
 #endif /* CONFIG_I2C */
 
 

+ 4 - 1
drivers/media/video/hdpvr/hdpvr.h

@@ -25,6 +25,7 @@
 	KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE)
 	KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE)
 
 
 #define HDPVR_MAX 8
 #define HDPVR_MAX 8
+#define HDPVR_I2C_MAX_SIZE 128
 
 
 /* Define these values to match your devices */
 /* Define these values to match your devices */
 #define HD_PVR_VENDOR_ID	0x2040
 #define HD_PVR_VENDOR_ID	0x2040
@@ -106,9 +107,11 @@ struct hdpvr_device {
 	struct work_struct	worker;
 	struct work_struct	worker;
 
 
 	/* I2C adapter */
 	/* I2C adapter */
-	struct i2c_adapter	*i2c_adapter;
+	struct i2c_adapter	i2c_adapter;
 	/* I2C lock */
 	/* I2C lock */
 	struct mutex		i2c_mutex;
 	struct mutex		i2c_mutex;
+	/* I2C message buffer space */
+	char			i2c_buf[HDPVR_I2C_MAX_SIZE];
 
 
 	/* For passing data to ir-kbd-i2c */
 	/* For passing data to ir-kbd-i2c */
 	struct IR_i2c_init_data	ir_i2c_init_data;
 	struct IR_i2c_init_data	ir_i2c_init_data;

+ 10 - 2
drivers/media/video/ir-kbd-i2c.c

@@ -244,15 +244,17 @@ static void ir_key_poll(struct IR_i2c *ir)
 	static u32 ir_key, ir_raw;
 	static u32 ir_key, ir_raw;
 	int rc;
 	int rc;
 
 
-	dprintk(2,"ir_poll_key\n");
+	dprintk(3, "%s\n", __func__);
 	rc = ir->get_key(ir, &ir_key, &ir_raw);
 	rc = ir->get_key(ir, &ir_key, &ir_raw);
 	if (rc < 0) {
 	if (rc < 0) {
 		dprintk(2,"error\n");
 		dprintk(2,"error\n");
 		return;
 		return;
 	}
 	}
 
 
-	if (rc)
+	if (rc) {
+		dprintk(1, "%s: keycode = 0x%04x\n", __func__, ir_key);
 		rc_keydown(ir->rc, ir_key, 0);
 		rc_keydown(ir->rc, ir_key, 0);
+	}
 }
 }
 
 
 static void ir_work(struct work_struct *work)
 static void ir_work(struct work_struct *work)
@@ -321,6 +323,12 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		rc_type     = RC_TYPE_OTHER;
 		rc_type     = RC_TYPE_OTHER;
 		ir_codes    = RC_MAP_AVERMEDIA_CARDBUS;
 		ir_codes    = RC_MAP_AVERMEDIA_CARDBUS;
 		break;
 		break;
+	case 0x71:
+		name        = "Hauppauge/Zilog Z8";
+		ir->get_key = get_key_haup_xvr;
+		rc_type     = RC_TYPE_RC5;
+		ir_codes    = hauppauge ? RC_MAP_HAUPPAUGE_NEW : RC_MAP_RC5_TV;
+		break;
 	}
 	}
 
 
 	/* Let the caller override settings */
 	/* Let the caller override settings */

+ 7 - 2
drivers/media/video/ivtv/ivtv-i2c.c

@@ -300,10 +300,15 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
 				adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
 				adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
 	} else if (hw == IVTV_HW_CX25840) {
 	} else if (hw == IVTV_HW_CX25840) {
 		struct cx25840_platform_data pdata;
 		struct cx25840_platform_data pdata;
+		struct i2c_board_info cx25840_info = {
+			.type = "cx25840",
+			.addr = hw_addrs[idx],
+			.platform_data = &pdata,
+		};
 
 
 		pdata.pvr150_workaround = itv->pvr150_workaround;
 		pdata.pvr150_workaround = itv->pvr150_workaround;
-		sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev,
-				adap, type, 0, &pdata, hw_addrs[idx], NULL);
+		sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap,
+				&cx25840_info, NULL);
 	} else {
 	} else {
 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
 				adap, type, hw_addrs[idx], NULL);
 				adap, type, hw_addrs[idx], NULL);

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно