소스 검색

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

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (95 commits)
  V4L/DVB (9296): Patch to remove warning message during cx88-dvb compilation
  V4L/DVB (9294): gspca: Add a stop sequence in t613.
  V4L/DVB (9293): gspca: Separate and fix the sensor dependant sequences in t613.
  V4L/DVB (9292): gspca: Call the control setting functions at init time in t613.
  V4L/DVB (9291): gspca: Do not set the white balance temperature by default in t613.
  V4L/DVB (9290): gspca: Adjust the sensor init sequences in t613.
  V4L/DVB (9289): gspca: Other sensor identified as om6802 in t613.
  V4L/DVB (9288): gspca: Write to the USB device and not USB interface in t613.
  V4L/DVB (9287): gspca: Change the name of the multi bytes write function in t613.
  V4L/DVB (9286): gspca: Compilation problem of gspca.c and the kernel version.
  V4L/DVB (9283): Correct typo and enable setting the gain on the mt9m111 sensor
  V4L/DVB (9282): Properly iterate the urbs when destroying them.
  V4L/DVB (9281): gspca: Add hflip and vflip to the po1030 sensor
  V4L/DVB (9280): gspca: Use the gspca debug macros
  V4L/DVB (9279): gspca: Correct some copyright headers
  V4L/DVB (9278): gspca: Remove the m5602_debug variable
  V4L/DVB (9277): gspca: propagate an error in m5602_start_transfer()
  V4L/DVB (9276): videobuf-dvb: two functions are now static
  V4L/DVB (9275): dvb: input data pointer of cx24116_writeregN() should be const
  V4L/DVB (9274): Remove spurious messages and turn into debug.
  ...
Linus Torvalds 16 년 전
부모
커밋
5564da7e9d
92개의 변경된 파일4068개의 추가작업 그리고 4160개의 파일을 삭제
  1. 1 1
      Documentation/video4linux/CARDLIST.au0828
  2. 1 0
      Documentation/video4linux/CARDLIST.tuner
  3. 7 3
      drivers/media/common/tuners/mxl5005s.c
  4. 2 0
      drivers/media/common/tuners/tuner-simple.c
  5. 32 1
      drivers/media/common/tuners/tuner-types.c
  6. 37 36
      drivers/media/common/tuners/xc5000.c
  7. 4 4
      drivers/media/common/tuners/xc5000.h
  8. 12 0
      drivers/media/dvb/dm1105/dm1105.c
  9. 85 49
      drivers/media/dvb/dvb-core/dvb_frontend.c
  10. 1 0
      drivers/media/dvb/dvb-core/dvb_frontend.h
  11. 3 0
      drivers/media/dvb/dvb-core/dvbdev.c
  12. 4 0
      drivers/media/dvb/dvb-core/dvbdev.h
  13. 12 0
      drivers/media/dvb/dvb-usb/dw2102.c
  14. 306 200
      drivers/media/dvb/frontends/cx22702.c
  15. 11 9
      drivers/media/dvb/frontends/cx22702.h
  16. 306 249
      drivers/media/dvb/frontends/cx24116.c
  17. 11 10
      drivers/media/dvb/frontends/cx24116.h
  18. 128 100
      drivers/media/dvb/frontends/cx24123.c
  19. 5 5
      drivers/media/dvb/frontends/cx24123.h
  20. 70 68
      drivers/media/dvb/frontends/s5h1409.c
  21. 8 7
      drivers/media/dvb/frontends/s5h1409.h
  22. 4 4
      drivers/media/dvb/frontends/s5h1411.c
  23. 73 27
      drivers/media/dvb/frontends/tda10048.c
  24. 2 14
      drivers/media/dvb/frontends/z0194a.h
  25. 4 0
      drivers/media/dvb/siano/sms-cards.c
  26. 1 1
      drivers/media/radio/Kconfig
  27. 97 137
      drivers/media/radio/radio-si470x.c
  28. 57 194
      drivers/media/video/adv7170.c
  29. 60 183
      drivers/media/video/adv7175.c
  30. 4 1
      drivers/media/video/au0828/au0828-cards.c
  31. 2 1
      drivers/media/video/au0828/au0828-core.c
  32. 2 1
      drivers/media/video/au0828/au0828-dvb.c
  33. 92 229
      drivers/media/video/bt819.c
  34. 49 169
      drivers/media/video/bt856.c
  35. 83 172
      drivers/media/video/bt866.c
  36. 89 63
      drivers/media/video/cx23885/cx23885-cards.c
  37. 156 120
      drivers/media/video/cx23885/cx23885-core.c
  38. 116 74
      drivers/media/video/cx23885/cx23885-dvb.c
  39. 24 23
      drivers/media/video/cx23885/cx23885-i2c.c
  40. 13 12
      drivers/media/video/cx23885/cx23885-video.c
  41. 11 15
      drivers/media/video/cx23885/cx23885.h
  42. 51 7
      drivers/media/video/cx88/cx88-cards.c
  43. 2 1
      drivers/media/video/cx88/cx88-core.c
  44. 273 132
      drivers/media/video/cx88/cx88-dvb.c
  45. 12 5
      drivers/media/video/cx88/cx88-i2c.c
  46. 21 1
      drivers/media/video/cx88/cx88-mpeg.c
  47. 11 0
      drivers/media/video/cx88/cx88-tvaudio.c
  48. 30 22
      drivers/media/video/cx88/cx88-video.c
  49. 5 2
      drivers/media/video/cx88/cx88.h
  50. 2 1
      drivers/media/video/gspca/gspca.c
  51. 0 1
      drivers/media/video/gspca/gspca.h
  52. 1 28
      drivers/media/video/gspca/m5602/m5602_bridge.h
  53. 21 25
      drivers/media/video/gspca/m5602/m5602_core.c
  54. 9 9
      drivers/media/video/gspca/m5602/m5602_mt9m111.c
  55. 3 4
      drivers/media/video/gspca/m5602/m5602_mt9m111.h
  56. 20 20
      drivers/media/video/gspca/m5602/m5602_ov9650.c
  57. 1 2
      drivers/media/video/gspca/m5602/m5602_ov9650.h
  58. 77 13
      drivers/media/video/gspca/m5602/m5602_po1030.c
  59. 38 8
      drivers/media/video/gspca/m5602/m5602_po1030.h
  60. 11 11
      drivers/media/video/gspca/m5602/m5602_s5k4aa.c
  61. 1 2
      drivers/media/video/gspca/m5602/m5602_s5k4aa.h
  62. 3 3
      drivers/media/video/gspca/m5602/m5602_s5k83a.c
  63. 1 3
      drivers/media/video/gspca/m5602/m5602_s5k83a.h
  64. 1 1
      drivers/media/video/gspca/m5602/m5602_sensor.h
  65. 239 136
      drivers/media/video/gspca/t613.c
  66. 8 7
      drivers/media/video/ivtv/ivtv-fileops.c
  67. 16 2
      drivers/media/video/ivtv/ivtv-ioctl.c
  68. 212 264
      drivers/media/video/ks0127.c
  69. 64 178
      drivers/media/video/saa7110.c
  70. 58 166
      drivers/media/video/saa7111.c
  71. 108 256
      drivers/media/video/saa7114.c
  72. 1 1
      drivers/media/video/saa7127.c
  73. 123 93
      drivers/media/video/saa7134/saa7134-dvb.c
  74. 1 1
      drivers/media/video/saa7134/saa7134.h
  75. 50 160
      drivers/media/video/saa7185.c
  76. 61 35
      drivers/media/video/sh_mobile_ceu_camera.c
  77. 11 9
      drivers/media/video/soc_camera_platform.c
  78. 8 19
      drivers/media/video/stk-webcam.c
  79. 0 1
      drivers/media/video/stk-webcam.h
  80. 1 1
      drivers/media/video/tveeprom.c
  81. 167 34
      drivers/media/video/videobuf-dvb.c
  82. 207 71
      drivers/media/video/vivi.c
  83. 91 237
      drivers/media/video/vpx3220.c
  84. 1 0
      drivers/media/video/zoran/zoran_card.c
  85. 0 1
      drivers/media/video/zoran/zoran_driver.c
  86. 2 0
      include/linux/dvb/frontend.h
  87. 1 1
      include/linux/i2c-id.h
  88. 11 0
      include/media/soc_camera_platform.h
  89. 1 0
      include/media/tuner.h
  90. 11 0
      include/media/v4l2-i2c-drv-legacy.h
  91. 11 0
      include/media/v4l2-i2c-drv.h
  92. 25 4
      include/media/videobuf-dvb.h

+ 1 - 1
Documentation/video4linux/CARDLIST.au0828

@@ -1,5 +1,5 @@
   0 -> Unknown board                            (au0828)
-  1 -> Hauppauge HVR950Q                        (au0828)        [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
+  1 -> Hauppauge HVR950Q                        (au0828)        [2040:7200,2040:7210,2040:7217,2040:721b,2040:721e,2040:721f,2040:7280,0fd9:0008]
   2 -> Hauppauge HVR850                         (au0828)        [2040:7240]
   3 -> DViCO FusionHDTV USB                     (au0828)        [0fe9:d620]
   4 -> Hauppauge HVR950Q rev xxF8               (au0828)        [2040:7201,2040:7211,2040:7281]

+ 1 - 0
Documentation/video4linux/CARDLIST.tuner

@@ -75,3 +75,4 @@ tuner=73 - Samsung TCPG 6121P30A
 tuner=75 - Philips TEA5761 FM Radio
 tuner=76 - Xceive 5000 tuner
 tuner=77 - TCL tuner MF02GIP-5N-E
+tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner

+ 7 - 3
drivers/media/common/tuners/mxl5005s.c

@@ -3481,7 +3481,9 @@ static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
 					}
 					ctrlVal = 0;
 					for (k = 0; k < state->MXL_Ctrl[i].size; k++)
-						ctrlVal += state->MXL_Ctrl[i].val[k] * (1 << k);
+						ctrlVal += state->
+							MXL_Ctrl[i].val[k] *
+							(1 << k);
 				} else
 					return -1;
 			}
@@ -3581,7 +3583,7 @@ static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
 
 static u32 MXL_Ceiling(u32 value, u32 resolution)
 {
-	return (value/resolution + (value % resolution > 0 ? 1 : 0));
+	return value / resolution + (value % resolution > 0 ? 1 : 0);
 }
 
 /* Retrieve the Initialzation Registers */
@@ -3910,7 +3912,10 @@ static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
 
 static int mxl5005s_init(struct dvb_frontend *fe)
 {
+	struct mxl5005s_state *state = fe->tuner_priv;
+
 	dprintk(1, "%s()\n", __func__);
+	state->current_mode = MXL_QAM;
 	return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ);
 }
 
@@ -4092,7 +4097,6 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
 	state->frontend = fe;
 	state->config = config;
 	state->i2c = i2c;
-	state->current_mode = MXL_QAM;
 
 	printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n",
 		config->i2c_address);

+ 2 - 0
drivers/media/common/tuners/tuner-simple.c

@@ -493,6 +493,7 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
 	case TUNER_PHILIPS_FM1216ME_MK3:
 	case TUNER_PHILIPS_FM1236_MK3:
 	case TUNER_PHILIPS_FMD1216ME_MK3:
+	case TUNER_PHILIPS_FMD1216MEX_MK3:
 	case TUNER_LG_NTSC_TAPE:
 	case TUNER_PHILIPS_FM1256_IH3:
 	case TUNER_TCL_MF02GIP_5N:
@@ -767,6 +768,7 @@ static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf,
 
 	switch (priv->type) {
 	case TUNER_PHILIPS_FMD1216ME_MK3:
+	case TUNER_PHILIPS_FMD1216MEX_MK3:
 		if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ &&
 		    params->frequency >= 158870000)
 			buf[3] |= 0x08;

+ 32 - 1
drivers/media/common/tuners/tuner-types.c

@@ -946,7 +946,7 @@ static struct tuner_params tuner_tena_9533_di_params[] = {
 	},
 };
 
-/* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */
+/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */
 
 static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
 	{ 16 * 160.00 /*MHz*/, 0x86, 0x51, },
@@ -984,6 +984,27 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
 	},
 };
 
+static struct tuner_params tuner_philips_fmd1216mex_mk3_params[] = {
+	{
+		.type   = TUNER_PARAM_TYPE_PAL,
+		.ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
+		.count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
+		.has_tda9887 = 1,
+		.port1_active = 1,
+		.port2_active = 1,
+		.port2_fm_high_sensitivity = 1,
+		.port2_invert_for_secam_lc = 1,
+		.port1_set_for_fm_mono = 1,
+		.radio_if = 1,
+		.fm_gain_normal = 1,
+	},
+	{
+		.type   = TUNER_PARAM_TYPE_DIGITAL,
+		.ranges = tuner_philips_fmd1216me_mk3_dvb_ranges,
+		.count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges),
+		.iffreq = 16 * 36.125, /*MHz*/
+	},
+};
 
 /* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */
 
@@ -1663,6 +1684,16 @@ struct tunertype tuners[] = {
 		.params = tuner_tcl_mf02gip_5n_params,
 		.count  = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params),
 	},
+	[TUNER_PHILIPS_FMD1216MEX_MK3] = { /* Philips PAL */
+		.name   = "Philips FMD1216MEX MK3 Hybrid Tuner",
+		.params = tuner_philips_fmd1216mex_mk3_params,
+		.count  = ARRAY_SIZE(tuner_philips_fmd1216mex_mk3_params),
+		.min = 16 *  50.87,
+		.max = 16 * 858.00,
+		.stepsize = 166667,
+		.initdata = tua603x_agc112,
+		.sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
+	},
 };
 EXPORT_SYMBOL(tuners);
 

+ 37 - 36
drivers/media/common/tuners/xc5000.c

@@ -43,7 +43,7 @@ MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization.");
 static DEFINE_MUTEX(xc5000_list_mutex);
 static LIST_HEAD(hybrid_tuner_instance_list);
 
-#define dprintk(level,fmt, arg...) if (debug >= level) \
+#define dprintk(level, fmt, arg...) if (debug >= level) \
 	printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
 
 #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw"
@@ -138,11 +138,11 @@ struct xc5000_priv {
    immediately the length of the following transaction.
 
 */
-typedef struct {
+struct XC_TV_STANDARD {
 	char *Name;
 	u16 AudioMode;
 	u16 VideoMode;
-} XC_TV_STANDARD;
+};
 
 /* Tuner standards */
 #define MN_NTSC_PAL_BTSC	0
@@ -169,7 +169,7 @@ typedef struct {
 #define FM_Radio_INPUT2 	21
 #define FM_Radio_INPUT1 	22
 
-static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
+static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
 	{"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
 	{"M/N-NTSC/PAL-A2",   0x0600, 0x8020},
 	{"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
@@ -183,7 +183,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
 	{"D/K-PAL-NICAM",     0x0E80, 0x8009},
 	{"D/K-PAL-MONO",      0x1478, 0x8009},
 	{"D/K-SECAM-A2 DK1",  0x1200, 0x8009},
-	{"D/K-SECAM-A2 L/DK3",0x0E00, 0x8009},
+	{"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
 	{"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
 	{"L-SECAM-NICAM",     0x8E82, 0x0009},
 	{"L'-SECAM-NICAM",    0x8E82, 0x4009},
@@ -307,9 +307,10 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
 	unsigned int len, pos, index;
 	u8 buf[XC_MAX_I2C_WRITE_LENGTH];
 
-	index=0;
-	while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) {
-		len = i2c_sequence[index]* 256 + i2c_sequence[index+1];
+	index = 0;
+	while ((i2c_sequence[index] != 0xFF) ||
+		(i2c_sequence[index + 1] != 0xFF)) {
+		len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
 		if (len == 0x0000) {
 			/* RESET command */
 			result = xc_reset(fe);
@@ -329,15 +330,17 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
 			buf[1] = i2c_sequence[index + 1];
 			pos = 2;
 			while (pos < len) {
-				if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2) {
-					nbytes_to_send = XC_MAX_I2C_WRITE_LENGTH;
-				} else {
+				if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
+					nbytes_to_send =
+						XC_MAX_I2C_WRITE_LENGTH;
+				else
 					nbytes_to_send = (len - pos + 2);
+				for (i = 2; i < nbytes_to_send; i++) {
+					buf[i] = i2c_sequence[index + pos +
+						i - 2];
 				}
-				for (i=2; i<nbytes_to_send; i++) {
-					buf[i] = i2c_sequence[index + pos + i - 2];
-				}
-				result = xc_send_i2c_data(priv, buf, nbytes_to_send);
+				result = xc_send_i2c_data(priv, buf,
+					nbytes_to_send);
 
 				if (result != XC_RESULT_SUCCESS)
 					return result;
@@ -386,8 +389,7 @@ static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
 	dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
 		rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
 
-	if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE))
-	{
+	if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
 		rf_mode = XC_RF_MODE_CABLE;
 		printk(KERN_ERR
 			"%s(), Invalid mode, defaulting to CABLE",
@@ -560,13 +562,13 @@ static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len)
 		.flags = I2C_M_RD, .buf = buf, .len = len };
 
 	if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
-		printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n",(int)len);
+		printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len);
 		return -EREMOTEIO;
 	}
 	return 0;
 }
 
-static int xc5000_fwupload(struct dvb_frontend* fe)
+static int xc5000_fwupload(struct dvb_frontend *fe)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
 	const struct firmware *fw;
@@ -576,7 +578,8 @@ static int xc5000_fwupload(struct dvb_frontend* fe)
 	printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
 		XC5000_DEFAULT_FIRMWARE);
 
-	ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c_props.adap->dev);
+	ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE,
+		&priv->i2c_props.adap->dev);
 	if (ret) {
 		printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
 		ret = XC_RESULT_RESET_FAILURE;
@@ -592,7 +595,7 @@ static int xc5000_fwupload(struct dvb_frontend* fe)
 		ret = XC_RESULT_RESET_FAILURE;
 	} else {
 		printk(KERN_INFO "xc5000: firmware upload\n");
-		ret = xc_load_i2c_sequence(fe,  fw->data );
+		ret = xc_load_i2c_sequence(fe,  fw->data);
 	}
 
 out:
@@ -651,7 +654,7 @@ static int xc5000_set_params(struct dvb_frontend *fe,
 
 	dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
 
-	switch(params->u.vsb.modulation) {
+	switch (params->u.vsb.modulation) {
 	case VSB_8:
 	case VSB_16:
 		dprintk(1, "%s() VSB modulation\n", __func__);
@@ -748,42 +751,42 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
 	/* FIX ME: Some video standards may have several possible audio
 		   standards. We simply default to one of them here.
 	 */
-	if(params->std & V4L2_STD_MN) {
+	if (params->std & V4L2_STD_MN) {
 		/* default to BTSC audio standard */
 		priv->video_standard = MN_NTSC_PAL_BTSC;
 		goto tune_channel;
 	}
 
-	if(params->std & V4L2_STD_PAL_BG) {
+	if (params->std & V4L2_STD_PAL_BG) {
 		/* default to NICAM audio standard */
 		priv->video_standard = BG_PAL_NICAM;
 		goto tune_channel;
 	}
 
-	if(params->std & V4L2_STD_PAL_I) {
+	if (params->std & V4L2_STD_PAL_I) {
 		/* default to NICAM audio standard */
 		priv->video_standard = I_PAL_NICAM;
 		goto tune_channel;
 	}
 
-	if(params->std & V4L2_STD_PAL_DK) {
+	if (params->std & V4L2_STD_PAL_DK) {
 		/* default to NICAM audio standard */
 		priv->video_standard = DK_PAL_NICAM;
 		goto tune_channel;
 	}
 
-	if(params->std & V4L2_STD_SECAM_DK) {
+	if (params->std & V4L2_STD_SECAM_DK) {
 		/* default to A2 DK1 audio standard */
 		priv->video_standard = DK_SECAM_A2DK1;
 		goto tune_channel;
 	}
 
-	if(params->std & V4L2_STD_SECAM_L) {
+	if (params->std & V4L2_STD_SECAM_L) {
 		priv->video_standard = L_SECAM_NICAM;
 		goto tune_channel;
 	}
 
-	if(params->std & V4L2_STD_SECAM_LC) {
+	if (params->std & V4L2_STD_SECAM_LC) {
 		priv->video_standard = LC_SECAM_NICAM;
 		goto tune_channel;
 	}
@@ -791,7 +794,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
 tune_channel:
 	ret = xc_SetSignalSource(priv, priv->rf_mode);
 	if (ret != XC_RESULT_SUCCESS) {
-	printk(KERN_ERR
+		printk(KERN_ERR
 			"xc5000: xc_SetSignalSource(%d) failed\n",
 			priv->rf_mode);
 		return -EREMOTEIO;
@@ -863,7 +866,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
 	 * I2C transactions until calibration is complete.  This way we
 	 * don't have to rely on clock stretching working.
 	 */
-	xc_wait( 100 );
+	xc_wait(100);
 
 	/* Default to "CABLE" mode */
 	ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
@@ -885,15 +888,13 @@ static int xc5000_sleep(struct dvb_frontend *fe)
 	 */
 
 	ret = xc_shutdown(priv);
-	if(ret != XC_RESULT_SUCCESS) {
+	if (ret != XC_RESULT_SUCCESS) {
 		printk(KERN_ERR
 			"xc5000: %s() unable to shutdown tuner\n",
 			__func__);
 		return -EREMOTEIO;
-	}
-	else {
+	} else
 		return XC_RESULT_SUCCESS;
-	}
 }
 
 static int xc5000_init(struct dvb_frontend *fe)
@@ -989,7 +990,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
 	if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0)
 		goto fail;
 
-	switch(id) {
+	switch (id) {
 	case XC_PRODUCT_ID_FW_LOADED:
 		printk(KERN_INFO
 			"xc5000: Successfully identified at address 0x%02x\n",

+ 4 - 4
drivers/media/common/tuners/xc5000.h

@@ -45,17 +45,17 @@ struct xc5000_config {
 
 #if defined(CONFIG_MEDIA_TUNER_XC5000) || \
     (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
-extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
+extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
 					  struct i2c_adapter *i2c,
 					  struct xc5000_config *cfg);
 #else
-static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
+static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
 						 struct i2c_adapter *i2c,
 						 struct xc5000_config *cfg)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
-#endif // CONFIG_MEDIA_TUNER_XC5000
+#endif
 
-#endif // __XC5000_H__
+#endif

+ 12 - 0
drivers/media/dvb/dm1105/dm1105.c

@@ -595,6 +595,18 @@ static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb)
 	dm1105dvb_dma_unmap(dm1105dvb);
 }
 
+static struct stv0299_config sharp_z0194a_config = {
+	.demod_address = 0x68,
+	.inittab = sharp_z0194a_inittab,
+	.mclk = 88000000UL,
+	.invert = 1,
+	.skip_reinit = 0,
+	.lock_output = STV0299_LOCKOUTPUT_1,
+	.volt13_op0_op1 = STV0299_VOLT13_OP1,
+	.min_delay_ms = 100,
+	.set_symbol_rate = sharp_z0194a_set_symbol_rate,
+};
+
 static struct stv0288_config earda_config = {
 	.demod_address = 0x68,
 	.min_delay_ms = 100,

+ 85 - 49
drivers/media/dvb/dvb-core/dvb_frontend.c

@@ -47,6 +47,7 @@ static int dvb_shutdown_timeout;
 static int dvb_force_auto_inversion;
 static int dvb_override_tune_delay;
 static int dvb_powerdown_on_sleep = 1;
+static int dvb_mfe_wait_time = 5;
 
 module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
 MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
@@ -58,6 +59,8 @@ module_param(dvb_override_tune_delay, int, 0644);
 MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
 module_param(dvb_powerdown_on_sleep, int, 0644);
 MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)");
+module_param(dvb_mfe_wait_time, int, 0644);
+MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)");
 
 #define dprintk if (dvb_frontend_debug) printk
 
@@ -212,8 +215,9 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
 
 static void dvb_frontend_init(struct dvb_frontend *fe)
 {
-	dprintk ("DVB: initialising frontend %i (%s)...\n",
+	dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n",
 		 fe->dvb->num,
+		 fe->id,
 		 fe->ops.info.name);
 
 	if (fe->ops.init)
@@ -686,7 +690,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
 	mb();
 
 	fe_thread = kthread_run(dvb_frontend_thread, fe,
-		"kdvb-fe-%i", fe->dvb->num);
+		"kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id);
 	if (IS_ERR(fe_thread)) {
 		ret = PTR_ERR(fe_thread);
 		printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
@@ -710,8 +714,8 @@ static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe,
 		*freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);
 
 	if (*freq_min == 0 || *freq_max == 0)
-		printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n",
-		       fe->dvb->num);
+		printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
+		       fe->dvb->num,fe->id);
 }
 
 static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
@@ -724,8 +728,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
 	dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max);
 	if ((freq_min && parms->frequency < freq_min) ||
 	    (freq_max && parms->frequency > freq_max)) {
-		printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n",
-		       fe->dvb->num, parms->frequency, freq_min, freq_max);
+		printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
+		       fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max);
 		return -EINVAL;
 	}
 
@@ -735,8 +739,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
 		     parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
 		    (fe->ops.info.symbol_rate_max &&
 		     parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) {
-			printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
-			       fe->dvb->num, parms->u.qpsk.symbol_rate,
+			printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
+			       fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate,
 			       fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
 			return -EINVAL;
 		}
@@ -746,8 +750,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
 		     parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) ||
 		    (fe->ops.info.symbol_rate_max &&
 		     parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) {
-			printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
-			       fe->dvb->num, parms->u.qam.symbol_rate,
+			printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
+			       fe->dvb->num, fe->id, parms->u.qam.symbol_rate,
 			       fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
 			return -EINVAL;
 		}
@@ -899,30 +903,30 @@ void dtv_property_dump(struct dtv_property *tvp)
 	int i;
 
 	if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
-		printk("%s: tvp.cmd = 0x%08x (undefined/unknown/invalid)\n",
+		printk(KERN_WARNING "%s: tvp.cmd = 0x%08x undefined\n",
 			__func__, tvp->cmd);
 		return;
 	}
 
-	printk("%s() tvp.cmd    = 0x%08x (%s)\n"
-		,__FUNCTION__
+	dprintk("%s() tvp.cmd    = 0x%08x (%s)\n"
+		,__func__
 		,tvp->cmd
 		,dtv_cmds[ tvp->cmd ].name);
 
 	if(dtv_cmds[ tvp->cmd ].buffer) {
 
-		printk("%s() tvp.u.buffer.len = 0x%02x\n"
-			,__FUNCTION__
+		dprintk("%s() tvp.u.buffer.len = 0x%02x\n"
+			,__func__
 			,tvp->u.buffer.len);
 
 		for(i = 0; i < tvp->u.buffer.len; i++)
-			printk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n"
-				,__FUNCTION__
+			dprintk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n"
+				,__func__
 				,i
 				,tvp->u.buffer.data[i]);
 
 	} else
-		printk("%s() tvp.u.data = 0x%08x\n", __FUNCTION__, tvp->u.data);
+		dprintk("%s() tvp.u.data = 0x%08x\n", __func__, tvp->u.data);
 }
 
 int is_legacy_delivery_system(fe_delivery_system_t s)
@@ -942,8 +946,6 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame
 {
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 
-	printk("%s()\n", __FUNCTION__);
-
 	c->frequency = p->frequency;
 	c->inversion = p->inversion;
 
@@ -998,27 +1000,25 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	struct dvb_frontend_parameters *p = &fepriv->parameters;
 
-	printk("%s()\n", __FUNCTION__);
-
 	p->frequency = c->frequency;
 	p->inversion = c->inversion;
 
 	switch (fe->ops.info.type) {
 	case FE_QPSK:
-		printk("%s() Preparing QPSK req\n", __FUNCTION__);
+		dprintk("%s() Preparing QPSK req\n", __func__);
 		p->u.qpsk.symbol_rate = c->symbol_rate;
 		p->u.qpsk.fec_inner = c->fec_inner;
 		c->delivery_system = SYS_DVBS;
 		break;
 	case FE_QAM:
-		printk("%s() Preparing QAM req\n", __FUNCTION__);
+		dprintk("%s() Preparing QAM req\n", __func__);
 		p->u.qam.symbol_rate = c->symbol_rate;
 		p->u.qam.fec_inner = c->fec_inner;
 		p->u.qam.modulation = c->modulation;
 		c->delivery_system = SYS_DVBC_ANNEX_AC;
 		break;
 	case FE_OFDM:
-		printk("%s() Preparing OFDM req\n", __FUNCTION__);
+		dprintk("%s() Preparing OFDM req\n", __func__);
 		if (c->bandwidth_hz == 6000000)
 			p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
 		else if (c->bandwidth_hz == 7000000)
@@ -1036,7 +1036,7 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
 		c->delivery_system = SYS_DVBT;
 		break;
 	case FE_ATSC:
-		printk("%s() Preparing VSB req\n", __FUNCTION__);
+		dprintk("%s() Preparing VSB req\n", __func__);
 		p->u.vsb.modulation = c->modulation;
 		if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
 			c->delivery_system = SYS_ATSC;
@@ -1055,14 +1055,13 @@ void dtv_property_adv_params_sync(struct dvb_frontend *fe)
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	struct dvb_frontend_parameters *p = &fepriv->parameters;
 
-	printk("%s()\n", __FUNCTION__);
-
 	p->frequency = c->frequency;
 	p->inversion = c->inversion;
 
 	switch(c->modulation) {
 	case PSK_8:
 	case APSK_16:
+	case APSK_32:
 	case QPSK:
 		p->u.qpsk.symbol_rate = c->symbol_rate;
 		p->u.qpsk.fec_inner = c->fec_inner;
@@ -1089,19 +1088,17 @@ void dtv_property_cache_submit(struct dvb_frontend *fe)
 {
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 
-	printk("%s()\n", __FUNCTION__);
-
 	/* For legacy delivery systems we don't need the delivery_system to
 	 * be specified, but we populate the older structures from the cache
 	 * so we can call set_frontend on older drivers.
 	 */
 	if(is_legacy_delivery_system(c->delivery_system)) {
 
-		printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation);
+		dprintk("%s() legacy, modulation = %d\n", __func__, c->modulation);
 		dtv_property_legacy_params_sync(fe);
 
 	} else {
-		printk("%s() adv, modulation = %d\n", __FUNCTION__, c->modulation);
+		dprintk("%s() adv, modulation = %d\n", __func__, c->modulation);
 
 		/* For advanced delivery systems / modulation types ...
 		 * we seed the lecacy dvb_frontend_parameters structure
@@ -1123,8 +1120,6 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp,
 {
 	int r = 0;
 
-	printk("%s()\n", __FUNCTION__);
-
 	dtv_property_dump(tvp);
 
 	/* Allow the frontend to validate incoming properties */
@@ -1198,7 +1193,6 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
 {
 	int r = 0;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
-	printk("%s()\n", __FUNCTION__);
 	dtv_property_dump(tvp);
 
 	/* Allow the frontend to validate incoming properties */
@@ -1213,7 +1207,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
 		/* Reset a cache of data specific to the frontend here. This does
 		 * not effect hardware.
 		 */
-		printk("%s() Flushing property cache\n", __FUNCTION__);
+		dprintk("%s() Flushing property cache\n", __func__);
 		memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
 		fe->dtv_property_cache.state = tvp->cmd;
 		fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
@@ -1224,7 +1218,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
 		 * ioctl.
 		 */
 		fe->dtv_property_cache.state = tvp->cmd;
-		printk("%s() Finalised property cache\n", __FUNCTION__);
+		dprintk("%s() Finalised property cache\n", __func__);
 		dtv_property_cache_submit(fe);
 
 		r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND,
@@ -1335,12 +1329,10 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
 	dprintk("%s\n", __func__);
 
 	if(cmd == FE_SET_PROPERTY) {
-		printk("%s() FE_SET_PROPERTY\n", __FUNCTION__);
-
 		tvps = (struct dtv_properties __user *)parg;
 
-		printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num);
-		printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props);
+		dprintk("%s() properties.num = %d\n", __func__, tvps->num);
+		dprintk("%s() properties.props = %p\n", __func__, tvps->props);
 
 		/* Put an arbitrary limit on the number of messages that can
 		 * be sent at once */
@@ -1364,18 +1356,16 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
 			err |= (tvp + i)->result;
 		}
 
-		if(fe->dtv_property_cache.state == DTV_TUNE) {
-			printk("%s() Property cache is full, tuning\n", __FUNCTION__);
-		}
+		if(fe->dtv_property_cache.state == DTV_TUNE)
+			dprintk("%s() Property cache is full, tuning\n", __func__);
 
 	} else
 	if(cmd == FE_GET_PROPERTY) {
-		printk("%s() FE_GET_PROPERTY\n", __FUNCTION__);
 
 		tvps = (struct dtv_properties __user *)parg;
 
-		printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num);
-		printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props);
+		dprintk("%s() properties.num = %d\n", __func__, tvps->num);
+		dprintk("%s() properties.props = %p\n", __func__, tvps->props);
 
 		/* Put an arbitrary limit on the number of messages that can
 		 * be sent at once */
@@ -1704,13 +1694,53 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
+	struct dvb_adapter *adapter = fe->dvb;
 	int ret;
 
 	dprintk ("%s\n", __func__);
 
+	if (adapter->mfe_shared) {
+		mutex_lock (&adapter->mfe_lock);
+
+		if (adapter->mfe_dvbdev == NULL)
+			adapter->mfe_dvbdev = dvbdev;
+
+		else if (adapter->mfe_dvbdev != dvbdev) {
+			struct dvb_device
+				*mfedev = adapter->mfe_dvbdev;
+			struct dvb_frontend
+				*mfe = mfedev->priv;
+			struct dvb_frontend_private
+				*mfepriv = mfe->frontend_priv;
+			int mferetry = (dvb_mfe_wait_time << 1);
+
+			mutex_unlock (&adapter->mfe_lock);
+			while (mferetry-- && (mfedev->users != -1 ||
+					mfepriv->thread != NULL)) {
+				if(msleep_interruptible(500)) {
+					if(signal_pending(current))
+						return -EINTR;
+				}
+			}
+
+			mutex_lock (&adapter->mfe_lock);
+			if(adapter->mfe_dvbdev != dvbdev) {
+				mfedev = adapter->mfe_dvbdev;
+				mfe = mfedev->priv;
+				mfepriv = mfe->frontend_priv;
+				if (mfedev->users != -1 ||
+						mfepriv->thread != NULL) {
+					mutex_unlock (&adapter->mfe_lock);
+					return -EBUSY;
+				}
+				adapter->mfe_dvbdev = dvbdev;
+			}
+		}
+	}
+
 	if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
 		if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
-			return ret;
+			goto err0;
 	}
 
 	if ((ret = dvb_generic_open (inode, file)) < 0)
@@ -1730,6 +1760,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 		fepriv->events.eventr = fepriv->events.eventw = 0;
 	}
 
+	if (adapter->mfe_shared)
+		mutex_unlock (&adapter->mfe_lock);
 	return ret;
 
 err2:
@@ -1737,6 +1769,9 @@ err2:
 err1:
 	if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
 		fe->ops.ts_bus_ctrl(fe, 0);
+err0:
+	if (adapter->mfe_shared)
+		mutex_unlock (&adapter->mfe_lock);
 	return ret;
 }
 
@@ -1806,8 +1841,9 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
 	fe->dvb = dvb;
 	fepriv->inversion = INVERSION_OFF;
 
-	printk ("DVB: registering frontend %i (%s)...\n",
+	printk ("DVB: registering adapter %i frontend %i (%s)...\n",
 		fe->dvb->num,
+		fe->id,
 		fe->ops.info.name);
 
 	dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,

+ 1 - 0
drivers/media/dvb/dvb-core/dvb_frontend.h

@@ -222,6 +222,7 @@ struct dvb_frontend {
 	struct dtv_frontend_properties dtv_property_cache;
 #define DVB_FRONTEND_COMPONENT_TUNER 0
 	int (*callback)(void *adapter_priv, int component, int cmd, int arg);
+	int id;
 };
 
 extern int dvb_register_frontend(struct dvb_adapter *dvb,

+ 3 - 0
drivers/media/dvb/dvb-core/dvbdev.c

@@ -326,6 +326,9 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
 	adap->name = name;
 	adap->module = module;
 	adap->device = device;
+	adap->mfe_shared = 0;
+	adap->mfe_dvbdev = NULL;
+	mutex_init (&adap->mfe_lock);
 
 	list_add_tail (&adap->list_head, &dvb_adapter_list);
 

+ 4 - 0
drivers/media/dvb/dvb-core/dvbdev.h

@@ -62,6 +62,10 @@ struct dvb_adapter {
 	struct device *device;
 
 	struct module *module;
+
+	int mfe_shared;			/* indicates mutually exclusive frontends */
+	struct dvb_device *mfe_dvbdev;	/* frontend device in use */
+	struct mutex mfe_lock;		/* access lock for thread creation */
 };
 
 

+ 12 - 0
drivers/media/dvb/dvb-usb/dw2102.c

@@ -422,6 +422,18 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 	return 0;
 }
 
+static struct stv0299_config sharp_z0194a_config = {
+	.demod_address = 0x68,
+	.inittab = sharp_z0194a_inittab,
+	.mclk = 88000000UL,
+	.invert = 1,
+	.skip_reinit = 0,
+	.lock_output = STV0299_LOCKOUTPUT_1,
+	.volt13_op0_op1 = STV0299_VOLT13_OP1,
+	.min_delay_ms = 100,
+	.set_symbol_rate = sharp_z0194a_set_symbol_rate,
+};
+
 static struct cx24116_config dw2104_config = {
 	.demod_address = 0x55,
 	.mpg_clk_pos_pol = 0x01,

+ 306 - 200
drivers/media/dvb/frontends/cx22702.c

@@ -34,13 +34,12 @@
 #include "dvb_frontend.h"
 #include "cx22702.h"
 
-
 struct cx22702_state {
 
-	struct i2c_adapter* i2c;
+	struct i2c_adapter *i2c;
 
 	/* configuration settings */
-	const struct cx22702_config* config;
+	const struct cx22702_config *config;
 
 	struct dvb_frontend frontend;
 
@@ -49,10 +48,13 @@ struct cx22702_state {
 };
 
 static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
 #define dprintk	if (debug) printk
 
 /* Register values to initialise the demod */
-static u8 init_tab [] = {
+static u8 init_tab[] = {
 	0x00, 0x00, /* Stop aquisition */
 	0x0B, 0x06,
 	0x09, 0x01,
@@ -80,65 +82,67 @@ static u8 init_tab [] = {
 	0xfd, 0x00,
 };
 
-static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data)
+static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data)
 {
 	int ret;
-	u8 buf [] = { reg, data };
-	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+	u8 buf[] = { reg, data };
+	struct i2c_msg msg = {
+		.addr = state->config->demod_address, .flags = 0,
+			.buf = buf, .len = 2 };
 
 	ret = i2c_transfer(state->i2c, &msg, 1);
 
 	if (ret != 1)
-		printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
+		printk(KERN_ERR
+			"%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
 			__func__, reg, data, ret);
 
 	return (ret != 1) ? -1 : 0;
 }
 
-static u8 cx22702_readreg (struct cx22702_state* state, u8 reg)
+static u8 cx22702_readreg(struct cx22702_state *state, u8 reg)
 {
 	int ret;
-	u8 b0 [] = { reg };
-	u8 b1 [] = { 0 };
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
 
-	struct i2c_msg msg [] = {
-		{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-		{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+	struct i2c_msg msg[] = {
+		{ .addr = state->config->demod_address, .flags = 0,
+			.buf = b0, .len = 1 },
+		{ .addr = state->config->demod_address, .flags = I2C_M_RD,
+			.buf = b1, .len = 1 } };
 
 	ret = i2c_transfer(state->i2c, msg, 2);
 
 	if (ret != 2)
-		printk("%s: readreg error (ret == %i)\n", __func__, ret);
+		printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+			__func__, ret);
 
 	return b1[0];
 }
 
-static int cx22702_set_inversion (struct cx22702_state *state, int inversion)
+static int cx22702_set_inversion(struct cx22702_state *state, int inversion)
 {
 	u8 val;
 
 	switch (inversion) {
-
-		case INVERSION_AUTO:
-			return -EOPNOTSUPP;
-
-		case INVERSION_ON:
-			val = cx22702_readreg (state, 0x0C);
-			return cx22702_writereg (state, 0x0C, val | 0x01);
-
-		case INVERSION_OFF:
-			val = cx22702_readreg (state, 0x0C);
-			return cx22702_writereg (state, 0x0C, val & 0xfe);
-
-		default:
-			return -EINVAL;
-
+	case INVERSION_AUTO:
+		return -EOPNOTSUPP;
+	case INVERSION_ON:
+		val = cx22702_readreg(state, 0x0C);
+		return cx22702_writereg(state, 0x0C, val | 0x01);
+	case INVERSION_OFF:
+		val = cx22702_readreg(state, 0x0C);
+		return cx22702_writereg(state, 0x0C, val & 0xfe);
+	default:
+		return -EINVAL;
 	}
 
 }
 
 /* Retrieve the demod settings */
-static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_parameters *p)
+static int cx22702_get_tps(struct cx22702_state *state,
+	struct dvb_ofdm_parameters *p)
 {
 	u8 val;
 
@@ -146,180 +150,281 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet
 	if (!(cx22702_readreg(state, 0x0A) & 0x20))
 		return -EAGAIN;
 
-	val = cx22702_readreg (state, 0x01);
-	switch( (val&0x18)>>3) {
-		case 0: p->constellation =   QPSK; break;
-		case 1: p->constellation = QAM_16; break;
-		case 2: p->constellation = QAM_64; break;
+	val = cx22702_readreg(state, 0x01);
+	switch ((val & 0x18) >> 3) {
+	case 0:
+		p->constellation = QPSK;
+		break;
+	case 1:
+		p->constellation = QAM_16;
+		break;
+	case 2:
+		p->constellation = QAM_64;
+		break;
 	}
-	switch( val&0x07 ) {
-		case 0: p->hierarchy_information = HIERARCHY_NONE; break;
-		case 1: p->hierarchy_information =    HIERARCHY_1; break;
-		case 2: p->hierarchy_information =    HIERARCHY_2; break;
-		case 3: p->hierarchy_information =    HIERARCHY_4; break;
+	switch (val & 0x07) {
+	case 0:
+		p->hierarchy_information = HIERARCHY_NONE;
+		break;
+	case 1:
+		p->hierarchy_information = HIERARCHY_1;
+		break;
+	case 2:
+		p->hierarchy_information = HIERARCHY_2;
+		break;
+	case 3:
+		p->hierarchy_information = HIERARCHY_4;
+		break;
 	}
 
 
-	val = cx22702_readreg (state, 0x02);
-	switch( (val&0x38)>>3 ) {
-		case 0: p->code_rate_HP = FEC_1_2; break;
-		case 1: p->code_rate_HP = FEC_2_3; break;
-		case 2: p->code_rate_HP = FEC_3_4; break;
-		case 3: p->code_rate_HP = FEC_5_6; break;
-		case 4: p->code_rate_HP = FEC_7_8; break;
+	val = cx22702_readreg(state, 0x02);
+	switch ((val & 0x38) >> 3) {
+	case 0:
+		p->code_rate_HP = FEC_1_2;
+		break;
+	case 1:
+		p->code_rate_HP = FEC_2_3;
+		break;
+	case 2:
+		p->code_rate_HP = FEC_3_4;
+		break;
+	case 3:
+		p->code_rate_HP = FEC_5_6;
+		break;
+	case 4:
+		p->code_rate_HP = FEC_7_8;
+		break;
 	}
-	switch( val&0x07 ) {
-		case 0: p->code_rate_LP = FEC_1_2; break;
-		case 1: p->code_rate_LP = FEC_2_3; break;
-		case 2: p->code_rate_LP = FEC_3_4; break;
-		case 3: p->code_rate_LP = FEC_5_6; break;
-		case 4: p->code_rate_LP = FEC_7_8; break;
+	switch (val & 0x07) {
+	case 0:
+		p->code_rate_LP = FEC_1_2;
+		break;
+	case 1:
+		p->code_rate_LP = FEC_2_3;
+		break;
+	case 2:
+		p->code_rate_LP = FEC_3_4;
+		break;
+	case 3:
+		p->code_rate_LP = FEC_5_6;
+		break;
+	case 4:
+		p->code_rate_LP = FEC_7_8;
+		break;
 	}
 
-
-	val = cx22702_readreg (state, 0x03);
-	switch( (val&0x0c)>>2 ) {
-		case 0: p->guard_interval = GUARD_INTERVAL_1_32; break;
-		case 1: p->guard_interval = GUARD_INTERVAL_1_16; break;
-		case 2: p->guard_interval =  GUARD_INTERVAL_1_8; break;
-		case 3: p->guard_interval =  GUARD_INTERVAL_1_4; break;
+	val = cx22702_readreg(state, 0x03);
+	switch ((val & 0x0c) >> 2) {
+	case 0:
+		p->guard_interval = GUARD_INTERVAL_1_32;
+		break;
+	case 1:
+		p->guard_interval = GUARD_INTERVAL_1_16;
+		break;
+	case 2:
+		p->guard_interval = GUARD_INTERVAL_1_8;
+		break;
+	case 3:
+		p->guard_interval = GUARD_INTERVAL_1_4;
+		break;
 	}
-	switch( val&0x03 ) {
-		case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break;
-		case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break;
+	switch (val & 0x03) {
+	case 0:
+		p->transmission_mode = TRANSMISSION_MODE_2K;
+		break;
+	case 1:
+		p->transmission_mode = TRANSMISSION_MODE_8K;
+		break;
 	}
 
 	return 0;
 }
 
-static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
-	struct cx22702_state* state = fe->demodulator_priv;
-	dprintk ("%s(%d)\n", __func__, enable);
+	struct cx22702_state *state = fe->demodulator_priv;
+	dprintk("%s(%d)\n", __func__, enable);
 	if (enable)
-		return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe);
+		return cx22702_writereg(state, 0x0D,
+			cx22702_readreg(state, 0x0D) & 0xfe);
 	else
-		return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1);
+		return cx22702_writereg(state, 0x0D,
+			cx22702_readreg(state, 0x0D) | 1);
 }
 
 /* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx22702_set_tps(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
 {
 	u8 val;
-	struct cx22702_state* state = fe->demodulator_priv;
+	struct cx22702_state *state = fe->demodulator_priv;
 
 	if (fe->ops.tuner_ops.set_params) {
 		fe->ops.tuner_ops.set_params(fe, p);
-		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
 	}
 
 	/* set inversion */
-	cx22702_set_inversion (state, p->inversion);
+	cx22702_set_inversion(state, p->inversion);
 
 	/* set bandwidth */
-	switch(p->u.ofdm.bandwidth) {
+	switch (p->u.ofdm.bandwidth) {
 	case BANDWIDTH_6_MHZ:
-		cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20 );
+		cx22702_writereg(state, 0x0C,
+			(cx22702_readreg(state, 0x0C) & 0xcf) | 0x20);
 		break;
 	case BANDWIDTH_7_MHZ:
-		cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10 );
+		cx22702_writereg(state, 0x0C,
+			(cx22702_readreg(state, 0x0C) & 0xcf) | 0x10);
 		break;
 	case BANDWIDTH_8_MHZ:
-		cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf );
+		cx22702_writereg(state, 0x0C,
+			cx22702_readreg(state, 0x0C) & 0xcf);
 		break;
 	default:
-		dprintk ("%s: invalid bandwidth\n",__func__);
+		dprintk("%s: invalid bandwidth\n", __func__);
 		return -EINVAL;
 	}
 
-
-	p->u.ofdm.code_rate_LP = FEC_AUTO; //temp hack as manual not working
+	p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */
 
 	/* use auto configuration? */
-	if((p->u.ofdm.hierarchy_information==HIERARCHY_AUTO) ||
-	   (p->u.ofdm.constellation==QAM_AUTO) ||
-	   (p->u.ofdm.code_rate_HP==FEC_AUTO) ||
-	   (p->u.ofdm.code_rate_LP==FEC_AUTO) ||
-	   (p->u.ofdm.guard_interval==GUARD_INTERVAL_AUTO) ||
-	   (p->u.ofdm.transmission_mode==TRANSMISSION_MODE_AUTO) ) {
+	if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) ||
+	   (p->u.ofdm.constellation == QAM_AUTO) ||
+	   (p->u.ofdm.code_rate_HP == FEC_AUTO) ||
+	   (p->u.ofdm.code_rate_LP == FEC_AUTO) ||
+	   (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) ||
+	   (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) {
 
 		/* TPS Source - use hardware driven values */
 		cx22702_writereg(state, 0x06, 0x10);
 		cx22702_writereg(state, 0x07, 0x9);
 		cx22702_writereg(state, 0x08, 0xC1);
-		cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
-		cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
+		cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B)
+			& 0xfc);
+		cx22702_writereg(state, 0x0C,
+			(cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
 		cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
-		dprintk("%s: Autodetecting\n",__func__);
+		dprintk("%s: Autodetecting\n", __func__);
 		return 0;
 	}
 
 	/* manually programmed values */
-	val=0;
-	switch(p->u.ofdm.constellation) {
-		case   QPSK: val = (val&0xe7); break;
-		case QAM_16: val = (val&0xe7)|0x08; break;
-		case QAM_64: val = (val&0xe7)|0x10; break;
-		default:
-			dprintk ("%s: invalid constellation\n",__func__);
-			return -EINVAL;
+	val = 0;
+	switch (p->u.ofdm.constellation) {
+	case QPSK:
+		val = (val & 0xe7);
+		break;
+	case QAM_16:
+		val = (val & 0xe7) | 0x08;
+		break;
+	case QAM_64:
+		val = (val & 0xe7) | 0x10;
+		break;
+	default:
+		dprintk("%s: invalid constellation\n", __func__);
+		return -EINVAL;
 	}
-	switch(p->u.ofdm.hierarchy_information) {
-		case HIERARCHY_NONE: val = (val&0xf8); break;
-		case    HIERARCHY_1: val = (val&0xf8)|1; break;
-		case    HIERARCHY_2: val = (val&0xf8)|2; break;
-		case    HIERARCHY_4: val = (val&0xf8)|3; break;
-		default:
-			dprintk ("%s: invalid hierarchy\n",__func__);
-			return -EINVAL;
+	switch (p->u.ofdm.hierarchy_information) {
+	case HIERARCHY_NONE:
+		val = (val & 0xf8);
+		break;
+	case HIERARCHY_1:
+		val = (val & 0xf8) | 1;
+		break;
+	case HIERARCHY_2:
+		val = (val & 0xf8) | 2;
+		break;
+	case HIERARCHY_4:
+		val = (val & 0xf8) | 3;
+		break;
+	default:
+		dprintk("%s: invalid hierarchy\n", __func__);
+		return -EINVAL;
 	}
-	cx22702_writereg (state, 0x06, val);
-
-	val=0;
-	switch(p->u.ofdm.code_rate_HP) {
-		case FEC_NONE:
-		case FEC_1_2: val = (val&0xc7); break;
-		case FEC_2_3: val = (val&0xc7)|0x08; break;
-		case FEC_3_4: val = (val&0xc7)|0x10; break;
-		case FEC_5_6: val = (val&0xc7)|0x18; break;
-		case FEC_7_8: val = (val&0xc7)|0x20; break;
-		default:
-			dprintk ("%s: invalid code_rate_HP\n",__func__);
-			return -EINVAL;
+	cx22702_writereg(state, 0x06, val);
+
+	val = 0;
+	switch (p->u.ofdm.code_rate_HP) {
+	case FEC_NONE:
+	case FEC_1_2:
+		val = (val & 0xc7);
+		break;
+	case FEC_2_3:
+		val = (val & 0xc7) | 0x08;
+		break;
+	case FEC_3_4:
+		val = (val & 0xc7) | 0x10;
+		break;
+	case FEC_5_6:
+		val = (val & 0xc7) | 0x18;
+		break;
+	case FEC_7_8:
+		val = (val & 0xc7) | 0x20;
+		break;
+	default:
+		dprintk("%s: invalid code_rate_HP\n", __func__);
+		return -EINVAL;
 	}
-	switch(p->u.ofdm.code_rate_LP) {
-		case FEC_NONE:
-		case FEC_1_2: val = (val&0xf8); break;
-		case FEC_2_3: val = (val&0xf8)|1; break;
-		case FEC_3_4: val = (val&0xf8)|2; break;
-		case FEC_5_6: val = (val&0xf8)|3; break;
-		case FEC_7_8: val = (val&0xf8)|4; break;
-		default:
-			dprintk ("%s: invalid code_rate_LP\n",__func__);
-			return -EINVAL;
+	switch (p->u.ofdm.code_rate_LP) {
+	case FEC_NONE:
+	case FEC_1_2:
+		val = (val & 0xf8);
+		break;
+	case FEC_2_3:
+		val = (val & 0xf8) | 1;
+		break;
+	case FEC_3_4:
+		val = (val & 0xf8) | 2;
+		break;
+	case FEC_5_6:
+		val = (val & 0xf8) | 3;
+		break;
+	case FEC_7_8:
+		val = (val & 0xf8) | 4;
+		break;
+	default:
+		dprintk("%s: invalid code_rate_LP\n", __func__);
+		return -EINVAL;
 	}
-	cx22702_writereg (state, 0x07, val);
-
-	val=0;
-	switch(p->u.ofdm.guard_interval) {
-		case GUARD_INTERVAL_1_32: val = (val&0xf3); break;
-		case GUARD_INTERVAL_1_16: val = (val&0xf3)|0x04; break;
-		case  GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break;
-		case  GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break;
-		default:
-			dprintk ("%s: invalid guard_interval\n",__func__);
-			return -EINVAL;
+	cx22702_writereg(state, 0x07, val);
+
+	val = 0;
+	switch (p->u.ofdm.guard_interval) {
+	case GUARD_INTERVAL_1_32:
+		val = (val & 0xf3);
+		break;
+	case GUARD_INTERVAL_1_16:
+		val = (val & 0xf3) | 0x04;
+		break;
+	case GUARD_INTERVAL_1_8:
+		val = (val & 0xf3) | 0x08;
+		break;
+	case GUARD_INTERVAL_1_4:
+		val = (val & 0xf3) | 0x0c;
+		break;
+	default:
+		dprintk("%s: invalid guard_interval\n", __func__);
+		return -EINVAL;
 	}
-	switch(p->u.ofdm.transmission_mode) {
-		case TRANSMISSION_MODE_2K: val = (val&0xfc); break;
-		case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break;
-		default:
-			dprintk ("%s: invalid transmission_mode\n",__func__);
-			return -EINVAL;
+	switch (p->u.ofdm.transmission_mode) {
+	case TRANSMISSION_MODE_2K:
+		val = (val & 0xfc);
+		break;
+	case TRANSMISSION_MODE_8K:
+		val = (val & 0xfc) | 1;
+		break;
+	default:
+		dprintk("%s: invalid transmission_mode\n", __func__);
+		return -EINVAL;
 	}
 	cx22702_writereg(state, 0x08, val);
-	cx22702_writereg(state, 0x0B, (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02 );
-	cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
+	cx22702_writereg(state, 0x0B,
+		(cx22702_readreg(state, 0x0B) & 0xfc) | 0x02);
+	cx22702_writereg(state, 0x0C,
+		(cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
 
 	/* Begin channel aquisition */
 	cx22702_writereg(state, 0x00, 0x01);
@@ -329,109 +434,111 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
 
 /* Reset the demod hardware and reset all of the configuration registers
    to a default state. */
-static int cx22702_init (struct dvb_frontend* fe)
+static int cx22702_init(struct dvb_frontend *fe)
 {
 	int i;
-	struct cx22702_state* state = fe->demodulator_priv;
+	struct cx22702_state *state = fe->demodulator_priv;
 
-	cx22702_writereg (state, 0x00, 0x02);
+	cx22702_writereg(state, 0x00, 0x02);
 
 	msleep(10);
 
-	for (i=0; i<sizeof(init_tab); i+=2)
-		cx22702_writereg (state, init_tab[i], init_tab[i+1]);
+	for (i = 0; i < ARRAY_SIZE(init_tab); i += 2)
+		cx22702_writereg(state, init_tab[i], init_tab[i + 1]);
 
-	cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
+	cx22702_writereg(state, 0xf8, (state->config->output_mode << 1)
+		& 0x02);
 
 	cx22702_i2c_gate_ctrl(fe, 0);
 
 	return 0;
 }
 
-static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status)
 {
-	struct cx22702_state* state = fe->demodulator_priv;
+	struct cx22702_state *state = fe->demodulator_priv;
 	u8 reg0A;
 	u8 reg23;
 
 	*status = 0;
 
-	reg0A = cx22702_readreg (state, 0x0A);
-	reg23 = cx22702_readreg (state, 0x23);
+	reg0A = cx22702_readreg(state, 0x0A);
+	reg23 = cx22702_readreg(state, 0x23);
 
-	dprintk ("%s: status demod=0x%02x agc=0x%02x\n"
-		,__func__,reg0A,reg23);
+	dprintk("%s: status demod=0x%02x agc=0x%02x\n"
+		, __func__, reg0A, reg23);
 
-	if(reg0A & 0x10) {
+	if (reg0A & 0x10) {
 		*status |= FE_HAS_LOCK;
 		*status |= FE_HAS_VITERBI;
 		*status |= FE_HAS_SYNC;
 	}
 
-	if(reg0A & 0x20)
+	if (reg0A & 0x20)
 		*status |= FE_HAS_CARRIER;
 
-	if(reg23 < 0xf0)
+	if (reg23 < 0xf0)
 		*status |= FE_HAS_SIGNAL;
 
 	return 0;
 }
 
-static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber)
+static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
-	struct cx22702_state* state = fe->demodulator_priv;
+	struct cx22702_state *state = fe->demodulator_priv;
 
-	if(cx22702_readreg (state, 0xE4) & 0x02) {
+	if (cx22702_readreg(state, 0xE4) & 0x02) {
 		/* Realtime statistics */
-		*ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
-			| (cx22702_readreg (state, 0xDF)&0x7F);
+		*ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
+			| (cx22702_readreg(state, 0xDF) & 0x7F);
 	} else {
 		/* Averagtine statistics */
-		*ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
-			| cx22702_readreg (state, 0xDF);
+		*ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
+			| cx22702_readreg(state, 0xDF);
 	}
 
 	return 0;
 }
 
-static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+static int cx22702_read_signal_strength(struct dvb_frontend *fe,
+	u16 *signal_strength)
 {
-	struct cx22702_state* state = fe->demodulator_priv;
+	struct cx22702_state *state = fe->demodulator_priv;
 
 	u16 rs_ber = 0;
-	rs_ber = cx22702_readreg (state, 0x23);
+	rs_ber = cx22702_readreg(state, 0x23);
 	*signal_strength = (rs_ber << 8) | rs_ber;
 
 	return 0;
 }
 
-static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr)
+static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
-	struct cx22702_state* state = fe->demodulator_priv;
+	struct cx22702_state *state = fe->demodulator_priv;
 
-	u16 rs_ber=0;
-	if(cx22702_readreg (state, 0xE4) & 0x02) {
+	u16 rs_ber = 0;
+	if (cx22702_readreg(state, 0xE4) & 0x02) {
 		/* Realtime statistics */
-		rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
-			| (cx22702_readreg (state, 0xDF)& 0x7F);
+		rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
+			| (cx22702_readreg(state, 0xDF) & 0x7F);
 	} else {
 		/* Averagine statistics */
-		rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 8
-			| cx22702_readreg (state, 0xDF);
+		rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8
+			| cx22702_readreg(state, 0xDF);
 	}
 	*snr = ~rs_ber;
 
 	return 0;
 }
 
-static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
-	struct cx22702_state* state = fe->demodulator_priv;
+	struct cx22702_state *state = fe->demodulator_priv;
 
 	u8 _ucblocks;
 
 	/* RS Uncorrectable Packet Count then reset */
-	_ucblocks = cx22702_readreg (state, 0xE3);
+	_ucblocks = cx22702_readreg(state, 0xE3);
 	if (state->prevUCBlocks < _ucblocks)
 		*ucblocks = (_ucblocks - state->prevUCBlocks);
 	else
@@ -441,34 +548,36 @@ static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 	return 0;
 }
 
-static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx22702_get_frontend(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
 {
-	struct cx22702_state* state = fe->demodulator_priv;
+	struct cx22702_state *state = fe->demodulator_priv;
 
-	u8 reg0C = cx22702_readreg (state, 0x0C);
+	u8 reg0C = cx22702_readreg(state, 0x0C);
 
 	p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF;
-	return cx22702_get_tps (state, &p->u.ofdm);
+	return cx22702_get_tps(state, &p->u.ofdm);
 }
 
-static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+static int cx22702_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *tune)
 {
 	tune->min_delay_ms = 1000;
 	return 0;
 }
 
-static void cx22702_release(struct dvb_frontend* fe)
+static void cx22702_release(struct dvb_frontend *fe)
 {
-	struct cx22702_state* state = fe->demodulator_priv;
+	struct cx22702_state *state = fe->demodulator_priv;
 	kfree(state);
 }
 
 static struct dvb_frontend_ops cx22702_ops;
 
-struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
-				    struct i2c_adapter* i2c)
+struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
+	struct i2c_adapter *i2c)
 {
-	struct cx22702_state* state = NULL;
+	struct cx22702_state *state = NULL;
 
 	/* allocate memory for the internal state */
 	state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
@@ -485,7 +594,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
 		goto error;
 
 	/* create dvb_frontend */
-	memcpy(&state->frontend.ops, &cx22702_ops, sizeof(struct dvb_frontend_ops));
+	memcpy(&state->frontend.ops, &cx22702_ops,
+		sizeof(struct dvb_frontend_ops));
 	state->frontend.demodulator_priv = state;
 	return &state->frontend;
 
@@ -493,6 +603,7 @@ error:
 	kfree(state);
 	return NULL;
 }
+EXPORT_SYMBOL(cx22702_attach);
 
 static struct dvb_frontend_ops cx22702_ops = {
 
@@ -525,11 +636,6 @@ static struct dvb_frontend_ops cx22702_ops = {
 	.read_ucblocks = cx22702_read_ucblocks,
 };
 
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
 MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver");
 MODULE_AUTHOR("Steven Toth");
 MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(cx22702_attach);

+ 11 - 9
drivers/media/dvb/frontends/cx22702.h

@@ -30,8 +30,7 @@
 
 #include <linux/dvb/frontend.h>
 
-struct cx22702_config
-{
+struct cx22702_config {
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
@@ -41,16 +40,19 @@ struct cx22702_config
 	u8 output_mode;
 };
 
-#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE))
-extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
-					   struct i2c_adapter* i2c);
+#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \
+	&& defined(MODULE))
+extern struct dvb_frontend *cx22702_attach(
+	const struct cx22702_config *config,
+	struct i2c_adapter *i2c);
 #else
-static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
-					   struct i2c_adapter* i2c)
+static inline struct dvb_frontend *cx22702_attach(
+	const struct cx22702_config *config,
+	struct i2c_adapter *i2c)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
-#endif // CONFIG_DVB_CX22702
+#endif
 
-#endif // CX22702_H
+#endif

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 306 - 249
drivers/media/dvb/frontends/cx24116.c


+ 11 - 10
drivers/media/dvb/frontends/cx24116.h

@@ -23,31 +23,32 @@
 
 #include <linux/dvb/frontend.h>
 
-struct cx24116_config
-{
+struct cx24116_config {
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
 	/* Need to set device param for start_dma */
-	int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+	int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
 
 	/* Need to reset device during firmware loading */
-	int (*reset_device)(struct dvb_frontend* fe);
+	int (*reset_device)(struct dvb_frontend *fe);
 
 	/* Need to set MPEG parameters */
 	u8 mpg_clk_pos_pol:0x02;
 };
 
 #if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE)
-extern struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
-					   struct i2c_adapter* i2c);
+extern struct dvb_frontend *cx24116_attach(
+	const struct cx24116_config *config,
+	struct i2c_adapter *i2c);
 #else
-static inline struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
-						  struct i2c_adapter* i2c)
+static inline struct dvb_frontend *cx24116_attach(
+	const struct cx24116_config *config,
+	struct i2c_adapter *i2c)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
-#endif // CONFIG_DVB_CX24116
+#endif
 
 #endif /* CX24116_H */

+ 128 - 100
drivers/media/dvb/frontends/cx24123.c

@@ -33,7 +33,13 @@
 #define XTAL 10111000
 
 static int force_band;
+module_param(force_band, int, 0644);
+MODULE_PARM_DESC(force_band, "Force a specific band select "\
+	"(1-9, default:off).");
+
 static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
 
 #define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0)
 #define err(args...)  do { printk(KERN_ERR  "CX24123: " args); } while (0)
@@ -46,10 +52,9 @@ static int debug;
 		} \
 	} while (0)
 
-struct cx24123_state
-{
-	struct i2c_adapter* i2c;
-	const struct cx24123_config* config;
+struct cx24123_state {
+	struct i2c_adapter *i2c;
+	const struct cx24123_config *config;
 
 	struct dvb_frontend frontend;
 
@@ -70,8 +75,7 @@ struct cx24123_state
 };
 
 /* Various tuner defaults need to be established for a given symbol rate Sps */
-static struct
-{
+static struct cx24123_AGC_val {
 	u32 symbolrate_low;
 	u32 symbolrate_high;
 	u32 VCAprogdata;
@@ -109,8 +113,7 @@ static struct
  * fixme: The bounds on the bands do not match the doc in real life.
  * fixme: Some of them have been moved, other might need adjustment.
  */
-static struct
-{
+static struct cx24123_bandselect_val {
 	u32 freq_low;
 	u32 freq_high;
 	u32 VCOdivider;
@@ -249,7 +252,8 @@ static int cx24123_i2c_writereg(struct cx24123_state *state,
 
 	/* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */
 
-	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+	err = i2c_transfer(state->i2c, &msg, 1);
+	if (err != 1) {
 		printk("%s: writereg error(err == %i, reg == 0x%02x,"
 			 " data == 0x%02x)\n", __func__, err, reg, data);
 		return err;
@@ -284,7 +288,8 @@ static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg)
 #define cx24123_writereg(state, reg, val) \
 	cx24123_i2c_writereg(state, state->config->demod_address, reg, val)
 
-static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
+static int cx24123_set_inversion(struct cx24123_state *state,
+	fe_spectral_inversion_t inversion)
 {
 	u8 nom_reg = cx24123_readreg(state, 0x0e);
 	u8 auto_reg = cx24123_readreg(state, 0x10);
@@ -311,7 +316,8 @@ static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_invers
 	return 0;
 }
 
-static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion)
+static int cx24123_get_inversion(struct cx24123_state *state,
+	fe_spectral_inversion_t *inversion)
 {
 	u8 val;
 
@@ -328,18 +334,20 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers
 	return 0;
 }
 
-static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
+static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec)
 {
 	u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
 
-	if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
+	if ((fec < FEC_NONE) || (fec > FEC_AUTO))
 		fec = FEC_AUTO;
 
 	/* Set the soft decision threshold */
-	if(fec == FEC_1_2)
-		cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) | 0x01);
+	if (fec == FEC_1_2)
+		cx24123_writereg(state, 0x43,
+			cx24123_readreg(state, 0x43) | 0x01);
 	else
-		cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) & ~0x01);
+		cx24123_writereg(state, 0x43,
+			cx24123_readreg(state, 0x43) & ~0x01);
 
 	switch (fec) {
 	case FEC_1_2:
@@ -388,11 +396,11 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
 	return 0;
 }
 
-static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec)
+static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec)
 {
 	int ret;
 
-	ret = cx24123_readreg (state, 0x1b);
+	ret = cx24123_readreg(state, 0x1b);
 	if (ret < 0)
 		return ret;
 	ret = ret & 0x07;
@@ -433,16 +441,16 @@ static u32 cx24123_int_log2(u32 a, u32 b)
 {
 	u32 exp, nearest = 0;
 	u32 div = a / b;
-	if(a % b >= b / 2) ++div;
-	if(div < (1 << 31))
-	{
-		for(exp = 1; div > exp; nearest++)
+	if (a % b >= b / 2)
+		++div;
+	if (div < (1 << 31)) {
+		for (exp = 1; div > exp; nearest++)
 			exp += exp;
 	}
 	return nearest;
 }
 
-static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
+static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
 {
 	u32 tmp, sample_rate, ratio, sample_gain;
 	u8 pll_mult;
@@ -498,9 +506,9 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
 
 	cx24123_writereg(state, 0x01, pll_mult * 6);
 
-	cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f );
-	cx24123_writereg(state, 0x09, (ratio >>  8) & 0xff );
-	cx24123_writereg(state, 0x0a, (ratio      ) & 0xff );
+	cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f);
+	cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff);
+	cx24123_writereg(state, 0x0a, ratio & 0xff);
 
 	/* also set the demodulator sample gain */
 	sample_gain = cx24123_int_log2(sample_rate, srate);
@@ -514,10 +522,12 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
 }
 
 /*
- * Based on the required frequency and symbolrate, the tuner AGC has to be configured
- * and the correct band selected. Calculate those values
+ * Based on the required frequency and symbolrate, the tuner AGC has
+ * to be configured and the correct band selected.
+ * Calculate those values.
  */
-static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx24123_pll_calculate(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	u32 ndiv = 0, adiv = 0, vco_div = 0;
@@ -525,6 +535,8 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
 	int pump = 2;
 	int band = 0;
 	int num_bands = ARRAY_SIZE(cx24123_bandselect_vals);
+	struct cx24123_bandselect_val *bsv = NULL;
+	struct cx24123_AGC_val *agcv = NULL;
 
 	/* Defaults for low freq, low rate */
 	state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
@@ -532,58 +544,65 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
 	state->bandselectarg = cx24123_bandselect_vals[0].progdata;
 	vco_div = cx24123_bandselect_vals[0].VCOdivider;
 
-	/* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */
-	for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++)
-	{
-		if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) &&
-		    (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
-			state->VCAarg = cx24123_AGC_vals[i].VCAprogdata;
-			state->VGAarg = cx24123_AGC_vals[i].VGAprogdata;
-			state->FILTune = cx24123_AGC_vals[i].FILTune;
+	/* For the given symbol rate, determine the VCA, VGA and
+	 * FILTUNE programming bits */
+	for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) {
+		agcv = &cx24123_AGC_vals[i];
+		if ((agcv->symbolrate_low <= p->u.qpsk.symbol_rate) &&
+		    (agcv->symbolrate_high >= p->u.qpsk.symbol_rate)) {
+			state->VCAarg = agcv->VCAprogdata;
+			state->VGAarg = agcv->VGAprogdata;
+			state->FILTune = agcv->FILTune;
 		}
 	}
 
 	/* determine the band to use */
-	if(force_band < 1 || force_band > num_bands)
-	{
-		for (i = 0; i < num_bands; i++)
-		{
-			if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
-			    (cx24123_bandselect_vals[i].freq_high >= p->frequency) )
+	if (force_band < 1 || force_band > num_bands) {
+		for (i = 0; i < num_bands; i++) {
+			bsv = &cx24123_bandselect_vals[i];
+			if ((bsv->freq_low <= p->frequency) &&
+				(bsv->freq_high >= p->frequency))
 				band = i;
 		}
-	}
-	else
+	} else
 		band = force_band - 1;
 
 	state->bandselectarg = cx24123_bandselect_vals[band].progdata;
 	vco_div = cx24123_bandselect_vals[band].VCOdivider;
 
 	/* determine the charge pump current */
-	if ( p->frequency < (cx24123_bandselect_vals[band].freq_low + cx24123_bandselect_vals[band].freq_high)/2 )
+	if (p->frequency < (cx24123_bandselect_vals[band].freq_low +
+		cx24123_bandselect_vals[band].freq_high) / 2)
 		pump = 0x01;
 	else
 		pump = 0x02;
 
 	/* Determine the N/A dividers for the requested lband freq (in kHz). */
-	/* Note: the reference divider R=10, frequency is in KHz, XTAL is in Hz */
-	ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff;
-	adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f;
+	/* Note: the reference divider R=10, frequency is in KHz,
+	 * XTAL is in Hz */
+	ndiv = (((p->frequency * vco_div * 10) /
+		(2 * XTAL / 1000)) / 32) & 0x1ff;
+	adiv = (((p->frequency * vco_div * 10) /
+		(2 * XTAL / 1000)) % 32) & 0x1f;
 
 	if (adiv == 0 && ndiv > 0)
 		ndiv--;
 
-	/* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */
-	state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv;
+	/* control bits 11, refdiv 11, charge pump polarity 1,
+	 * charge pump current, ndiv, adiv */
+	state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) |
+		(pump << 14) | (ndiv << 5) | adiv;
 
 	return 0;
 }
 
 /*
  * Tuner data is 21 bits long, must be left-aligned in data.
- * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip.
+ * Tuner cx24109 is written through a dedicated 3wire interface
+ * on the demod chip.
  */
-static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data)
+static int cx24123_pll_writereg(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p, u32 data)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	unsigned long timeout;
@@ -610,7 +629,7 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
 
 	/* send another 8 bytes, wait for the send to be completed */
 	timeout = jiffies + msecs_to_jiffies(40);
-	cx24123_writereg(state, 0x22, (data>>8) & 0xff );
+	cx24123_writereg(state, 0x22, (data >> 8) & 0xff);
 	while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
 		if (time_after(jiffies, timeout)) {
 			err("%s:  demodulator is not responding, "\
@@ -620,9 +639,10 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
 		msleep(10);
 	}
 
-	/* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */
+	/* send the lower 5 bits of this byte, padded with 3 LBB,
+	 * wait for the send to be completed */
 	timeout = jiffies + msecs_to_jiffies(40);
-	cx24123_writereg(state, 0x22, (data) & 0xff );
+	cx24123_writereg(state, 0x22, (data) & 0xff);
 	while ((cx24123_readreg(state, 0x20) & 0x80)) {
 		if (time_after(jiffies, timeout)) {
 			err("%s:  demodulator is not responding," \
@@ -639,7 +659,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
 	return 0;
 }
 
-static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx24123_pll_tune(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	u8 val;
@@ -690,7 +711,7 @@ static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start)
 	return cx24123_writereg(state, 0x23, r);
 }
 
-static int cx24123_initfe(struct dvb_frontend* fe)
+static int cx24123_initfe(struct dvb_frontend *fe)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	int i;
@@ -699,19 +720,22 @@ static int cx24123_initfe(struct dvb_frontend* fe)
 
 	/* Configure the demod to a good set of defaults */
 	for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++)
-		cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
+		cx24123_writereg(state, cx24123_regdata[i].reg,
+			cx24123_regdata[i].data);
 
 	/* Set the LNB polarity */
-	if(state->config->lnb_polarity)
-		cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02);
+	if (state->config->lnb_polarity)
+		cx24123_writereg(state, 0x32,
+			cx24123_readreg(state, 0x32) | 0x02);
 
 	if (state->config->dont_use_pll)
-	cx24123_repeater_mode(state, 1, 0);
+		cx24123_repeater_mode(state, 1, 0);
 
 	return 0;
 }
 
-static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+static int cx24123_set_voltage(struct dvb_frontend *fe,
+	fe_sec_voltage_t voltage)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	u8 val;
@@ -740,7 +764,7 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
 {
 	unsigned long timeout = jiffies + msecs_to_jiffies(200);
 	while (!(cx24123_readreg(state, 0x29) & 0x40)) {
-		if(time_after(jiffies, timeout)) {
+		if (time_after(jiffies, timeout)) {
 			err("%s: diseqc queue not ready, " \
 				"command may be lost.\n", __func__);
 			break;
@@ -749,7 +773,8 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
 	}
 }
 
-static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
+static int cx24123_send_diseqc_msg(struct dvb_frontend *fe,
+	struct dvb_diseqc_master_cmd *cmd)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	int i, val, tone;
@@ -771,20 +796,21 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
 		cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
 
 	val = cx24123_readreg(state, 0x29);
-	cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
+	cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) |
+		((cmd->msg_len-3) & 3));
 
 	/* wait for diseqc message to finish sending */
 	cx24123_wait_for_diseqc(state);
 
 	/* restart continuous tone if enabled */
-	if (tone & 0x10) {
+	if (tone & 0x10)
 		cx24123_writereg(state, 0x29, tone & ~0x40);
-	}
 
 	return 0;
 }
 
-static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+static int cx24123_diseqc_send_burst(struct dvb_frontend *fe,
+	fe_sec_mini_cmd_t burst)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	int val, tone;
@@ -814,13 +840,13 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
 	cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
 
 	/* restart continuous tone if enabled */
-	if (tone & 0x10) {
+	if (tone & 0x10)
 		cx24123_writereg(state, 0x29, tone & ~0x40);
-	}
+
 	return 0;
 }
 
-static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	int sync = cx24123_readreg(state, 0x14);
@@ -853,8 +879,9 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
 }
 
 /*
- * Configured to return the measurement of errors in blocks, because no UCBLOCKS value
- * is available, so this value doubles up to satisfy both measurements
+ * Configured to return the measurement of errors in blocks,
+ * because no UCBLOCKS value is available, so this value doubles up
+ * to satisfy both measurements.
  */
 static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
@@ -876,7 +903,8 @@ static int cx24123_read_signal_strength(struct dvb_frontend *fe,
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 
-	*signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
+	/* larger = better */
+	*signal_strength = cx24123_readreg(state, 0x3b) << 8;
 
 	dprintk("Signal strength = %d\n", *signal_strength);
 
@@ -907,7 +935,7 @@ static int cx24123_set_frontend(struct dvb_frontend *fe,
 	if (state->config->set_ts_params)
 		state->config->set_ts_params(fe, 0);
 
-	state->currentfreq=p->frequency;
+	state->currentfreq = p->frequency;
 	state->currentsymbolrate = p->u.qpsk.symbol_rate;
 
 	cx24123_set_inversion(state, p->inversion);
@@ -932,7 +960,8 @@ static int cx24123_set_frontend(struct dvb_frontend *fe,
 	return 0;
 }
 
-static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx24123_get_frontend(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 
@@ -952,7 +981,7 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 	return 0;
 }
 
-static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	u8 val;
@@ -977,8 +1006,8 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 	return 0;
 }
 
-static int cx24123_tune(struct dvb_frontend* fe,
-			struct dvb_frontend_parameters* params,
+static int cx24123_tune(struct dvb_frontend *fe,
+			struct dvb_frontend_parameters *params,
 			unsigned int mode_flags,
 			unsigned int *delay,
 			fe_status_t *status)
@@ -997,12 +1026,12 @@ static int cx24123_tune(struct dvb_frontend* fe,
 
 static int cx24123_get_algo(struct dvb_frontend *fe)
 {
-	return 1; //FE_ALGO_HW
+	return 1; /* FE_ALGO_HW */
 }
 
-static void cx24123_release(struct dvb_frontend* fe)
+static void cx24123_release(struct dvb_frontend *fe)
 {
-	struct cx24123_state* state = fe->demodulator_priv;
+	struct cx24123_state *state = fe->demodulator_priv;
 	dprintk("\n");
 	i2c_del_adapter(&state->tuner_i2c_adapter);
 	kfree(state);
@@ -1013,7 +1042,7 @@ static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap,
 {
 	struct cx24123_state *state = i2c_get_adapdata(i2c_adap);
 	/* this repeater closes after the first stop */
-    cx24123_repeater_mode(state, 1, 1);
+	cx24123_repeater_mode(state, 1, 1);
 	return i2c_transfer(state->i2c, msg, num);
 }
 
@@ -1037,8 +1066,8 @@ EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
 
 static struct dvb_frontend_ops cx24123_ops;
 
-struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
-				    struct i2c_adapter* i2c)
+struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
+				    struct i2c_adapter *i2c)
 {
 	struct cx24123_state *state =
 		kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
@@ -1057,20 +1086,25 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
 	/* check if the demod is there */
 	state->demod_rev = cx24123_readreg(state, 0x00);
 	switch (state->demod_rev) {
-	case 0xe1: info("detected CX24123C\n"); break;
-	case 0xd1: info("detected CX24123\n"); break;
+	case 0xe1:
+		info("detected CX24123C\n");
+		break;
+	case 0xd1:
+		info("detected CX24123\n");
+		break;
 	default:
 		err("wrong demod revision: %x\n", state->demod_rev);
 		goto error;
 	}
 
 	/* create dvb_frontend */
-	memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
+	memcpy(&state->frontend.ops, &cx24123_ops,
+		sizeof(struct dvb_frontend_ops));
 	state->frontend.demodulator_priv = state;
 
-    /* create tuner i2c adapter */
-    if (config->dont_use_pll)
-	cx24123_repeater_mode(state, 1, 0);
+	/* create tuner i2c adapter */
+	if (config->dont_use_pll)
+		cx24123_repeater_mode(state, 1, 0);
 
 	strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
 		sizeof(state->tuner_i2c_adapter.name));
@@ -1079,7 +1113,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
 	state->tuner_i2c_adapter.algo_data = NULL;
 	i2c_set_adapdata(&state->tuner_i2c_adapter, state);
 	if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
-	err("tuner i2c bus could not be initialized\n");
+		err("tuner i2c bus could not be initialized\n");
 		goto error;
 	}
 
@@ -1090,6 +1124,7 @@ error:
 
 	return NULL;
 }
+EXPORT_SYMBOL(cx24123_attach);
 
 static struct dvb_frontend_ops cx24123_ops = {
 
@@ -1126,15 +1161,8 @@ static struct dvb_frontend_ops cx24123_ops = {
 	.get_frontend_algo = cx24123_get_algo,
 };
 
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-
-module_param(force_band, int, 0644);
-MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off).");
-
 MODULE_DESCRIPTION("DVB Frontend module for Conexant " \
 	"CX24123/CX24109/CX24113 hardware");
 MODULE_AUTHOR("Steven Toth");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(cx24123_attach);

+ 5 - 5
drivers/media/dvb/frontends/cx24123.h

@@ -23,13 +23,12 @@
 
 #include <linux/dvb/frontend.h>
 
-struct cx24123_config
-{
+struct cx24123_config {
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
 	/* Need to set device param for start_dma */
-	int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+	int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
 
 	/* 0 = LNB voltage normal, 1 = LNB voltage inverted */
 	int lnb_polarity;
@@ -39,7 +38,8 @@ struct cx24123_config
 	void (*agc_callback) (struct dvb_frontend *);
 };
 
-#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE))
+#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \
+	&& defined(MODULE))
 extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
 					   struct i2c_adapter *i2c);
 extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);
@@ -56,6 +56,6 @@ static struct i2c_adapter *
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
-#endif // CONFIG_DVB_CX24123
+#endif
 
 #endif /* CX24123_H */

+ 70 - 68
drivers/media/dvb/frontends/s5h1409.c

@@ -30,10 +30,10 @@
 
 struct s5h1409_state {
 
-	struct i2c_adapter* i2c;
+	struct i2c_adapter *i2c;
 
 	/* configuration settings */
-	const struct s5h1409_config* config;
+	const struct s5h1409_config *config;
 
 	struct dvb_frontend frontend;
 
@@ -48,6 +48,9 @@ struct s5h1409_state {
 };
 
 static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
 #define dprintk	if (debug) printk
 
 /* Register values to initialise the demod, this will set VSB by default */
@@ -299,10 +302,10 @@ static struct qam256_snr_tab {
 };
 
 /* 8 bit registers, 16 bit values */
-static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data)
+static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data)
 {
 	int ret;
-	u8 buf [] = { reg, data >> 8,  data & 0xff };
+	u8 buf[] = { reg, data >> 8,  data & 0xff };
 
 	struct i2c_msg msg = { .addr = state->config->demod_address,
 			       .flags = 0, .buf = buf, .len = 3 };
@@ -310,19 +313,19 @@ static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data)
 	ret = i2c_transfer(state->i2c, &msg, 1);
 
 	if (ret != 1)
-		printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
+		printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, "
 		       "ret == %i)\n", __func__, reg, data, ret);
 
 	return (ret != 1) ? -1 : 0;
 }
 
-static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg)
+static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg)
 {
 	int ret;
-	u8 b0 [] = { reg };
-	u8 b1 [] = { 0, 0 };
+	u8 b0[] = { reg };
+	u8 b1[] = { 0, 0 };
 
-	struct i2c_msg msg [] = {
+	struct i2c_msg msg[] = {
 		{ .addr = state->config->demod_address, .flags = 0,
 		  .buf = b0, .len = 1 },
 		{ .addr = state->config->demod_address, .flags = I2C_M_RD,
@@ -335,9 +338,9 @@ static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg)
 	return (b1[0] << 8) | b1[1];
 }
 
-static int s5h1409_softreset(struct dvb_frontend* fe)
+static int s5h1409_softreset(struct dvb_frontend *fe)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	dprintk("%s()\n", __func__);
 
@@ -349,11 +352,11 @@ static int s5h1409_softreset(struct dvb_frontend* fe)
 }
 
 #define S5H1409_VSB_IF_FREQ 5380
-#define S5H1409_QAM_IF_FREQ state->config->qam_if
+#define S5H1409_QAM_IF_FREQ (state->config->qam_if)
 
-static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
+static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	dprintk("%s(%d KHz)\n", __func__, KHz);
 
@@ -376,26 +379,26 @@ static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
 	return 0;
 }
 
-static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted)
+static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	dprintk("%s(%d)\n", __func__, inverted);
 
-	if(inverted == 1)
+	if (inverted == 1)
 		return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
 	else
 		return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */
 }
 
-static int s5h1409_enable_modulation(struct dvb_frontend* fe,
+static int s5h1409_enable_modulation(struct dvb_frontend *fe,
 				     fe_modulation_t m)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	dprintk("%s(0x%08x)\n", __func__, m);
 
-	switch(m) {
+	switch (m) {
 	case VSB_8:
 		dprintk("%s() VSB_8\n", __func__);
 		if (state->if_freq != S5H1409_VSB_IF_FREQ)
@@ -422,9 +425,9 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe,
 	return 0;
 }
 
-static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	dprintk("%s(%d)\n", __func__, enable);
 
@@ -434,9 +437,9 @@ static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
 		return s5h1409_writereg(state, 0xf3, 0);
 }
 
-static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
+static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	dprintk("%s(%d)\n", __func__, enable);
 
@@ -448,18 +451,18 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
 			s5h1409_readreg(state, 0xe3) & 0xfeff);
 }
 
-static int s5h1409_sleep(struct dvb_frontend* fe, int enable)
+static int s5h1409_sleep(struct dvb_frontend *fe, int enable)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	dprintk("%s(%d)\n", __func__, enable);
 
 	return s5h1409_writereg(state, 0xf2, enable);
 }
 
-static int s5h1409_register_reset(struct dvb_frontend* fe)
+static int s5h1409_register_reset(struct dvb_frontend *fe)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	dprintk("%s()\n", __func__);
 
@@ -483,7 +486,7 @@ static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe)
 		reg &= 0xff;
 
 		s5h1409_writereg(state, 0x96, 0x00c);
-		if ((reg < 0x38) || (reg > 0x68) ) {
+		if ((reg < 0x38) || (reg > 0x68)) {
 			s5h1409_writereg(state, 0x93, 0x3332);
 			s5h1409_writereg(state, 0x9e, 0x2c37);
 		} else {
@@ -514,7 +517,7 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
 
 			s5h1409_writereg(state, 0x96, 0x20);
 			s5h1409_writereg(state, 0xad,
-				( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) );
+				(((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
 			s5h1409_writereg(state, 0xab,
 				s5h1409_readreg(state, 0xab) & 0xeffe);
 		}
@@ -529,10 +532,10 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
 }
 
 /* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int s5h1409_set_frontend (struct dvb_frontend* fe,
+static int s5h1409_set_frontend(struct dvb_frontend *fe,
 				 struct dvb_frontend_parameters *p)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	dprintk("%s(frequency=%d)\n", __func__, p->frequency);
 
@@ -546,9 +549,11 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe,
 	msleep(100);
 
 	if (fe->ops.tuner_ops.set_params) {
-		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
 		fe->ops.tuner_ops.set_params(fe, p);
-		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
 	}
 
 	/* Optimize the demod for QAM */
@@ -592,17 +597,17 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode)
 
 /* Reset the demod hardware and reset all of the configuration registers
    to a default state. */
-static int s5h1409_init (struct dvb_frontend* fe)
+static int s5h1409_init(struct dvb_frontend *fe)
 {
 	int i;
 
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 	dprintk("%s()\n", __func__);
 
 	s5h1409_sleep(fe, 0);
 	s5h1409_register_reset(fe);
 
-	for (i=0; i < ARRAY_SIZE(init_tab); i++)
+	for (i = 0; i < ARRAY_SIZE(init_tab); i++)
 		s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data);
 
 	/* The datasheet says that after initialisation, VSB is default */
@@ -627,9 +632,9 @@ static int s5h1409_init (struct dvb_frontend* fe)
 	return 0;
 }
 
-static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 	u16 reg;
 	u32 tuner_status = 0;
 
@@ -637,12 +642,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
 	/* Get the demodulator status */
 	reg = s5h1409_readreg(state, 0xf1);
-	if(reg & 0x1000)
+	if (reg & 0x1000)
 		*status |= FE_HAS_VITERBI;
-	if(reg & 0x8000)
+	if (reg & 0x8000)
 		*status |= FE_HAS_LOCK | FE_HAS_SYNC;
 
-	switch(state->config->status_mode) {
+	switch (state->config->status_mode) {
 	case S5H1409_DEMODLOCKING:
 		if (*status & FE_HAS_VITERBI)
 			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
@@ -668,12 +673,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
 	return 0;
 }
 
-static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
+static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
 {
 	int i, ret = -EINVAL;
 	dprintk("%s()\n", __func__);
 
-	for (i=0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
+	for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
 		if (v < qam256_snr_tab[i].val) {
 			*snr = qam256_snr_tab[i].data;
 			ret = 0;
@@ -683,12 +688,12 @@ static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
 	return ret;
 }
 
-static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
+static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
 {
 	int i, ret = -EINVAL;
 	dprintk("%s()\n", __func__);
 
-	for (i=0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
+	for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
 		if (v < qam64_snr_tab[i].val) {
 			*snr = qam64_snr_tab[i].data;
 			ret = 0;
@@ -698,12 +703,12 @@ static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
 	return ret;
 }
 
-static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
+static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
 {
 	int i, ret = -EINVAL;
 	dprintk("%s()\n", __func__);
 
-	for (i=0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
+	for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
 		if (v > vsb_snr_tab[i].val) {
 			*snr = vsb_snr_tab[i].data;
 			ret = 0;
@@ -714,13 +719,13 @@ static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
 	return ret;
 }
 
-static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr)
+static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 	u16 reg;
 	dprintk("%s()\n", __func__);
 
-	switch(state->current_modulation) {
+	switch (state->current_modulation) {
 	case QAM_64:
 		reg = s5h1409_readreg(state, 0xf0) & 0xff;
 		return s5h1409_qam64_lookup_snr(fe, snr, reg);
@@ -737,30 +742,30 @@ static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr)
 	return -EINVAL;
 }
 
-static int s5h1409_read_signal_strength(struct dvb_frontend* fe,
-					u16* signal_strength)
+static int s5h1409_read_signal_strength(struct dvb_frontend *fe,
+					u16 *signal_strength)
 {
 	return s5h1409_read_snr(fe, signal_strength);
 }
 
-static int s5h1409_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	*ucblocks = s5h1409_readreg(state, 0xb5);
 
 	return 0;
 }
 
-static int s5h1409_read_ber(struct dvb_frontend* fe, u32* ber)
+static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
 	return s5h1409_read_ucblocks(fe, ber);
 }
 
-static int s5h1409_get_frontend(struct dvb_frontend* fe,
+static int s5h1409_get_frontend(struct dvb_frontend *fe,
 				struct dvb_frontend_parameters *p)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 
 	p->frequency = state->current_frequency;
 	p->u.vsb.modulation = state->current_modulation;
@@ -768,25 +773,25 @@ static int s5h1409_get_frontend(struct dvb_frontend* fe,
 	return 0;
 }
 
-static int s5h1409_get_tune_settings(struct dvb_frontend* fe,
+static int s5h1409_get_tune_settings(struct dvb_frontend *fe,
 				     struct dvb_frontend_tune_settings *tune)
 {
 	tune->min_delay_ms = 1000;
 	return 0;
 }
 
-static void s5h1409_release(struct dvb_frontend* fe)
+static void s5h1409_release(struct dvb_frontend *fe)
 {
-	struct s5h1409_state* state = fe->demodulator_priv;
+	struct s5h1409_state *state = fe->demodulator_priv;
 	kfree(state);
 }
 
 static struct dvb_frontend_ops s5h1409_ops;
 
-struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
-				    struct i2c_adapter* i2c)
+struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
+				    struct i2c_adapter *i2c)
 {
-	struct s5h1409_state* state = NULL;
+	struct s5h1409_state *state = NULL;
 	u16 reg;
 
 	/* allocate memory for the internal state */
@@ -825,6 +830,7 @@ error:
 	kfree(state);
 	return NULL;
 }
+EXPORT_SYMBOL(s5h1409_attach);
 
 static struct dvb_frontend_ops s5h1409_ops = {
 
@@ -850,14 +856,10 @@ static struct dvb_frontend_ops s5h1409_ops = {
 	.release              = s5h1409_release,
 };
 
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
 MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver");
 MODULE_AUTHOR("Steven Toth");
 MODULE_LICENSE("GPL");
 
-EXPORT_SYMBOL(s5h1409_attach);
 
 /*
  * Local variables:

+ 8 - 7
drivers/media/dvb/frontends/s5h1409.h

@@ -24,8 +24,7 @@
 
 #include <linux/dvb/frontend.h>
 
-struct s5h1409_config
-{
+struct s5h1409_config {
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
@@ -60,12 +59,14 @@ struct s5h1409_config
 	u16 mpeg_timing;
 };
 
-#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) && defined(MODULE))
-extern struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
-					   struct i2c_adapter* i2c);
+#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
+	&& defined(MODULE))
+extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
+					   struct i2c_adapter *i2c);
 #else
-static inline struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
-						  struct i2c_adapter* i2c)
+static inline struct dvb_frontend *s5h1409_attach(
+	const struct s5h1409_config *config,
+	struct i2c_adapter *i2c)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;

+ 4 - 4
drivers/media/dvb/frontends/s5h1411.c

@@ -343,7 +343,7 @@ static int s5h1411_writereg(struct s5h1411_state *state,
 	u8 addr, u8 reg, u16 data)
 {
 	int ret;
-	u8 buf [] = { reg, data >> 8,  data & 0xff };
+	u8 buf[] = { reg, data >> 8,  data & 0xff };
 
 	struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
 
@@ -359,10 +359,10 @@ static int s5h1411_writereg(struct s5h1411_state *state,
 static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg)
 {
 	int ret;
-	u8 b0 [] = { reg };
-	u8 b1 [] = { 0, 0 };
+	u8 b0[] = { reg };
+	u8 b1[] = { 0, 0 };
 
-	struct i2c_msg msg [] = {
+	struct i2c_msg msg[] = {
 		{ .addr = addr, .flags = 0, .buf = b0, .len = 1 },
 		{ .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
 

+ 73 - 27
drivers/media/dvb/frontends/tda10048.c

@@ -195,7 +195,7 @@ static struct init_tab {
 static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
 {
 	int ret;
-	u8 buf [] = { reg, data };
+	u8 buf[] = { reg, data };
 	struct i2c_msg msg = {
 		.addr = state->config->demod_address,
 		.flags = 0, .buf = buf, .len = 2 };
@@ -213,9 +213,9 @@ static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
 static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
 {
 	int ret;
-	u8 b0 [] = { reg };
-	u8 b1 [] = { 0 };
-	struct i2c_msg msg [] = {
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+	struct i2c_msg msg[] = {
 		{ .addr = state->config->demod_address,
 			.flags = 0, .buf = b0, .len = 1 },
 		{ .addr = state->config->demod_address,
@@ -393,43 +393,89 @@ static int tda10048_get_tps(struct tda10048_state *state,
 
 	val = tda10048_readreg(state, TDA10048_OUT_CONF2);
 	switch ((val & 0x60) >> 5) {
-	case 0: p->constellation =   QPSK; break;
-	case 1: p->constellation = QAM_16; break;
-	case 2: p->constellation = QAM_64; break;
+	case 0:
+		p->constellation = QPSK;
+		break;
+	case 1:
+		p->constellation = QAM_16;
+		break;
+	case 2:
+		p->constellation = QAM_64;
+		break;
 	}
 	switch ((val & 0x18) >> 3) {
-	case 0: p->hierarchy_information = HIERARCHY_NONE; break;
-	case 1: p->hierarchy_information =    HIERARCHY_1; break;
-	case 2: p->hierarchy_information =    HIERARCHY_2; break;
-	case 3: p->hierarchy_information =    HIERARCHY_4; break;
+	case 0:
+		p->hierarchy_information = HIERARCHY_NONE;
+		break;
+	case 1:
+		p->hierarchy_information = HIERARCHY_1;
+		break;
+	case 2:
+		p->hierarchy_information = HIERARCHY_2;
+		break;
+	case 3:
+		p->hierarchy_information = HIERARCHY_4;
+		break;
 	}
 	switch (val & 0x07) {
-	case 0: p->code_rate_HP = FEC_1_2; break;
-	case 1: p->code_rate_HP = FEC_2_3; break;
-	case 2: p->code_rate_HP = FEC_3_4; break;
-	case 3: p->code_rate_HP = FEC_5_6; break;
-	case 4: p->code_rate_HP = FEC_7_8; break;
+	case 0:
+		p->code_rate_HP = FEC_1_2;
+		break;
+	case 1:
+		p->code_rate_HP = FEC_2_3;
+		break;
+	case 2:
+		p->code_rate_HP = FEC_3_4;
+		break;
+	case 3:
+		p->code_rate_HP = FEC_5_6;
+		break;
+	case 4:
+		p->code_rate_HP = FEC_7_8;
+		break;
 	}
 
 	val = tda10048_readreg(state, TDA10048_OUT_CONF3);
 	switch (val & 0x07) {
-	case 0: p->code_rate_LP = FEC_1_2; break;
-	case 1: p->code_rate_LP = FEC_2_3; break;
-	case 2: p->code_rate_LP = FEC_3_4; break;
-	case 3: p->code_rate_LP = FEC_5_6; break;
-	case 4: p->code_rate_LP = FEC_7_8; break;
+	case 0:
+		p->code_rate_LP = FEC_1_2;
+		break;
+	case 1:
+		p->code_rate_LP = FEC_2_3;
+		break;
+	case 2:
+		p->code_rate_LP = FEC_3_4;
+		break;
+	case 3:
+		p->code_rate_LP = FEC_5_6;
+		break;
+	case 4:
+		p->code_rate_LP = FEC_7_8;
+		break;
 	}
 
 	val = tda10048_readreg(state, TDA10048_OUT_CONF1);
 	switch ((val & 0x0c) >> 2) {
-	case 0: p->guard_interval = GUARD_INTERVAL_1_32; break;
-	case 1: p->guard_interval = GUARD_INTERVAL_1_16; break;
-	case 2: p->guard_interval =  GUARD_INTERVAL_1_8; break;
-	case 3: p->guard_interval =  GUARD_INTERVAL_1_4; break;
+	case 0:
+		p->guard_interval = GUARD_INTERVAL_1_32;
+		break;
+	case 1:
+		p->guard_interval = GUARD_INTERVAL_1_16;
+		break;
+	case 2:
+		p->guard_interval =  GUARD_INTERVAL_1_8;
+		break;
+	case 3:
+		p->guard_interval =  GUARD_INTERVAL_1_4;
+		break;
 	}
 	switch (val & 0x02) {
-	case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break;
-	case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break;
+	case 0:
+		p->transmission_mode = TRANSMISSION_MODE_2K;
+		break;
+	case 1:
+		p->transmission_mode = TRANSMISSION_MODE_8K;
+		break;
 	}
 
 	return 0;

+ 2 - 14
drivers/media/dvb/frontends/z0194a.h

@@ -12,7 +12,7 @@
 #ifndef Z0194A
 #define Z0194A
 
-static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe,
+static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe,
 					 u32 srate, u32 ratio)
 {
 	u8 aclk = 0;
@@ -40,7 +40,7 @@ static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe,
 	return 0;
 }
 
-static u8 sharp_z0194a__inittab[] = {
+static u8 sharp_z0194a_inittab[] = {
 	0x01, 0x15,
 	0x02, 0x00,
 	0x03, 0x00,
@@ -82,16 +82,4 @@ static u8 sharp_z0194a__inittab[] = {
 	0xff, 0xff
 };
 
-static struct stv0299_config sharp_z0194a_config = {
-	.demod_address = 0x68,
-	.inittab = sharp_z0194a__inittab,
-	.mclk = 88000000UL,
-	.invert = 1,
-	.skip_reinit = 0,
-	.lock_output = STV0299_LOCKOUTPUT_1,
-	.volt13_op0_op1 = STV0299_VOLT13_OP1,
-	.min_delay_ms = 100,
-	.set_symbol_rate = sharp_z0194a__set_symbol_rate,
-};
-
 #endif

+ 4 - 0
drivers/media/dvb/siano/sms-cards.c

@@ -42,6 +42,10 @@ struct usb_device_id smsusb_id_table[] = {
 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
 	{ USB_DEVICE(0x2040, 0x5510),
 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0x5520),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+	{ USB_DEVICE(0x2040, 0x5530),
+		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
 	{ USB_DEVICE(0x2040, 0x5580),
 		.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
 	{ USB_DEVICE(0x2040, 0x5590),

+ 1 - 1
drivers/media/radio/Kconfig

@@ -359,7 +359,7 @@ config USB_SI470X
 	  computer's USB port.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called radio-silabs.
+	  module will be called radio-si470x.
 
 config USB_MR800
 	tristate "AverMedia MR 800 USB FM radio support"

+ 97 - 137
drivers/media/radio/radio-si470x.c

@@ -104,6 +104,7 @@
  *		- hardware frequency seek support
  *		- afc indication
  *		- more safety checks, let si470x_get_freq return errno
+ *		- vidioc behavior corrected according to v4l2 spec
  *
  * ToDo:
  * - add firmware download/update support
@@ -141,9 +142,9 @@
 /* USB Device ID List */
 static struct usb_device_id si470x_usb_driver_id_table[] = {
 	/* Silicon Labs USB FM Radio Reference Design */
-	{ USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a,	USB_CLASS_HID, 0, 0) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
 	/* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */
-	{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155,	USB_CLASS_HID, 0, 0) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
 	/* Terminating entry */
 	{ }
 };
@@ -157,7 +158,7 @@ MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
 
 /* Radio Nr */
 static int radio_nr = -1;
-module_param(radio_nr, int, 0);
+module_param(radio_nr, int, 0444);
 MODULE_PARM_DESC(radio_nr, "Radio Nr");
 
 /* Spacing (kHz) */
@@ -165,42 +166,42 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr");
 /* 1: 100 kHz (Europe, Japan) */
 /* 2:  50 kHz */
 static unsigned short space = 2;
-module_param(space, ushort, 0);
-MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
+module_param(space, ushort, 0444);
+MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
 
 /* Bottom of Band (MHz) */
 /* 0: 87.5 - 108 MHz (USA, Europe)*/
 /* 1: 76   - 108 MHz (Japan wide band) */
 /* 2: 76   -  90 MHz (Japan) */
 static unsigned short band = 1;
-module_param(band, ushort, 0);
-MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
+module_param(band, ushort, 0444);
+MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
 
 /* De-emphasis */
 /* 0: 75 us (USA) */
 /* 1: 50 us (Europe, Australia, Japan) */
 static unsigned short de = 1;
-module_param(de, ushort, 0);
-MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*");
+module_param(de, ushort, 0444);
+MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*");
 
 /* USB timeout */
 static unsigned int usb_timeout = 500;
-module_param(usb_timeout, uint, 0);
+module_param(usb_timeout, uint, 0644);
 MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
 
 /* Tune timeout */
 static unsigned int tune_timeout = 3000;
-module_param(tune_timeout, uint, 0);
+module_param(tune_timeout, uint, 0644);
 MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
 
 /* Seek timeout */
 static unsigned int seek_timeout = 5000;
-module_param(seek_timeout, uint, 0);
+module_param(seek_timeout, uint, 0644);
 MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
 
 /* RDS buffer blocks */
 static unsigned int rds_buf = 100;
-module_param(rds_buf, uint, 0);
+module_param(rds_buf, uint, 0444);
 MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
 
 /* RDS maximum block errors */
@@ -209,7 +210,7 @@ static unsigned short max_rds_errors = 1;
 /* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
 /* 2 means 3-5  errors requiring correction */
 /* 3 means   6+ errors or errors in checkword, correction not possible */
-module_param(max_rds_errors, ushort, 0);
+module_param(max_rds_errors, ushort, 0644);
 MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
 
 /* RDS poll frequency */
@@ -218,7 +219,7 @@ static unsigned int rds_poll_time = 40;
 /* 50 is used by radio-cadet */
 /* 75 should be okay */
 /* 80 is the usual RDS receive interval */
-module_param(rds_poll_time, uint, 0);
+module_param(rds_poll_time, uint, 0644);
 MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
 
 
@@ -667,23 +668,29 @@ static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
 	int retval;
 
 	/* Spacing (kHz) */
-	switch (space) {
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
 	/* 0: 200 kHz (USA, Australia) */
-	case 0 : spacing = 0.200 * FREQ_MUL; break;
+	case 0:
+		spacing = 0.200 * FREQ_MUL; break;
 	/* 1: 100 kHz (Europe, Japan) */
-	case 1 : spacing = 0.100 * FREQ_MUL; break;
+	case 1:
+		spacing = 0.100 * FREQ_MUL; break;
 	/* 2:  50 kHz */
-	default: spacing = 0.050 * FREQ_MUL; break;
+	default:
+		spacing = 0.050 * FREQ_MUL; break;
 	};
 
 	/* Bottom of Band (MHz) */
-	switch (band) {
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
 	/* 0: 87.5 - 108 MHz (USA, Europe) */
-	case 0 : band_bottom = 87.5 * FREQ_MUL; break;
+	case 0:
+		band_bottom = 87.5 * FREQ_MUL; break;
 	/* 1: 76   - 108 MHz (Japan wide band) */
-	default: band_bottom = 76   * FREQ_MUL; break;
+	default:
+		band_bottom = 76   * FREQ_MUL; break;
 	/* 2: 76   -  90 MHz (Japan) */
-	case 2 : band_bottom = 76   * FREQ_MUL; break;
+	case 2:
+		band_bottom = 76   * FREQ_MUL; break;
 	};
 
 	/* read channel */
@@ -706,23 +713,29 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
 	unsigned short chan;
 
 	/* Spacing (kHz) */
-	switch (space) {
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
 	/* 0: 200 kHz (USA, Australia) */
-	case 0 : spacing = 0.200 * FREQ_MUL; break;
+	case 0:
+		spacing = 0.200 * FREQ_MUL; break;
 	/* 1: 100 kHz (Europe, Japan) */
-	case 1 : spacing = 0.100 * FREQ_MUL; break;
+	case 1:
+		spacing = 0.100 * FREQ_MUL; break;
 	/* 2:  50 kHz */
-	default: spacing = 0.050 * FREQ_MUL; break;
+	default:
+		spacing = 0.050 * FREQ_MUL; break;
 	};
 
 	/* Bottom of Band (MHz) */
-	switch (band) {
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
 	/* 0: 87.5 - 108 MHz (USA, Europe) */
-	case 0 : band_bottom = 87.5 * FREQ_MUL; break;
+	case 0:
+		band_bottom = 87.5 * FREQ_MUL; break;
 	/* 1: 76   - 108 MHz (Japan wide band) */
-	default: band_bottom = 76   * FREQ_MUL; break;
+	default:
+		band_bottom = 76   * FREQ_MUL; break;
 	/* 2: 76   -  90 MHz (Japan) */
-	case 2 : band_bottom = 76   * FREQ_MUL; break;
+	case 2:
+		band_bottom = 76   * FREQ_MUL; break;
 	};
 
 	/* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */
@@ -1164,7 +1177,6 @@ static const struct file_operations si470x_fops = {
  * si470x_v4l2_queryctrl - query control
  */
 static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
-/* HINT: the disabled controls are only here to satify kradio and such apps */
 	{
 		.id		= V4L2_CID_AUDIO_VOLUME,
 		.type		= V4L2_CTRL_TYPE_INTEGER,
@@ -1174,18 +1186,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
 		.step		= 1,
 		.default_value	= 15,
 	},
-	{
-		.id		= V4L2_CID_AUDIO_BALANCE,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_BASS,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_TREBLE,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
 	{
 		.id		= V4L2_CID_AUDIO_MUTE,
 		.type		= V4L2_CTRL_TYPE_BOOLEAN,
@@ -1195,10 +1195,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
 		.step		= 1,
 		.default_value	= 1,
 	},
-	{
-		.id		= V4L2_CID_AUDIO_LOUDNESS,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
 };
 
 
@@ -1219,57 +1215,35 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
 }
 
 
-/*
- * si470x_vidioc_g_input - get input
- */
-static int si470x_vidioc_g_input(struct file *file, void *priv,
-		unsigned int *i)
-{
-	*i = 0;
-
-	return 0;
-}
-
-
-/*
- * si470x_vidioc_s_input - set input
- */
-static int si470x_vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
-	int retval = 0;
-
-	/* safety checks */
-	if (i != 0)
-		retval = -EINVAL;
-
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": set input failed with %d\n", retval);
-	return retval;
-}
-
-
 /*
  * si470x_vidioc_queryctrl - enumerate control items
  */
 static int si470x_vidioc_queryctrl(struct file *file, void *priv,
 		struct v4l2_queryctrl *qc)
 {
-	unsigned char i;
+	unsigned char i = 0;
 	int retval = -EINVAL;
 
-	/* safety checks */
-	if (!qc->id)
+	/* abort if qc->id is below V4L2_CID_BASE */
+	if (qc->id < V4L2_CID_BASE)
 		goto done;
 
+	/* search video control */
 	for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
 		if (qc->id == si470x_v4l2_queryctrl[i].id) {
 			memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
-			retval = 0;
+			retval = 0; /* found */
 			break;
 		}
 	}
 
+	/* disable unsupported base controls */
+	/* to satisfy kradio and such apps */
+	if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) {
+		qc->flags = V4L2_CTRL_FLAG_DISABLED;
+		retval = 0;
+	}
+
 done:
 	if (retval < 0)
 		printk(KERN_WARNING DRIVER_NAME
@@ -1360,44 +1334,13 @@ done:
 static int si470x_vidioc_g_audio(struct file *file, void *priv,
 		struct v4l2_audio *audio)
 {
-	int retval = 0;
-
-	/* safety checks */
-	if (audio->index != 0) {
-		retval = -EINVAL;
-		goto done;
-	}
-
+	/* driver constants */
+	audio->index = 0;
 	strcpy(audio->name, "Radio");
 	audio->capability = V4L2_AUDCAP_STEREO;
+	audio->mode = 0;
 
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": get audio failed with %d\n", retval);
-	return retval;
-}
-
-
-/*
- * si470x_vidioc_s_audio - set audio attributes
- */
-static int si470x_vidioc_s_audio(struct file *file, void *priv,
-		struct v4l2_audio *audio)
-{
-	int retval = 0;
-
-	/* safety checks */
-	if (audio->index != 0) {
-		retval = -EINVAL;
-		goto done;
-	}
-
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": set audio failed with %d\n", retval);
-	return retval;
+	return 0;
 }
 
 
@@ -1415,7 +1358,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
 		retval = -EIO;
 		goto done;
 	}
-	if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) {
+	if (tuner->index != 0) {
 		retval = -EINVAL;
 		goto done;
 	}
@@ -1424,8 +1367,13 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
 	if (retval < 0)
 		goto done;
 
+	/* driver constants */
 	strcpy(tuner->name, "FM");
-	switch (band) {
+	tuner->type = V4L2_TUNER_RADIO;
+	tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+
+	/* range limits */
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
 	/* 0: 87.5 - 108 MHz (USA, Europe, default) */
 	default:
 		tuner->rangelow  =  87.5 * FREQ_MUL;
@@ -1442,14 +1390,18 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
 		tuner->rangehigh =  90   * FREQ_MUL;
 		break;
 	};
-	tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-	tuner->capability = V4L2_TUNER_CAP_LOW;
 
-	/* Stereo indicator == Stereo (instead of Mono) */
+	/* stereo indicator == stereo (instead of mono) */
 	if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1)
-		tuner->audmode = V4L2_TUNER_MODE_STEREO;
+		tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
 	else
+		tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+
+	/* mono/stereo selector */
+	if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1)
 		tuner->audmode = V4L2_TUNER_MODE_MONO;
+	else
+		tuner->audmode = V4L2_TUNER_MODE_STEREO;
 
 	/* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
 	tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI)
@@ -1474,22 +1426,27 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
 		struct v4l2_tuner *tuner)
 {
 	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
+	int retval = -EINVAL;
 
 	/* safety checks */
 	if (radio->disconnected) {
 		retval = -EIO;
 		goto done;
 	}
-	if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) {
-		retval = -EINVAL;
+	if (tuner->index != 0)
 		goto done;
-	}
 
-	if (tuner->audmode == V4L2_TUNER_MODE_MONO)
+	/* mono/stereo selector */
+	switch (tuner->audmode) {
+	case V4L2_TUNER_MODE_MONO:
 		radio->registers[POWERCFG] |= POWERCFG_MONO;  /* force mono */
-	else
+		break;
+	case V4L2_TUNER_MODE_STEREO:
 		radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
+		break;
+	default:
+		goto done;
+	}
 
 	retval = si470x_set_register(radio, POWERCFG);
 
@@ -1515,11 +1472,12 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv,
 		retval = -EIO;
 		goto done;
 	}
-	if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) {
+	if (freq->tuner != 0) {
 		retval = -EINVAL;
 		goto done;
 	}
 
+	freq->type = V4L2_TUNER_RADIO;
 	retval = si470x_get_freq(radio, &freq->frequency);
 
 done:
@@ -1544,7 +1502,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
 		retval = -EIO;
 		goto done;
 	}
-	if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) {
+	if (freq->tuner != 0) {
 		retval = -EINVAL;
 		goto done;
 	}
@@ -1573,7 +1531,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
 		retval = -EIO;
 		goto done;
 	}
-	if ((seek->tuner != 0) && (seek->type != V4L2_TUNER_RADIO)) {
+	if (seek->tuner != 0) {
 		retval = -EINVAL;
 		goto done;
 	}
@@ -1588,15 +1546,16 @@ done:
 	return retval;
 }
 
+
+/*
+ * si470x_ioctl_ops - video device ioctl operations
+ */
 static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
 	.vidioc_querycap	= si470x_vidioc_querycap,
-	.vidioc_g_input		= si470x_vidioc_g_input,
-	.vidioc_s_input		= si470x_vidioc_s_input,
 	.vidioc_queryctrl	= si470x_vidioc_queryctrl,
 	.vidioc_g_ctrl		= si470x_vidioc_g_ctrl,
 	.vidioc_s_ctrl		= si470x_vidioc_s_ctrl,
 	.vidioc_g_audio		= si470x_vidioc_g_audio,
-	.vidioc_s_audio		= si470x_vidioc_s_audio,
 	.vidioc_g_tuner		= si470x_vidioc_g_tuner,
 	.vidioc_s_tuner		= si470x_vidioc_s_tuner,
 	.vidioc_g_frequency	= si470x_vidioc_g_frequency,
@@ -1604,14 +1563,15 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
 	.vidioc_s_hw_freq_seek	= si470x_vidioc_s_hw_freq_seek,
 };
 
+
 /*
- * si470x_viddev_tamples - video device interface
+ * si470x_viddev_template - video device interface
  */
 static struct video_device si470x_viddev_template = {
 	.fops			= &si470x_fops,
-	.ioctl_ops 		= &si470x_ioctl_ops,
 	.name			= DRIVER_NAME,
 	.release		= video_device_release,
+	.ioctl_ops		= &si470x_ioctl_ops,
 };
 
 

+ 57 - 194
drivers/media/video/adv7170.c

@@ -29,43 +29,24 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
 #include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
 #include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
 #include <linux/videodev.h>
 #include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
 
 MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
 MODULE_AUTHOR("Maxim Yevtyushkin");
 MODULE_LICENSE("GPL");
 
-
-#define I2C_NAME(x) (x)->name
-
-
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
-	do { \
-		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
-
 /* ----------------------------------------------------------------------- */
 
 struct adv7170 {
@@ -80,21 +61,12 @@ struct adv7170 {
 	int sat;
 };
 
-#define   I2C_ADV7170        0xd4
-#define   I2C_ADV7171        0x54
-
-static char adv7170_name[] = "adv7170";
-static char adv7171_name[] = "adv7171";
-
 static char *inputs[] = { "pass_through", "play_back" };
 static char *norms[] = { "PAL", "NTSC" };
 
 /* ----------------------------------------------------------------------- */
 
-static inline int
-adv7170_write (struct i2c_client *client,
-	       u8                 reg,
-	       u8                 value)
+static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value)
 {
 	struct adv7170 *encoder = i2c_get_clientdata(client);
 
@@ -102,17 +74,13 @@ adv7170_write (struct i2c_client *client,
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int
-adv7170_read (struct i2c_client *client,
-	      u8                 reg)
+static inline int adv7170_read(struct i2c_client *client, u8 reg)
 {
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int
-adv7170_write_block (struct i2c_client *client,
-		     const u8          *data,
-		     unsigned int       len)
+static int adv7170_write_block(struct i2c_client *client,
+		     const u8 *data, unsigned int len)
 {
 	int ret = -1;
 	u8 reg;
@@ -133,33 +101,25 @@ adv7170_write_block (struct i2c_client *client,
 				    encoder->reg[reg++] = data[1];
 				len -= 2;
 				data += 2;
-			} while (len >= 2 && data[0] == reg &&
-				 block_len < 32);
-			if ((ret = i2c_master_send(client, block_data,
-						   block_len)) < 0)
+			} while (len >= 2 && data[0] == reg && block_len < 32);
+			ret = i2c_master_send(client, block_data, block_len);
+			if (ret < 0)
 				break;
 		}
 	} else {
 		/* do some slow I2C emulation kind of thing */
 		while (len >= 2) {
 			reg = *data++;
-			if ((ret = adv7170_write(client, reg,
-						 *data++)) < 0)
+			ret = adv7170_write(client, reg, *data++);
+			if (ret < 0)
 				break;
 			len -= 2;
 		}
 	}
-
 	return ret;
 }
 
 /* ----------------------------------------------------------------------- */
-// Output filter:  S-Video  Composite
-
-#define MR050       0x11	//0x09
-#define MR060       0x14	//0x0c
-
-//---------------------------------------------------------------------------
 
 #define TR0MODE     0x4c
 #define TR0RST	    0x80
@@ -167,7 +127,6 @@ adv7170_write_block (struct i2c_client *client,
 #define TR1CAPT	    0x00
 #define TR1PLAY	    0x00
 
-
 static const unsigned char init_NTSC[] = {
 	0x00, 0x10,		// MR0
 	0x01, 0x20,		// MR1
@@ -227,15 +186,11 @@ static const unsigned char init_PAL[] = {
 };
 
 
-static int
-adv7170_command (struct i2c_client *client,
-		 unsigned int       cmd,
-		 void *             arg)
+static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
 	struct adv7170 *encoder = i2c_get_clientdata(client);
 
 	switch (cmd) {
-
 	case 0:
 #if 0
 		/* This is just for testing!!! */
@@ -254,18 +209,16 @@ adv7170_command (struct i2c_client *client,
 			     VIDEO_ENCODER_NTSC;
 		cap->inputs = 2;
 		cap->outputs = 1;
-	}
 		break;
+	}
 
 	case ENCODER_SET_NORM:
 	{
 		int iarg = *(int *) arg;
 
-		dprintk(1, KERN_DEBUG "%s_command: set norm %d",
-			I2C_NAME(client), iarg);
+		v4l_dbg(1, debug, client, "set norm %d\n", iarg);
 
 		switch (iarg) {
-
 		case VIDEO_MODE_NTSC:
 			adv7170_write_block(client, init_NTSC,
 					    sizeof(init_NTSC));
@@ -285,16 +238,13 @@ adv7170_command (struct i2c_client *client,
 			break;
 
 		default:
-			dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
-			       I2C_NAME(client), iarg);
+			v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
 			return -EINVAL;
-
 		}
-		dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
-			norms[iarg]);
+		v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
 		encoder->norm = iarg;
-	}
 		break;
+	}
 
 	case ENCODER_SET_INPUT:
 	{
@@ -304,19 +254,17 @@ adv7170_command (struct i2c_client *client,
 		 *iarg = 1: input is from ZR36060
 		 *iarg = 2: color bar */
 
-		dprintk(1, KERN_DEBUG "%s_command: set input from %s\n",
-			I2C_NAME(client),
+		v4l_dbg(1, debug, client, "set input from %s\n",
 			iarg == 0 ? "decoder" : "ZR36060");
 
 		switch (iarg) {
-
 		case 0:
 			adv7170_write(client, 0x01, 0x20);
 			adv7170_write(client, 0x08, TR1CAPT);	/* TR1 */
 			adv7170_write(client, 0x02, 0x0e);	// Enable genlock
 			adv7170_write(client, 0x07, TR0MODE | TR0RST);
 			adv7170_write(client, 0x07, TR0MODE);
-			//udelay(10);
+			/* udelay(10); */
 			break;
 
 		case 1:
@@ -325,20 +273,17 @@ adv7170_command (struct i2c_client *client,
 			adv7170_write(client, 0x02, 0x08);
 			adv7170_write(client, 0x07, TR0MODE | TR0RST);
 			adv7170_write(client, 0x07, TR0MODE);
-			//udelay(10);
+			/* udelay(10); */
 			break;
 
 		default:
-			dprintk(1, KERN_ERR "%s: illegal input: %d\n",
-				I2C_NAME(client), iarg);
+			v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
 			return -EINVAL;
-
 		}
-		dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
-			inputs[iarg]);
+		v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
 		encoder->input = iarg;
-	}
 		break;
+	}
 
 	case ENCODER_SET_OUTPUT:
 	{
@@ -348,16 +293,16 @@ adv7170_command (struct i2c_client *client,
 		if (*iarg != 0) {
 			return -EINVAL;
 		}
-	}
 		break;
+	}
 
 	case ENCODER_ENABLE_OUTPUT:
 	{
 		int *iarg = arg;
 
 		encoder->enable = !!*iarg;
-	}
 		break;
+	}
 
 	default:
 		return -EINVAL;
@@ -368,149 +313,67 @@ adv7170_command (struct i2c_client *client,
 
 /* ----------------------------------------------------------------------- */
 
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] =
-    { I2C_ADV7170 >> 1, (I2C_ADV7170 >> 1) + 1,
-	I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1,
+static unsigned short normal_i2c[] = {
+	0xd4 >> 1, 0xd6 >> 1,	/* adv7170 IDs */
+	0x54 >> 1, 0x56 >> 1,	/* adv7171 IDs */
 	I2C_CLIENT_END
 };
 
-static unsigned short ignore = I2C_CLIENT_END;
+I2C_CLIENT_INSMOD;
 
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.probe			= &ignore,
-	.ignore			= &ignore,
-};
-
-static struct i2c_driver i2c_driver_adv7170;
-
-static int
-adv7170_detect_client (struct i2c_adapter *adapter,
-		       int                 address,
-		       int                 kind)
+static int adv7170_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
-	int i;
-	struct i2c_client *client;
 	struct adv7170 *encoder;
-	char *dname;
-
-	dprintk(1,
-		KERN_INFO
-		"adv7170.c: detecting adv7170 client on address 0x%x\n",
-		address << 1);
+	int i;
 
 	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
 
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = &i2c_driver_adv7170;
-	if ((client->addr == I2C_ADV7170 >> 1) ||
-	    (client->addr == (I2C_ADV7170 >> 1) + 1)) {
-		dname = adv7170_name;
-	} else if ((client->addr == I2C_ADV7171 >> 1) ||
-		   (client->addr == (I2C_ADV7171 >> 1) + 1)) {
-		dname = adv7171_name;
-	} else {
-		/* We should never get here!!! */
-		kfree(client);
-		return 0;
-	}
-	strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
 	encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
-	if (encoder == NULL) {
-		kfree(client);
+	if (encoder == NULL)
 		return -ENOMEM;
-	}
 	encoder->norm = VIDEO_MODE_NTSC;
 	encoder->input = 0;
 	encoder->enable = 1;
 	i2c_set_clientdata(client, encoder);
 
-	i = i2c_attach_client(client);
-	if (i) {
-		kfree(client);
-		kfree(encoder);
-		return i;
-	}
-
 	i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
 	if (i >= 0) {
 		i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
 		i = adv7170_write(client, 0x07, TR0MODE);
 		i = adv7170_read(client, 0x12);
-		dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%02x\n",
-			I2C_NAME(client), i & 1, client->addr << 1);
-	}
-	if (i < 0) {
-		dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
-		       I2C_NAME(client), i);
+		v4l_dbg(1, debug, client, "revision %d\n", i & 1);
 	}
-
+	if (i < 0)
+		v4l_dbg(1, debug, client, "init error 0x%x\n", i);
 	return 0;
 }
 
-static int
-adv7170_attach_adapter (struct i2c_adapter *adapter)
-{
-	dprintk(1,
-		KERN_INFO
-		"adv7170.c: starting probe for adapter %s (0x%x)\n",
-		I2C_NAME(adapter), adapter->id);
-	return i2c_probe(adapter, &addr_data, &adv7170_detect_client);
-}
-
-static int
-adv7170_detach_client (struct i2c_client *client)
+static int adv7170_remove(struct i2c_client *client)
 {
-	struct adv7170 *encoder = i2c_get_clientdata(client);
-	int err;
-
-	err = i2c_detach_client(client);
-	if (err) {
-		return err;
-	}
-
-	kfree(encoder);
-	kfree(client);
-
+	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver i2c_driver_adv7170 = {
-	.driver = {
-		.name = "adv7170",	/* name */
-	},
-
-	.id = I2C_DRIVERID_ADV7170,
+static const struct i2c_device_id adv7170_id[] = {
+	{ "adv7170", 0 },
+	{ "adv7171", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adv7170_id);
 
-	.attach_adapter = adv7170_attach_adapter,
-	.detach_client = adv7170_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "adv7170",
+	.driverid = I2C_DRIVERID_ADV7170,
 	.command = adv7170_command,
+	.probe = adv7170_probe,
+	.remove = adv7170_remove,
+	.id_table = adv7170_id,
 };
-
-static int __init
-adv7170_init (void)
-{
-	return i2c_add_driver(&i2c_driver_adv7170);
-}
-
-static void __exit
-adv7170_exit (void)
-{
-	i2c_del_driver(&i2c_driver_adv7170);
-}
-
-module_init(adv7170_init);
-module_exit(adv7170_exit);

+ 60 - 183
drivers/media/video/adv7175.c

@@ -25,43 +25,24 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
 #include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
 #include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
 #include <linux/videodev.h>
 #include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
 
 MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
 MODULE_AUTHOR("Dave Perks");
 MODULE_LICENSE("GPL");
 
-
-#define I2C_NAME(s) (s)->name
-
-
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
-	do { \
-		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
-
 /* ----------------------------------------------------------------------- */
 
 struct adv7175 {
@@ -77,33 +58,23 @@ struct adv7175 {
 #define   I2C_ADV7175        0xd4
 #define   I2C_ADV7176        0x54
 
-static char adv7175_name[] = "adv7175";
-static char adv7176_name[] = "adv7176";
-
 static char *inputs[] = { "pass_through", "play_back", "color_bar" };
 static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
 
 /* ----------------------------------------------------------------------- */
 
-static inline int
-adv7175_write (struct i2c_client *client,
-	       u8                 reg,
-	       u8                 value)
+static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value)
 {
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int
-adv7175_read (struct i2c_client *client,
-	      u8                 reg)
+static inline int adv7175_read(struct i2c_client *client, u8 reg)
 {
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int
-adv7175_write_block (struct i2c_client *client,
-		     const u8          *data,
-		     unsigned int       len)
+static int adv7175_write_block(struct i2c_client *client,
+		     const u8 *data, unsigned int len)
 {
 	int ret = -1;
 	u8 reg;
@@ -123,18 +94,17 @@ adv7175_write_block (struct i2c_client *client,
 				reg++;
 				len -= 2;
 				data += 2;
-			} while (len >= 2 && data[0] == reg &&
-				 block_len < 32);
-			if ((ret = i2c_master_send(client, block_data,
-						   block_len)) < 0)
+			} while (len >= 2 && data[0] == reg && block_len < 32);
+			ret = i2c_master_send(client, block_data, block_len);
+			if (ret < 0)
 				break;
 		}
 	} else {
 		/* do some slow I2C emulation kind of thing */
 		while (len >= 2) {
 			reg = *data++;
-			if ((ret = adv7175_write(client, reg,
-						 *data++)) < 0)
+			ret = adv7175_write(client, reg, *data++);
+			if (ret < 0)
 				break;
 			len -= 2;
 		}
@@ -143,13 +113,11 @@ adv7175_write_block (struct i2c_client *client,
 	return ret;
 }
 
-static void
-set_subcarrier_freq (struct i2c_client *client,
-		     int                pass_through)
+static void set_subcarrier_freq(struct i2c_client *client, int pass_through)
 {
 	/* for some reason pass_through NTSC needs
 	 * a different sub-carrier freq to remain stable. */
-	if(pass_through)
+	if (pass_through)
 		adv7175_write(client, 0x02, 0x00);
 	else
 		adv7175_write(client, 0x02, 0x55);
@@ -160,12 +128,12 @@ set_subcarrier_freq (struct i2c_client *client,
 }
 
 /* ----------------------------------------------------------------------- */
-// Output filter:  S-Video  Composite
+/* Output filter:  S-Video  Composite */
 
-#define MR050       0x11	//0x09
-#define MR060       0x14	//0x0c
+#define MR050       0x11	/* 0x09 */
+#define MR060       0x14	/* 0x0c */
 
-//---------------------------------------------------------------------------
+/* ----------------------------------------------------------------------- */
 
 #define TR0MODE     0x46
 #define TR0RST	    0x80
@@ -216,15 +184,11 @@ static const unsigned char init_ntsc[] = {
 	0x06, 0x1a,		/* subc. phase */
 };
 
-static int
-adv7175_command (struct i2c_client *client,
-		 unsigned int       cmd,
-		 void              *arg)
+static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
 	struct adv7175 *encoder = i2c_get_clientdata(client);
 
 	switch (cmd) {
-
 	case 0:
 		/* This is just for testing!!! */
 		adv7175_write_block(client, init_common,
@@ -242,15 +206,14 @@ adv7175_command (struct i2c_client *client,
 			     VIDEO_ENCODER_SECAM; /* well, hacky */
 		cap->inputs = 2;
 		cap->outputs = 1;
-	}
 		break;
+	}
 
 	case ENCODER_SET_NORM:
 	{
 		int iarg = *(int *) arg;
 
 		switch (iarg) {
-
 		case VIDEO_MODE_NTSC:
 			adv7175_write_block(client, init_ntsc,
 					    sizeof(init_ntsc));
@@ -284,16 +247,13 @@ adv7175_command (struct i2c_client *client,
 			adv7175_write(client, 0x07, TR0MODE);
 			break;
 		default:
-			dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
-				I2C_NAME(client), iarg);
+			v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
 			return -EINVAL;
-
 		}
-		dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
-			norms[iarg]);
+		v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
 		encoder->norm = iarg;
-	}
 		break;
+	}
 
 	case ENCODER_SET_INPUT:
 	{
@@ -304,7 +264,6 @@ adv7175_command (struct i2c_client *client,
 		 *iarg = 2: color bar */
 
 		switch (iarg) {
-
 		case 0:
 			adv7175_write(client, 0x01, 0x00);
 
@@ -331,7 +290,7 @@ adv7175_command (struct i2c_client *client,
 			adv7175_write(client, 0x0d, 0x49);
 			adv7175_write(client, 0x07, TR0MODE | TR0RST);
 			adv7175_write(client, 0x07, TR0MODE);
-			//udelay(10);
+			/* udelay(10); */
 			break;
 
 		case 2:
@@ -343,39 +302,35 @@ adv7175_command (struct i2c_client *client,
 			adv7175_write(client, 0x0d, 0x49);
 			adv7175_write(client, 0x07, TR0MODE | TR0RST);
 			adv7175_write(client, 0x07, TR0MODE);
-			//udelay(10);
+			/* udelay(10); */
 			break;
 
 		default:
-			dprintk(1, KERN_ERR "%s: illegal input: %d\n",
-				I2C_NAME(client), iarg);
+			v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
 			return -EINVAL;
-
 		}
-		dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
-			inputs[iarg]);
+		v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
 		encoder->input = iarg;
-	}
 		break;
+	}
 
 	case ENCODER_SET_OUTPUT:
 	{
 		int *iarg = arg;
 
 		/* not much choice of outputs */
-		if (*iarg != 0) {
+		if (*iarg != 0)
 			return -EINVAL;
-		}
-	}
 		break;
+	}
 
 	case ENCODER_ENABLE_OUTPUT:
 	{
 		int *iarg = arg;
 
 		encoder->enable = !!*iarg;
-	}
 		break;
+	}
 
 	default:
 		return -EINVAL;
@@ -390,145 +345,67 @@ adv7175_command (struct i2c_client *client,
  * Generic i2c probe
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
-static unsigned short normal_i2c[] =
-    { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
+static unsigned short normal_i2c[] = {
+	I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
 	I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
 	I2C_CLIENT_END
 };
 
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.probe			= &ignore,
-	.ignore			= &ignore,
-};
-
-static struct i2c_driver i2c_driver_adv7175;
+I2C_CLIENT_INSMOD;
 
-static int
-adv7175_detect_client (struct i2c_adapter *adapter,
-		       int                 address,
-		       int                 kind)
+static int adv7175_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	int i;
-	struct i2c_client *client;
 	struct adv7175 *encoder;
-	char *dname;
-
-	dprintk(1,
-		KERN_INFO
-		"adv7175.c: detecting adv7175 client on address 0x%x\n",
-		address << 1);
 
 	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
 
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = &i2c_driver_adv7175;
-	if ((client->addr == I2C_ADV7175 >> 1) ||
-	    (client->addr == (I2C_ADV7175 >> 1) + 1)) {
-		dname = adv7175_name;
-	} else if ((client->addr == I2C_ADV7176 >> 1) ||
-		   (client->addr == (I2C_ADV7176 >> 1) + 1)) {
-		dname = adv7176_name;
-	} else {
-		/* We should never get here!!! */
-		kfree(client);
-		return 0;
-	}
-	strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
 	encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
-	if (encoder == NULL) {
-		kfree(client);
+	if (encoder == NULL)
 		return -ENOMEM;
-	}
 	encoder->norm = VIDEO_MODE_PAL;
 	encoder->input = 0;
 	encoder->enable = 1;
 	i2c_set_clientdata(client, encoder);
 
-	i = i2c_attach_client(client);
-	if (i) {
-		kfree(client);
-		kfree(encoder);
-		return i;
-	}
-
 	i = adv7175_write_block(client, init_common, sizeof(init_common));
 	if (i >= 0) {
 		i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
 		i = adv7175_write(client, 0x07, TR0MODE);
 		i = adv7175_read(client, 0x12);
-		dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n",
-			I2C_NAME(client), i & 1, client->addr << 1);
+		v4l_dbg(1, debug, client, "revision %d\n", i & 1);
 	}
-	if (i < 0) {
-		dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
-			I2C_NAME(client), i);
-	}
-
+	if (i < 0)
+		v4l_dbg(1, debug, client, "init error 0x%x\n", i);
 	return 0;
 }
 
-static int
-adv7175_attach_adapter (struct i2c_adapter *adapter)
-{
-	dprintk(1,
-		KERN_INFO
-		"adv7175.c: starting probe for adapter %s (0x%x)\n",
-		I2C_NAME(adapter), adapter->id);
-	return i2c_probe(adapter, &addr_data, &adv7175_detect_client);
-}
-
-static int
-adv7175_detach_client (struct i2c_client *client)
+static int adv7175_remove(struct i2c_client *client)
 {
-	struct adv7175 *encoder = i2c_get_clientdata(client);
-	int err;
-
-	err = i2c_detach_client(client);
-	if (err) {
-		return err;
-	}
-
-	kfree(encoder);
-	kfree(client);
-
+	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver i2c_driver_adv7175 = {
-	.driver = {
-		.name = "adv7175",	/* name */
-	},
-
-	.id = I2C_DRIVERID_ADV7175,
+static const struct i2c_device_id adv7175_id[] = {
+	{ "adv7175", 0 },
+	{ "adv7176", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adv7175_id);
 
-	.attach_adapter = adv7175_attach_adapter,
-	.detach_client = adv7175_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "adv7175",
+	.driverid = I2C_DRIVERID_ADV7175,
 	.command = adv7175_command,
+	.probe = adv7175_probe,
+	.remove = adv7175_remove,
+	.id_table = adv7175_id,
 };
-
-static int __init
-adv7175_init (void)
-{
-	return i2c_add_driver(&i2c_driver_adv7175);
-}
-
-static void __exit
-adv7175_exit (void)
-{
-	i2c_del_driver(&i2c_driver_adv7175);
-}
-
-module_init(adv7175_init);
-module_exit(adv7175_exit);

+ 4 - 1
drivers/media/video/au0828/au0828-cards.c

@@ -90,6 +90,7 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
 	case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
 	case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
 	case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */
+	case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
 	case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
 	case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
 		break;
@@ -185,7 +186,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
 }
 
 /* table of devices that work with this driver */
-struct usb_device_id au0828_usb_id_table [] = {
+struct usb_device_id au0828_usb_id_table[] = {
 	{ USB_DEVICE(0x2040, 0x7200),
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
 	{ USB_DEVICE(0x2040, 0x7240),
@@ -198,6 +199,8 @@ struct usb_device_id au0828_usb_id_table [] = {
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
 	{ USB_DEVICE(0x2040, 0x721b),
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+	{ USB_DEVICE(0x2040, 0x721e),
+		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
 	{ USB_DEVICE(0x2040, 0x721f),
 		.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
 	{ USB_DEVICE(0x2040, 0x7280),

+ 2 - 1
drivers/media/video/au0828/au0828-core.c

@@ -91,7 +91,8 @@ static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
 		status = usb_control_msg(dev->usbdev,
 				usb_sndctrlpipe(dev->usbdev, 0),
 				request,
-				USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				USB_DIR_OUT | USB_TYPE_VENDOR |
+					USB_RECIP_DEVICE,
 				value, index,
 				cp, size, 1000);
 

+ 2 - 1
drivers/media/video/au0828/au0828-dvb.c

@@ -173,7 +173,8 @@ static int start_urb_transfer(struct au0828_dev *dev)
 		purb->status = -EINPROGRESS;
 		usb_fill_bulk_urb(purb,
 				  dev->usbdev,
-				  usb_rcvbulkpipe(dev->usbdev, _AU0828_BULKPIPE),
+				  usb_rcvbulkpipe(dev->usbdev,
+					_AU0828_BULKPIPE),
 				  purb->transfer_buffer,
 				  URB_BUFSIZE,
 				  urb_completion,

+ 92 - 229
drivers/media/video/bt819.c

@@ -29,44 +29,25 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
 #include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
 #include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
 #include <linux/videodev.h>
 #include <linux/video_decoder.h>
-
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
 
 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
 MODULE_AUTHOR("Mike Bernson & Dave Perks");
 MODULE_LICENSE("GPL");
 
-
-#define I2C_NAME(s) (s)->name
-
-
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
-	do { \
-		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
-
 /* ----------------------------------------------------------------------- */
 
 struct bt819 {
@@ -97,14 +78,9 @@ static struct timing timing_data[] = {
 	{858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
 };
 
-#define   I2C_BT819        0x8a
-
 /* ----------------------------------------------------------------------- */
 
-static inline int
-bt819_write (struct i2c_client *client,
-	     u8                 reg,
-	     u8                 value)
+static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value)
 {
 	struct bt819 *decoder = i2c_get_clientdata(client);
 
@@ -112,24 +88,15 @@ bt819_write (struct i2c_client *client,
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int
-bt819_setbit (struct i2c_client *client,
-	      u8                 reg,
-	      u8                 bit,
-	      u8                 value)
+static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
 {
 	struct bt819 *decoder = i2c_get_clientdata(client);
 
 	return bt819_write(client, reg,
-			   (decoder->
-			    reg[reg] & ~(1 << bit)) |
-			    (value ? (1 << bit) : 0));
+		(decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
 }
 
-static int
-bt819_write_block (struct i2c_client *client,
-		   const u8          *data,
-		   unsigned int       len)
+static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
 {
 	int ret = -1;
 	u8 reg;
@@ -150,10 +117,9 @@ bt819_write_block (struct i2c_client *client,
 				    decoder->reg[reg++] = data[1];
 				len -= 2;
 				data += 2;
-			} while (len >= 2 && data[0] == reg &&
-				 block_len < 32);
-			if ((ret = i2c_master_send(client, block_data,
-						   block_len)) < 0)
+			} while (len >= 2 && data[0] == reg && block_len < 32);
+			ret = i2c_master_send(client, block_data, block_len);
+			if (ret < 0)
 				break;
 		}
 	} else {
@@ -169,20 +135,17 @@ bt819_write_block (struct i2c_client *client,
 	return ret;
 }
 
-static inline int
-bt819_read (struct i2c_client *client,
-	    u8                 reg)
+static inline int bt819_read(struct i2c_client *client, u8 reg)
 {
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int
-bt819_init (struct i2c_client *client)
+static int bt819_init(struct i2c_client *client)
 {
 	struct bt819 *decoder = i2c_get_clientdata(client);
 
 	static unsigned char init[] = {
-		//0x1f, 0x00,     /* Reset */
+		/*0x1f, 0x00,*/     /* Reset */
 		0x01, 0x59,	/* 0x01 input format */
 		0x02, 0x00,	/* 0x02 temporal decimation */
 		0x03, 0x12,	/* 0x03 Cropping msb */
@@ -218,12 +181,10 @@ bt819_init (struct i2c_client *client)
 	struct timing *timing = &timing_data[decoder->norm];
 
 	init[0x03 * 2 - 1] =
-	    (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
-						       vactive >> 8) &
-						      0x03) << 4) |
-	    (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
-						      hactive >> 8) &
-						     0x03);
+	    (((timing->vdelay >> 8) & 0x03) << 6) |
+	    (((timing->vactive >> 8) & 0x03) << 4) |
+	    (((timing->hdelay >> 8) & 0x03) << 2) |
+	    ((timing->hactive >> 8) & 0x03);
 	init[0x04 * 2 - 1] = timing->vdelay & 0xff;
 	init[0x05 * 2 - 1] = timing->vactive & 0xff;
 	init[0x06 * 2 - 1] = timing->hdelay & 0xff;
@@ -238,27 +199,22 @@ bt819_init (struct i2c_client *client)
 
 	/* init */
 	return bt819_write_block(client, init, sizeof(init));
-
 }
 
 /* ----------------------------------------------------------------------- */
 
-static int
-bt819_command (struct i2c_client *client,
-	       unsigned int       cmd,
-	       void              *arg)
+static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
 	int temp;
 
 	struct bt819 *decoder = i2c_get_clientdata(client);
 
-	if (!decoder->initialized) {	// First call to bt819_init could be
-		bt819_init(client);	// without #FRST = 0
+	if (!decoder->initialized) {	/* First call to bt819_init could be */
+		bt819_init(client);	/* without #FRST = 0 */
 		decoder->initialized = 1;
 	}
 
 	switch (cmd) {
-
 	case 0:
 		/* This is just for testing!!! */
 		bt819_init(client);
@@ -274,8 +230,8 @@ bt819_command (struct i2c_client *client,
 			     VIDEO_DECODER_CCIR;
 		cap->inputs = 8;
 		cap->outputs = 1;
-	}
 		break;
+	}
 
 	case DECODER_GET_STATUS:
 	{
@@ -285,9 +241,9 @@ bt819_command (struct i2c_client *client,
 
 		status = bt819_read(client, 0x00);
 		res = 0;
-		if ((status & 0x80)) {
+		if ((status & 0x80))
 			res |= DECODER_STATUS_GOOD;
-		}
+
 		switch (decoder->norm) {
 		case VIDEO_MODE_NTSC:
 			res |= DECODER_STATUS_NTSC;
@@ -297,28 +253,25 @@ bt819_command (struct i2c_client *client,
 			break;
 		default:
 		case VIDEO_MODE_AUTO:
-			if ((status & 0x10)) {
+			if ((status & 0x10))
 				res |= DECODER_STATUS_PAL;
-			} else {
+			else
 				res |= DECODER_STATUS_NTSC;
-			}
 			break;
 		}
 		res |= DECODER_STATUS_COLOR;
 		*iarg = res;
 
-		dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
-			*iarg);
-	}
+		v4l_dbg(1, debug, client, "get status %x\n", *iarg);
 		break;
+	}
 
 	case DECODER_SET_NORM:
 	{
 		int *iarg = arg;
 		struct timing *timing = NULL;
 
-		dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
-			*iarg);
+		v4l_dbg(1, debug, client, "set norm %x\n", *iarg);
 
 		switch (*iarg) {
 		case VIDEO_MODE_NTSC:
@@ -327,7 +280,7 @@ bt819_command (struct i2c_client *client,
 			bt819_setbit(client, 0x01, 5, 0);
 			bt819_write(client, 0x18, 0x68);
 			bt819_write(client, 0x19, 0x5d);
-			//bt819_setbit(client, 0x1a,  5, 1);
+			/* bt819_setbit(client, 0x1a,  5, 1); */
 			timing = &timing_data[VIDEO_MODE_NTSC];
 			break;
 		case VIDEO_MODE_PAL:
@@ -336,7 +289,7 @@ bt819_command (struct i2c_client *client,
 			bt819_setbit(client, 0x01, 5, 1);
 			bt819_write(client, 0x18, 0x7f);
 			bt819_write(client, 0x19, 0x72);
-			//bt819_setbit(client, 0x1a,  5, 0);
+			/* bt819_setbit(client, 0x1a,  5, 0); */
 			timing = &timing_data[VIDEO_MODE_PAL];
 			break;
 		case VIDEO_MODE_AUTO:
@@ -344,10 +297,7 @@ bt819_command (struct i2c_client *client,
 			bt819_setbit(client, 0x01, 1, 0);
 			break;
 		default:
-			dprintk(1,
-				KERN_ERR
-				"%s: unsupported norm %d\n",
-				I2C_NAME(client), *iarg);
+			v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg);
 			return -EINVAL;
 		}
 
@@ -366,19 +316,17 @@ bt819_command (struct i2c_client *client,
 		}
 
 		decoder->norm = *iarg;
-	}
 		break;
+	}
 
 	case DECODER_SET_INPUT:
 	{
 		int *iarg = arg;
 
-		dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
-			*iarg);
+		v4l_dbg(1, debug, client, "set input %x\n", *iarg);
 
-		if (*iarg < 0 || *iarg > 7) {
+		if (*iarg < 0 || *iarg > 7)
 			return -EINVAL;
-		}
 
 		if (decoder->input != *iarg) {
 			decoder->input = *iarg;
@@ -391,52 +339,42 @@ bt819_command (struct i2c_client *client,
 				bt819_setbit(client, 0x1a, 1, 0);
 			}
 		}
-	}
 		break;
+	}
 
 	case DECODER_SET_OUTPUT:
 	{
 		int *iarg = arg;
 
-		dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
-			*iarg);
+		v4l_dbg(1, debug, client, "set output %x\n", *iarg);
 
 		/* not much choice of outputs */
-		if (*iarg != 0) {
+		if (*iarg != 0)
 			return -EINVAL;
-		}
-	}
 		break;
+	}
 
 	case DECODER_ENABLE_OUTPUT:
 	{
 		int *iarg = arg;
 		int enable = (*iarg != 0);
 
-		dprintk(1, KERN_INFO "%s: enable output %x\n",
-			I2C_NAME(client), *iarg);
+		v4l_dbg(1, debug, client, "enable output %x\n", *iarg);
 
 		if (decoder->enable != enable) {
 			decoder->enable = enable;
-
-			if (decoder->enable) {
-				bt819_setbit(client, 0x16, 7, 0);
-			} else {
-				bt819_setbit(client, 0x16, 7, 1);
-			}
+			bt819_setbit(client, 0x16, 7, !enable);
 		}
-	}
 		break;
+	}
 
 	case DECODER_SET_PICTURE:
 	{
 		struct video_picture *pic = arg;
 
-		dprintk(1,
-			KERN_INFO
-			"%s: set picture brightness %d contrast %d colour %d\n",
-			I2C_NAME(client), pic->brightness, pic->contrast,
-			pic->colour);
+		v4l_dbg(1, debug, client,
+			"set picture brightness %d contrast %d colour %d\n",
+			pic->brightness, pic->contrast, pic->colour);
 
 
 		if (decoder->bright != pic->brightness) {
@@ -474,8 +412,8 @@ bt819_command (struct i2c_client *client,
 			bt819_write(client, 0x0f,
 				    128 - (decoder->hue >> 8));
 		}
-	}
 		break;
+	}
 
 	default:
 		return -EINVAL;
@@ -486,55 +424,44 @@ bt819_command (struct i2c_client *client,
 
 /* ----------------------------------------------------------------------- */
 
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = {
-	I2C_BT819 >> 1,
-	I2C_CLIENT_END,
-};
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.probe			= &ignore,
-	.ignore			= &ignore,
-};
+static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END };
 
-static struct i2c_driver i2c_driver_bt819;
+I2C_CLIENT_INSMOD;
 
-static int
-bt819_detect_client (struct i2c_adapter *adapter,
-		     int                 address,
-		     int                 kind)
+static int bt819_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
-	int i, id;
+	int i, ver;
 	struct bt819 *decoder;
-	struct i2c_client *client;
-
-	dprintk(1,
-		KERN_INFO
-		"bt819: detecting bt819 client on address 0x%x\n",
-		address << 1);
+	const char *name;
 
 	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
 
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = &i2c_driver_bt819;
+	ver = bt819_read(client, 0x17);
+	switch (ver & 0xf0) {
+	case 0x70:
+		name = "bt819a";
+		break;
+	case 0x60:
+		name = "bt817a";
+		break;
+	case 0x20:
+		name = "bt815a";
+		break;
+	default:
+		v4l_dbg(1, debug, client,
+			"unknown chip version 0x%02x\n", ver);
+		return -ENODEV;
+	}
+
+	v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+			client->addr << 1, client->adapter->name);
 
 	decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
-	if (decoder == NULL) {
-		kfree(client);
+	if (decoder == NULL)
 		return -ENOMEM;
-	}
 	decoder->norm = VIDEO_MODE_NTSC;
 	decoder->input = 0;
 	decoder->enable = 1;
@@ -545,97 +472,33 @@ bt819_detect_client (struct i2c_adapter *adapter,
 	decoder->initialized = 0;
 	i2c_set_clientdata(client, decoder);
 
-	id = bt819_read(client, 0x17);
-	switch (id & 0xf0) {
-	case 0x70:
-		strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
-		break;
-	case 0x60:
-		strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
-		break;
-	case 0x20:
-		strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
-		break;
-	default:
-		dprintk(1,
-			KERN_ERR
-			"bt819: unknown chip version 0x%x (ver 0x%x)\n",
-			id & 0xf0, id & 0x0f);
-		kfree(decoder);
-		kfree(client);
-		return 0;
-	}
-
-	i = i2c_attach_client(client);
-	if (i) {
-		kfree(client);
-		kfree(decoder);
-		return i;
-	}
-
 	i = bt819_init(client);
-	if (i < 0) {
-		dprintk(1, KERN_ERR "%s_attach: init status %d\n",
-			I2C_NAME(client), i);
-	} else {
-		dprintk(1,
-			KERN_INFO
-			"%s_attach: chip version 0x%x at address 0x%x\n",
-			I2C_NAME(client), id & 0x0f,
-			client->addr << 1);
-	}
-
+	if (i < 0)
+		v4l_dbg(1, debug, client, "init status %d\n", i);
 	return 0;
 }
 
-static int
-bt819_attach_adapter (struct i2c_adapter *adapter)
-{
-	return i2c_probe(adapter, &addr_data, &bt819_detect_client);
-}
-
-static int
-bt819_detach_client (struct i2c_client *client)
+static int bt819_remove(struct i2c_client *client)
 {
-	struct bt819 *decoder = i2c_get_clientdata(client);
-	int err;
-
-	err = i2c_detach_client(client);
-	if (err) {
-		return err;
-	}
-
-	kfree(decoder);
-	kfree(client);
-
+	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver i2c_driver_bt819 = {
-	.driver = {
-		.name = "bt819",
-	},
-
-	.id = I2C_DRIVERID_BT819,
+static const struct i2c_device_id bt819_id[] = {
+	{ "bt819a", 0 },
+	{ "bt817a", 0 },
+	{ "bt815a", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bt819_id);
 
-	.attach_adapter = bt819_attach_adapter,
-	.detach_client = bt819_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "bt819",
+	.driverid = I2C_DRIVERID_BT819,
 	.command = bt819_command,
+	.probe = bt819_probe,
+	.remove = bt819_remove,
+	.id_table = bt819_id,
 };
-
-static int __init
-bt819_init_module (void)
-{
-	return i2c_add_driver(&i2c_driver_bt819);
-}
-
-static void __exit
-bt819_exit (void)
-{
-	i2c_del_driver(&i2c_driver_bt819);
-}
-
-module_init(bt819_init_module);
-module_exit(bt819_exit);

+ 49 - 169
drivers/media/video/bt856.c

@@ -29,43 +29,24 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
 #include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/video_encoder.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
 #include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
 #include <linux/videodev.h>
+#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
 
 MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
 MODULE_AUTHOR("Mike Bernson & Dave Perks");
 MODULE_LICENSE("GPL");
 
-
-#define I2C_NAME(s) (s)->name
-
-
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
-	do { \
-		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
-
 /* ----------------------------------------------------------------------- */
 
 #define BT856_REG_OFFSET	0xDA
@@ -78,14 +59,9 @@ struct bt856 {
 	int enable;
 };
 
-#define   I2C_BT856        0x88
-
 /* ----------------------------------------------------------------------- */
 
-static inline int
-bt856_write (struct i2c_client *client,
-	     u8                 reg,
-	     u8                 value)
+static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value)
 {
 	struct bt856 *encoder = i2c_get_clientdata(client);
 
@@ -93,46 +69,36 @@ bt856_write (struct i2c_client *client,
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int
-bt856_setbit (struct i2c_client *client,
-	      u8                 reg,
-	      u8                 bit,
-	      u8                 value)
+static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
 {
 	struct bt856 *encoder = i2c_get_clientdata(client);
 
 	return bt856_write(client, reg,
-			   (encoder->
-			    reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
-			    (value ? (1 << bit) : 0));
+		(encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
+				(value ? (1 << bit) : 0));
 }
 
-static void
-bt856_dump (struct i2c_client *client)
+static void bt856_dump(struct i2c_client *client)
 {
 	int i;
 	struct bt856 *encoder = i2c_get_clientdata(client);
 
-	printk(KERN_INFO "%s: register dump:", I2C_NAME(client));
+	v4l_info(client, "register dump:\n");
 	for (i = 0; i < BT856_NR_REG; i += 2)
-		printk(" %02x", encoder->reg[i]);
-	printk("\n");
+		printk(KERN_CONT " %02x", encoder->reg[i]);
+	printk(KERN_CONT "\n");
 }
 
 /* ----------------------------------------------------------------------- */
 
-static int
-bt856_command (struct i2c_client *client,
-	       unsigned int       cmd,
-	       void              *arg)
+static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
 	struct bt856 *encoder = i2c_get_clientdata(client);
 
 	switch (cmd) {
-
 	case 0:
 		/* This is just for testing!!! */
-		dprintk(1, KERN_INFO "bt856: init\n");
+		v4l_dbg(1, debug, client, "init\n");
 		bt856_write(client, 0xdc, 0x18);
 		bt856_write(client, 0xda, 0);
 		bt856_write(client, 0xde, 0);
@@ -142,7 +108,6 @@ bt856_command (struct i2c_client *client,
 		bt856_setbit(client, 0xdc, 4, 1);
 
 		switch (encoder->norm) {
-
 		case VIDEO_MODE_NTSC:
 			bt856_setbit(client, 0xdc, 2, 0);
 			break;
@@ -163,26 +128,23 @@ bt856_command (struct i2c_client *client,
 	{
 		struct video_encoder_capability *cap = arg;
 
-		dprintk(1, KERN_INFO "%s: get capabilities\n",
-			I2C_NAME(client));
+		v4l_dbg(1, debug, client, "get capabilities\n");
 
 		cap->flags = VIDEO_ENCODER_PAL |
 			     VIDEO_ENCODER_NTSC |
 			     VIDEO_ENCODER_CCIR;
 		cap->inputs = 2;
 		cap->outputs = 1;
-	}
 		break;
+	}
 
 	case ENCODER_SET_NORM:
 	{
 		int *iarg = arg;
 
-		dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client),
-			*iarg);
+		v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
 
 		switch (*iarg) {
-
 		case VIDEO_MODE_NTSC:
 			bt856_setbit(client, 0xdc, 2, 0);
 			break;
@@ -195,27 +157,23 @@ bt856_command (struct i2c_client *client,
 
 		default:
 			return -EINVAL;
-
 		}
 		encoder->norm = *iarg;
 		if (debug != 0)
 			bt856_dump(client);
-	}
 		break;
+	}
 
 	case ENCODER_SET_INPUT:
 	{
 		int *iarg = arg;
 
-		dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client),
-			*iarg);
+		v4l_dbg(1, debug, client, "set input %d\n", *iarg);
 
 		/* We only have video bus.
 		 * iarg = 0: input is from bt819
 		 * iarg = 1: input is from ZR36060 */
-
 		switch (*iarg) {
-
 		case 0:
 			bt856_setbit(client, 0xde, 4, 0);
 			bt856_setbit(client, 0xde, 3, 1);
@@ -234,27 +192,24 @@ bt856_command (struct i2c_client *client,
 			break;
 		default:
 			return -EINVAL;
-
 		}
 
 		if (debug != 0)
 			bt856_dump(client);
-	}
 		break;
+	}
 
 	case ENCODER_SET_OUTPUT:
 	{
 		int *iarg = arg;
 
-		dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client),
-			*iarg);
+		v4l_dbg(1, debug, client, "set output %d\n", *iarg);
 
 		/* not much choice of outputs */
-		if (*iarg != 0) {
+		if (*iarg != 0)
 			return -EINVAL;
-		}
-	}
 		break;
+	}
 
 	case ENCODER_ENABLE_OUTPUT:
 	{
@@ -262,10 +217,9 @@ bt856_command (struct i2c_client *client,
 
 		encoder->enable = !!*iarg;
 
-		dprintk(1, KERN_INFO "%s: enable output %d\n",
-			I2C_NAME(client), encoder->enable);
-	}
+		v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
 		break;
+	}
 
 	default:
 		return -EINVAL;
@@ -276,64 +230,29 @@ bt856_command (struct i2c_client *client,
 
 /* ----------------------------------------------------------------------- */
 
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.probe			= &ignore,
-	.ignore			= &ignore,
-};
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
 
-static struct i2c_driver i2c_driver_bt856;
+I2C_CLIENT_INSMOD;
 
-static int
-bt856_detect_client (struct i2c_adapter *adapter,
-		     int                 address,
-		     int                 kind)
+static int bt856_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
-	int i;
-	struct i2c_client *client;
 	struct bt856 *encoder;
 
-	dprintk(1,
-		KERN_INFO
-		"bt856.c: detecting bt856 client on address 0x%x\n",
-		address << 1);
-
 	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
 
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = &i2c_driver_bt856;
-	strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
 	encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
-	if (encoder == NULL) {
-		kfree(client);
+	if (encoder == NULL)
 		return -ENOMEM;
-	}
 	encoder->norm = VIDEO_MODE_NTSC;
 	encoder->enable = 1;
 	i2c_set_clientdata(client, encoder);
 
-	i = i2c_attach_client(client);
-	if (i) {
-		kfree(client);
-		kfree(encoder);
-		return i;
-	}
-
 	bt856_write(client, 0xdc, 0x18);
 	bt856_write(client, 0xda, 0);
 	bt856_write(client, 0xde, 0);
@@ -359,65 +278,26 @@ bt856_detect_client (struct i2c_adapter *adapter,
 
 	if (debug != 0)
 		bt856_dump(client);
-
-	dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client),
-		client->addr << 1);
-
 	return 0;
 }
 
-static int
-bt856_attach_adapter (struct i2c_adapter *adapter)
+static int bt856_remove(struct i2c_client *client)
 {
-	dprintk(1,
-		KERN_INFO
-		"bt856.c: starting probe for adapter %s (0x%x)\n",
-		I2C_NAME(adapter), adapter->id);
-	return i2c_probe(adapter, &addr_data, &bt856_detect_client);
-}
-
-static int
-bt856_detach_client (struct i2c_client *client)
-{
-	struct bt856 *encoder = i2c_get_clientdata(client);
-	int err;
-
-	err = i2c_detach_client(client);
-	if (err) {
-		return err;
-	}
-
-	kfree(encoder);
-	kfree(client);
-
+	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_driver i2c_driver_bt856 = {
-	.driver = {
-		.name = "bt856",
-	},
-
-	.id = I2C_DRIVERID_BT856,
+static const struct i2c_device_id bt856_id[] = {
+	{ "bt856", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bt856_id);
 
-	.attach_adapter = bt856_attach_adapter,
-	.detach_client = bt856_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "bt856",
+	.driverid = I2C_DRIVERID_BT856,
 	.command = bt856_command,
+	.probe = bt856_probe,
+	.remove = bt856_remove,
+	.id_table = bt856_id,
 };
-
-static int __init
-bt856_init (void)
-{
-	return i2c_add_driver(&i2c_driver_bt856);
-}
-
-static void __exit
-bt856_exit (void)
-{
-	i2c_del_driver(&i2c_driver_bt856);
-}
-
-module_init(bt856_init);
-module_exit(bt856_exit);

+ 83 - 172
drivers/media/video/bt866.c

@@ -29,42 +29,28 @@
 */
 
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
 #include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
 #include <linux/i2c.h>
-
+#include <linux/i2c-id.h>
 #include <linux/videodev.h>
-#include <asm/uaccess.h>
-
 #include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
 
+MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
+MODULE_AUTHOR("Mike Bernson & Dave Perks");
 MODULE_LICENSE("GPL");
 
-#define	BT866_DEVNAME	"bt866"
-#define I2C_BT866	0x88
-
-MODULE_LICENSE("GPL");
-
-#define DEBUG(x)		/* Debug driver */
+static int debug;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 /* ----------------------------------------------------------------------- */
 
 struct bt866 {
-	struct i2c_client *i2c;
-	int addr;
-	unsigned char reg[256];
+	u8 reg[256];
 
 	int norm;
 	int enable;
@@ -74,20 +60,45 @@ struct bt866 {
 	int sat;
 };
 
-static int bt866_write(struct bt866 *dev,
-			unsigned char subaddr, unsigned char data);
+static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
+{
+	struct bt866 *encoder = i2c_get_clientdata(client);
+	u8 buffer[2];
+	int err;
+
+	buffer[0] = subaddr;
+	buffer[1] = data;
+
+	encoder->reg[subaddr] = data;
+
+	v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);
+
+	for (err = 0; err < 3;) {
+		if (i2c_master_send(client, buffer, 2) == 2)
+			break;
+		err++;
+		v4l_warn(client, "error #%d writing to 0x%02x\n",
+				err, subaddr);
+		schedule_timeout_interruptible(msecs_to_jiffies(100));
+	}
+	if (err == 3) {
+		v4l_warn(client, "giving up\n");
+		return -1;
+	}
+
+	return 0;
+}
 
-static int bt866_do_command(struct bt866 *encoder,
-			unsigned int cmd, void *arg)
+static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
+	struct bt866 *encoder = i2c_get_clientdata(client);
+
 	switch (cmd) {
 	case ENCODER_GET_CAPABILITIES:
 	{
 		struct video_encoder_capability *cap = arg;
 
-		DEBUG(printk
-		      (KERN_INFO "%s: get capabilities\n",
-		       encoder->i2c->name));
+		v4l_dbg(1, debug, client, "get capabilities\n");
 
 		cap->flags
 			= VIDEO_ENCODER_PAL
@@ -95,18 +106,16 @@ static int bt866_do_command(struct bt866 *encoder,
 			| VIDEO_ENCODER_CCIR;
 		cap->inputs = 2;
 		cap->outputs = 1;
+		break;
 	}
-	break;
 
 	case ENCODER_SET_NORM:
 	{
 		int *iarg = arg;
 
-		DEBUG(printk(KERN_INFO "%s: set norm %d\n",
-			     encoder->i2c->name, *iarg));
+		v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
 
 		switch (*iarg) {
-
 		case VIDEO_MODE_NTSC:
 			break;
 
@@ -115,11 +124,10 @@ static int bt866_do_command(struct bt866 *encoder,
 
 		default:
 			return -EINVAL;
-
 		}
 		encoder->norm = *iarg;
+		break;
 	}
-	break;
 
 	case ENCODER_SET_INPUT:
 	{
@@ -155,7 +163,7 @@ static int bt866_do_command(struct bt866 *encoder,
 		u8 val;
 
 		for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
-			bt866_write(encoder, init[i], init[i+1]);
+			bt866_write(client, init[i], init[i+1]);
 
 		val = encoder->reg[0xdc];
 
@@ -164,17 +172,16 @@ static int bt866_do_command(struct bt866 *encoder,
 		else
 			val &= ~0x40; /* !CBSWAP */
 
-		bt866_write(encoder, 0xdc, val);
+		bt866_write(client, 0xdc, val);
 
 		val = encoder->reg[0xcc];
 		if (*iarg == 2)
 			val |= 0x01; /* OSDBAR */
 		else
 			val &= ~0x01; /* !OSDBAR */
-		bt866_write(encoder, 0xcc, val);
+		bt866_write(client, 0xcc, val);
 
-		DEBUG(printk(KERN_INFO "%s: set input %d\n",
-			     encoder->i2c->name, *iarg));
+		v4l_dbg(1, debug, client, "set input %d\n", *iarg);
 
 		switch (*iarg) {
 		case 0:
@@ -183,48 +190,44 @@ static int bt866_do_command(struct bt866 *encoder,
 			break;
 		default:
 			return -EINVAL;
-
 		}
+		break;
 	}
-	break;
 
 	case ENCODER_SET_OUTPUT:
 	{
 		int *iarg = arg;
 
-		DEBUG(printk(KERN_INFO "%s: set output %d\n",
-			     encoder->i2c->name, *iarg));
+		v4l_dbg(1, debug, client, "set output %d\n", *iarg);
 
 		/* not much choice of outputs */
 		if (*iarg != 0)
 			return -EINVAL;
+		break;
 	}
-	break;
 
 	case ENCODER_ENABLE_OUTPUT:
 	{
 		int *iarg = arg;
 		encoder->enable = !!*iarg;
 
-		DEBUG(printk
-		      (KERN_INFO "%s: enable output %d\n",
-		       encoder->i2c->name, encoder->enable));
+		v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
+		break;
 	}
-	break;
 
 	case 4711:
 	{
 		int *iarg = arg;
 		__u8 val;
 
-		printk("bt866: square = %d\n", *iarg);
+		v4l_dbg(1, debug, client, "square %d\n", *iarg);
 
 		val = encoder->reg[0xdc];
 		if (*iarg)
 			val |= 1; /* SQUARE */
 		else
 			val &= ~1; /* !SQUARE */
-		bt866_write(encoder, 0xdc, val);
+		bt866_write(client, 0xdc, val);
 		break;
 	}
 
@@ -235,141 +238,49 @@ static int bt866_do_command(struct bt866 *encoder,
 	return 0;
 }
 
-static int bt866_write(struct bt866 *encoder,
-			unsigned char subaddr, unsigned char data)
-{
-	unsigned char buffer[2];
-	int err;
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
 
-	buffer[0] = subaddr;
-	buffer[1] = data;
-
-	encoder->reg[subaddr] = data;
+I2C_CLIENT_INSMOD;
 
-	DEBUG(printk
-	      ("%s: write 0x%02X = 0x%02X\n",
-	       encoder->i2c->name, subaddr, data));
-
-	for (err = 0; err < 3;) {
-		if (i2c_master_send(encoder->i2c, buffer, 2) == 2)
-			break;
-		err++;
-		printk(KERN_WARNING "%s: I/O error #%d "
-		       "(write 0x%02x/0x%02x)\n",
-		       encoder->i2c->name, err, encoder->addr, subaddr);
-		schedule_timeout_interruptible(msecs_to_jiffies(100));
-	}
-	if (err == 3) {
-		printk(KERN_WARNING "%s: giving up\n",
-		       encoder->i2c->name);
-		return -1;
-	}
-
-	return 0;
-}
-
-static int bt866_attach(struct i2c_adapter *adapter);
-static int bt866_detach(struct i2c_client *client);
-static int bt866_command(struct i2c_client *client,
-			 unsigned int cmd, void *arg);
-
-
-/* Addresses to scan */
-static unsigned short normal_i2c[]	= {I2C_BT866>>1, I2C_CLIENT_END};
-static unsigned short probe[2]		= {I2C_CLIENT_END, I2C_CLIENT_END};
-static unsigned short ignore[2]		= {I2C_CLIENT_END, I2C_CLIENT_END};
-
-static struct i2c_client_address_data addr_data = {
-	normal_i2c,
-	probe,
-	ignore,
-};
-
-static struct i2c_driver i2c_driver_bt866 = {
-	.driver.name = BT866_DEVNAME,
-	.id = I2C_DRIVERID_BT866,
-	.attach_adapter = bt866_attach,
-	.detach_client = bt866_detach,
-	.command = bt866_command
-};
-
-
-static struct i2c_client bt866_client_tmpl =
-{
-	.name = "(nil)",
-	.addr = 0,
-	.adapter = NULL,
-	.driver = &i2c_driver_bt866,
-};
-
-static int bt866_found_proc(struct i2c_adapter *adapter,
-			    int addr, int kind)
+static int bt866_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	struct bt866 *encoder;
-	struct i2c_client *client;
 
-	client = kzalloc(sizeof(*client), GFP_KERNEL);
-	if (client == NULL)
-		return -ENOMEM;
-	memcpy(client, &bt866_client_tmpl, sizeof(*client));
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
 	encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
-	if (encoder == NULL) {
-		kfree(client);
+	if (encoder == NULL)
 		return -ENOMEM;
-	}
 
 	i2c_set_clientdata(client, encoder);
-	client->adapter = adapter;
-	client->addr = addr;
-	sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
-
-	encoder->i2c = client;
-	encoder->addr = addr;
-	//encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
-
-	/* initialize */
-
-	i2c_attach_client(client);
-
-	return 0;
-}
-
-static int bt866_attach(struct i2c_adapter *adapter)
-{
-	if (adapter->id == I2C_HW_B_ZR36067)
-		return i2c_probe(adapter, &addr_data, bt866_found_proc);
-	return 0;
-}
-
-static int bt866_detach(struct i2c_client *client)
-{
-	struct bt866 *encoder = i2c_get_clientdata(client);
-
-	i2c_detach_client(client);
-	kfree(encoder);
-	kfree(client);
-
 	return 0;
 }
 
-static int bt866_command(struct i2c_client *client,
-			 unsigned int cmd, void *arg)
+static int bt866_remove(struct i2c_client *client)
 {
-	struct bt866 *encoder = i2c_get_clientdata(client);
-	return bt866_do_command(encoder, cmd, arg);
-}
-
-static int __devinit bt866_init(void)
-{
-	i2c_add_driver(&i2c_driver_bt866);
+	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
-static void __devexit bt866_exit(void)
+static int bt866_legacy_probe(struct i2c_adapter *adapter)
 {
-	i2c_del_driver(&i2c_driver_bt866);
+	return adapter->id == I2C_HW_B_ZR36067;
 }
 
-module_init(bt866_init);
-module_exit(bt866_exit);
+static const struct i2c_device_id bt866_id[] = {
+	{ "bt866", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bt866_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "bt866",
+	.driverid = I2C_DRIVERID_BT866,
+	.command = bt866_command,
+	.probe = bt866_probe,
+	.remove = bt866_remove,
+	.legacy_probe = bt866_legacy_probe,
+	.id_table = bt866_id,
+};

+ 89 - 63
drivers/media/video/cx23885/cx23885-cards.c

@@ -39,16 +39,16 @@ struct cx23885_board cx23885_boards[] = {
 		.input          = {{
 			.type   = CX23885_VMUX_COMPOSITE1,
 			.vmux   = 0,
-		},{
+		}, {
 			.type   = CX23885_VMUX_COMPOSITE2,
 			.vmux   = 1,
-		},{
+		}, {
 			.type   = CX23885_VMUX_COMPOSITE3,
 			.vmux   = 2,
-		},{
+		}, {
 			.type   = CX23885_VMUX_COMPOSITE4,
 			.vmux   = 3,
-		}},
+		} },
 	},
 	[CX23885_BOARD_HAUPPAUGE_HVR1800lp] = {
 		.name		= "Hauppauge WinTV-HVR1800lp",
@@ -57,19 +57,19 @@ struct cx23885_board cx23885_boards[] = {
 			.type   = CX23885_VMUX_TELEVISION,
 			.vmux   = 0,
 			.gpio0  = 0xff00,
-		},{
+		}, {
 			.type   = CX23885_VMUX_DEBUG,
 			.vmux   = 0,
 			.gpio0  = 0xff01,
-		},{
+		}, {
 			.type   = CX23885_VMUX_COMPOSITE1,
 			.vmux   = 1,
 			.gpio0  = 0xff02,
-		},{
+		}, {
 			.type   = CX23885_VMUX_SVIDEO,
 			.vmux   = 2,
 			.gpio0  = 0xff02,
-		}},
+		} },
 	},
 	[CX23885_BOARD_HAUPPAUGE_HVR1800] = {
 		.name		= "Hauppauge WinTV-HVR1800",
@@ -84,20 +84,20 @@ struct cx23885_board cx23885_boards[] = {
 					CX25840_VIN5_CH2 |
 					CX25840_VIN2_CH1,
 			.gpio0  = 0,
-		},{
+		}, {
 			.type   = CX23885_VMUX_COMPOSITE1,
 			.vmux   =	CX25840_VIN7_CH3 |
 					CX25840_VIN4_CH2 |
 					CX25840_VIN6_CH1,
 			.gpio0  = 0,
-		},{
+		}, {
 			.type   = CX23885_VMUX_SVIDEO,
 			.vmux   =	CX25840_VIN7_CH3 |
 					CX25840_VIN4_CH2 |
 					CX25840_VIN8_CH1 |
 					CX25840_SVIDEO_ON,
 			.gpio0  = 0,
-		}},
+		} },
 	},
 	[CX23885_BOARD_HAUPPAUGE_HVR1250] = {
 		.name		= "Hauppauge WinTV-HVR1250",
@@ -106,19 +106,19 @@ struct cx23885_board cx23885_boards[] = {
 			.type   = CX23885_VMUX_TELEVISION,
 			.vmux   = 0,
 			.gpio0  = 0xff00,
-		},{
+		}, {
 			.type   = CX23885_VMUX_DEBUG,
 			.vmux   = 0,
 			.gpio0  = 0xff01,
-		},{
+		}, {
 			.type   = CX23885_VMUX_COMPOSITE1,
 			.vmux   = 1,
 			.gpio0  = 0xff02,
-		},{
+		}, {
 			.type   = CX23885_VMUX_SVIDEO,
 			.vmux   = 2,
 			.gpio0  = 0xff02,
-		}},
+		} },
 	},
 	[CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = {
 		.name		= "DViCO FusionHDTV5 Express",
@@ -169,43 +169,43 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x0070,
 		.subdevice = 0x3400,
 		.card      = CX23885_BOARD_UNKNOWN,
-	},{
+	}, {
 		.subvendor = 0x0070,
 		.subdevice = 0x7600,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1800lp,
-	},{
+	}, {
 		.subvendor = 0x0070,
 		.subdevice = 0x7800,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1800,
-	},{
+	}, {
 		.subvendor = 0x0070,
 		.subdevice = 0x7801,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1800,
-	},{
+	}, {
 		.subvendor = 0x0070,
 		.subdevice = 0x7809,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1800,
-	},{
+	}, {
 		.subvendor = 0x0070,
 		.subdevice = 0x7911,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1250,
-	},{
+	}, {
 		.subvendor = 0x18ac,
 		.subdevice = 0xd500,
 		.card      = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP,
-	},{
+	}, {
 		.subvendor = 0x0070,
 		.subdevice = 0x7790,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1500Q,
-	},{
+	}, {
 		.subvendor = 0x0070,
 		.subdevice = 0x7797,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1500Q,
-	},{
+	}, {
 		.subvendor = 0x0070,
 		.subdevice = 0x7710,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1500,
-	},{
+	}, {
 		.subvendor = 0x0070,
 		.subdevice = 0x7717,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1500,
@@ -225,11 +225,11 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x0070,
 		.subdevice = 0x8010,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1400,
-	},{
+	}, {
 		.subvendor = 0x18ac,
 		.subdevice = 0xd618,
 		.card      = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP,
-	},{
+	}, {
 		.subvendor = 0x18ac,
 		.subdevice = 0xdb78,
 		.card      = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP,
@@ -247,23 +247,25 @@ void cx23885_card_list(struct cx23885_dev *dev)
 
 	if (0 == dev->pci->subsystem_vendor &&
 	    0 == dev->pci->subsystem_device) {
-		printk("%s: Your board has no valid PCIe Subsystem ID and thus can't\n"
-		       "%s: be autodetected.  Please pass card=<n> insmod option to\n"
-		       "%s: workaround that.  Redirect complaints to the vendor of\n"
-		       "%s: the TV card.  Best regards,\n"
+		printk(KERN_INFO
+			"%s: Board has no valid PCIe Subsystem ID and can't\n"
+		       "%s: be autodetected. Pass card=<n> insmod option\n"
+		       "%s: to workaround that. Redirect complaints to the\n"
+		       "%s: vendor of the TV card.  Best regards,\n"
 		       "%s:         -- tux\n",
 		       dev->name, dev->name, dev->name, dev->name, dev->name);
 	} else {
-		printk("%s: Your board isn't known (yet) to the driver.  You can\n"
-		       "%s: try to pick one of the existing card configs via\n"
+		printk(KERN_INFO
+			"%s: Your board isn't known (yet) to the driver.\n"
+		       "%s: Try to pick one of the existing card configs via\n"
 		       "%s: card=<n> insmod option.  Updating to the latest\n"
 		       "%s: version might help as well.\n",
 		       dev->name, dev->name, dev->name, dev->name);
 	}
-	printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
+	printk(KERN_INFO "%s: Here is a list of valid choices for the card=<n> insmod option:\n",
 	       dev->name);
 	for (i = 0; i < cx23885_bcount; i++)
-		printk("%s:    card=%d -> %s\n",
+		printk(KERN_INFO "%s:    card=%d -> %s\n",
 		       dev->name, i, cx23885_boards[i].name);
 }
 
@@ -271,11 +273,11 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
 {
 	struct tveeprom tv;
 
-	tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, eeprom_data);
+	tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
+		eeprom_data);
 
 	/* Make sure we support the board model */
-	switch (tv.model)
-	{
+	switch (tv.model) {
 	case 71009:
 		/* WinTV-HVR1200 (PCIe, Retail, full height)
 		 * DVB-T and basic analog */
@@ -303,21 +305,51 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
 	case 71999:
 		/* WinTV-HVR1200 (PCIe, OEM, full height)
 		 * DVB-T and basic analog */
-	case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */
-	case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */
-	case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */
-	case 77041: /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM and Basic analog */
-	case 77051: /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM and Basic analog */
-	case 78011: /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */
-	case 78501: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */
-	case 78521: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */
-	case 78531: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */
-	case 78631: /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */
-	case 79001: /* WinTV-HVR1250 (PCIe, Retail, IR, full height, ATSC and Basic analog */
-	case 79101: /* WinTV-HVR1250 (PCIe, Retail, IR, half height, ATSC and Basic analog */
-	case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */
-	case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */
-	case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */
+	case 76601:
+		/* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual
+			channel ATSC and MPEG2 HW Encoder */
+	case 77001:
+		/* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC
+			and Basic analog */
+	case 77011:
+		/* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC
+			and Basic analog */
+	case 77041:
+		/* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM
+			and Basic analog */
+	case 77051:
+		/* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM
+			and Basic analog */
+	case 78011:
+		/* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM,
+			Dual channel ATSC and MPEG2 HW Encoder */
+	case 78501:
+		/* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM,
+			Dual channel ATSC and MPEG2 HW Encoder */
+	case 78521:
+		/* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM,
+			Dual channel ATSC and MPEG2 HW Encoder */
+	case 78531:
+		/* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM,
+			Dual channel ATSC and MPEG2 HW Encoder */
+	case 78631:
+		/* WinTV-HVR1800 (PCIe, OEM, No IR, No FM,
+			Dual channel ATSC and MPEG2 HW Encoder */
+	case 79001:
+		/* WinTV-HVR1250 (PCIe, Retail, IR, full height,
+			ATSC and Basic analog */
+	case 79101:
+		/* WinTV-HVR1250 (PCIe, Retail, IR, half height,
+			ATSC and Basic analog */
+	case 79561:
+		/* WinTV-HVR1250 (PCIe, OEM, No IR, half height,
+			ATSC and Basic analog */
+	case 79571:
+		/* WinTV-HVR1250 (PCIe, OEM, No IR, full height,
+		 ATSC and Basic analog */
+	case 79671:
+		/* WinTV-HVR1250 (PCIe, OEM, No IR, half height,
+			ATSC and Basic analog */
 	case 80019:
 		/* WinTV-HVR1400 (Express Card, Retail, IR,
 		 * DVB-T and Basic analog */
@@ -329,7 +361,8 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
 		 * DVB-T and MPEG2 HW Encoder */
 		break;
 	default:
-		printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model);
+		printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n",
+			dev->name, tv.model);
 		break;
 	}
 
@@ -352,7 +385,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
 		return -EINVAL;
 	}
 
-	switch(dev->board) {
+	switch (dev->board) {
 	case CX23885_BOARD_HAUPPAUGE_HVR1400:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
@@ -383,7 +416,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
 
 void cx23885_gpio_setup(struct cx23885_dev *dev)
 {
-	switch(dev->board) {
+	switch (dev->board) {
 	case CX23885_BOARD_HAUPPAUGE_HVR1250:
 		/* GPIO-0 cx24227 demodulator reset */
 		cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */
@@ -617,10 +650,3 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 }
 
 /* ------------------------------------------------------------------ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
- */

+ 156 - 120
drivers/media/video/cx23885/cx23885-core.c

@@ -37,12 +37,12 @@ MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
 MODULE_LICENSE("GPL");
 
 static unsigned int debug;
-module_param(debug,int,0644);
-MODULE_PARM_DESC(debug,"enable debug messages");
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages");
 
 static unsigned int card[]  = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
 module_param_array(card,  int, NULL, 0444);
-MODULE_PARM_DESC(card,"card type");
+MODULE_PARM_DESC(card, "card type");
 
 #define dprintk(level, fmt, arg...)\
 	do { if (debug >= level)\
@@ -364,13 +364,12 @@ void cx23885_wakeup(struct cx23885_tsport *port,
 		list_del(&buf->vb.queue);
 		wake_up(&buf->vb.done);
 	}
-	if (list_empty(&q->active)) {
+	if (list_empty(&q->active))
 		del_timer(&q->timeout);
-	} else {
+	else
 		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
-	}
 	if (bc != 1)
-		printk("%s: %d buffers handled (should be 1)\n",
+		printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n",
 		       __func__, bc);
 }
 
@@ -381,8 +380,7 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
 	unsigned int i, lines;
 	u32 cdt;
 
-	if (ch->cmds_start == 0)
-	{
+	if (ch->cmds_start == 0) {
 		dprintk(1, "%s() Erasing channel [%s]\n", __func__,
 			ch->name);
 		cx_write(ch->ptr1_reg, 0);
@@ -418,15 +416,15 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
 
 	/* write CMDS */
 	if (ch->jumponly)
-		cx_write(ch->cmds_start +  0, 8);
+		cx_write(ch->cmds_start + 0, 8);
 	else
-		cx_write(ch->cmds_start +  0, risc);
+		cx_write(ch->cmds_start + 0, risc);
 	cx_write(ch->cmds_start +  4, 0); /* 64 bits 63-32 */
 	cx_write(ch->cmds_start +  8, cdt);
 	cx_write(ch->cmds_start + 12, (lines*16) >> 3);
 	cx_write(ch->cmds_start + 16, ch->ctrl_start);
 	if (ch->jumponly)
-		cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2) );
+		cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
 	else
 		cx_write(ch->cmds_start + 20, 64 >> 2);
 	for (i = 24; i < 80; i += 4)
@@ -436,9 +434,9 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
 	cx_write(ch->ptr1_reg, ch->fifo_start);
 	cx_write(ch->ptr2_reg, cdt);
 	cx_write(ch->cnt2_reg, (lines*16) >> 3);
-	cx_write(ch->cnt1_reg, (bpl >> 3) -1);
+	cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
 
-	dprintk(2,"[bridge %d] sram setup %s: bpl=%d lines=%d\n",
+	dprintk(2, "[bridge %d] sram setup %s: bpl=%d lines=%d\n",
 		dev->bridge,
 		ch->name,
 		bpl,
@@ -469,43 +467,43 @@ void cx23885_sram_channel_dump(struct cx23885_dev *dev,
 	u32 risc;
 	unsigned int i, j, n;
 
-	printk("%s: %s - dma channel status dump\n",
+	printk(KERN_WARNING "%s: %s - dma channel status dump\n",
 	       dev->name, ch->name);
 	for (i = 0; i < ARRAY_SIZE(name); i++)
-		printk("%s:   cmds: %-15s: 0x%08x\n",
+		printk(KERN_WARNING "%s:   cmds: %-15s: 0x%08x\n",
 		       dev->name, name[i],
 		       cx_read(ch->cmds_start + 4*i));
 
 	for (i = 0; i < 4; i++) {
 		risc = cx_read(ch->cmds_start + 4 * (i + 14));
-		printk("%s:   risc%d: ", dev->name, i);
+		printk(KERN_WARNING "%s:   risc%d: ", dev->name, i);
 		cx23885_risc_decode(risc);
 	}
 	for (i = 0; i < (64 >> 2); i += n) {
 		risc = cx_read(ch->ctrl_start + 4 * i);
 		/* No consideration for bits 63-32 */
 
-		printk("%s:   (0x%08x) iq %x: ", dev->name,
+		printk(KERN_WARNING "%s:   (0x%08x) iq %x: ", dev->name,
 		       ch->ctrl_start + 4 * i, i);
 		n = cx23885_risc_decode(risc);
 		for (j = 1; j < n; j++) {
 			risc = cx_read(ch->ctrl_start + 4 * (i + j));
-			printk("%s:   iq %x: 0x%08x [ arg #%d ]\n",
+			printk(KERN_WARNING "%s:   iq %x: 0x%08x [ arg #%d ]\n",
 			       dev->name, i+j, risc, j);
 		}
 	}
 
-	printk("%s: fifo: 0x%08x -> 0x%x\n",
+	printk(KERN_WARNING "%s: fifo: 0x%08x -> 0x%x\n",
 	       dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
-	printk("%s: ctrl: 0x%08x -> 0x%x\n",
+	printk(KERN_WARNING "%s: ctrl: 0x%08x -> 0x%x\n",
 	       dev->name, ch->ctrl_start, ch->ctrl_start + 6*16);
-	printk("%s:   ptr1_reg: 0x%08x\n",
+	printk(KERN_WARNING "%s:   ptr1_reg: 0x%08x\n",
 	       dev->name, cx_read(ch->ptr1_reg));
-	printk("%s:   ptr2_reg: 0x%08x\n",
+	printk(KERN_WARNING "%s:   ptr2_reg: 0x%08x\n",
 	       dev->name, cx_read(ch->ptr2_reg));
-	printk("%s:   cnt1_reg: 0x%08x\n",
+	printk(KERN_WARNING "%s:   cnt1_reg: 0x%08x\n",
 	       dev->name, cx_read(ch->cnt1_reg));
-	printk("%s:   cnt2_reg: 0x%08x\n",
+	printk(KERN_WARNING "%s:   cnt2_reg: 0x%08x\n",
 	       dev->name, cx_read(ch->cnt2_reg));
 }
 
@@ -515,13 +513,13 @@ static void cx23885_risc_disasm(struct cx23885_tsport *port,
 	struct cx23885_dev *dev = port->dev;
 	unsigned int i, j, n;
 
-	printk("%s: risc disasm: %p [dma=0x%08lx]\n",
+	printk(KERN_INFO "%s: risc disasm: %p [dma=0x%08lx]\n",
 	       dev->name, risc->cpu, (unsigned long)risc->dma);
 	for (i = 0; i < (risc->size >> 2); i += n) {
-		printk("%s:   %04d: ", dev->name, i);
+		printk(KERN_INFO "%s:   %04d: ", dev->name, i);
 		n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i]));
 		for (j = 1; j < n; j++)
-			printk("%s:   %04d: 0x%08x [ arg #%d ]\n",
+			printk(KERN_INFO "%s:   %04d: 0x%08x [ arg #%d ]\n",
 			       dev->name, i + j, risc->cpu[i + j], j);
 		if (risc->cpu[i] == cpu_to_le32(RISC_JUMP))
 			break;
@@ -600,7 +598,7 @@ static int cx23885_pci_quirks(struct cx23885_dev *dev)
 	 * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not
 	 * occur on the cx23887 bridge.
 	 */
-	if(dev->bridge == CX23885_BRIDGE_885)
+	if (dev->bridge == CX23885_BRIDGE_885)
 		cx_clear(RDR_TLCTL0, 1 << 4);
 
 	return 0;
@@ -608,13 +606,13 @@ static int cx23885_pci_quirks(struct cx23885_dev *dev)
 
 static int get_resources(struct cx23885_dev *dev)
 {
-	if (request_mem_region(pci_resource_start(dev->pci,0),
-			       pci_resource_len(dev->pci,0),
+	if (request_mem_region(pci_resource_start(dev->pci, 0),
+			       pci_resource_len(dev->pci, 0),
 			       dev->name))
 		return 0;
 
 	printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
-		dev->name, (unsigned long long)pci_resource_start(dev->pci,0));
+		dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
 
 	return -EBUSY;
 }
@@ -623,7 +621,8 @@ static void cx23885_timeout(unsigned long data);
 int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
 				u32 reg, u32 mask, u32 value);
 
-static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno)
+static int cx23885_init_tsport(struct cx23885_dev *dev,
+	struct cx23885_tsport *port, int portno)
 {
 	dprintk(1, "%s(portno=%d)\n", __func__, portno);
 
@@ -643,7 +642,18 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *p
 	port->mpegq.timeout.data = (unsigned long)port;
 	init_timer(&port->mpegq.timeout);
 
-	switch(portno) {
+	mutex_init(&port->frontends.lock);
+	INIT_LIST_HEAD(&port->frontends.felist);
+	port->frontends.active_fe_id = 0;
+
+	/* This should be hardcoded allow a single frontend
+	 * attachment to this tsport, keeping the -dvb.c
+	 * code clean and safe.
+	 */
+	if (!port->num_frontends)
+		port->num_frontends = 1;
+
+	switch (portno) {
 	case 1:
 		port->reg_gpcnt          = VID_B_GPCNT;
 		port->reg_gpcnt_ctl      = VID_B_GPCNT_CTL;
@@ -744,13 +754,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 	mutex_unlock(&devlist);
 
 	/* Configure the internal memory */
-	if(dev->pci->device == 0x8880) {
+	if (dev->pci->device == 0x8880) {
 		dev->bridge = CX23885_BRIDGE_887;
 		/* Apply a sensible clock frequency for the PCIe bridge */
 		dev->clk_freq = 25000000;
 		dev->sram_channels = cx23887_sram_channels;
 	} else
-	if(dev->pci->device == 0x8852) {
+	if (dev->pci->device == 0x8852) {
 		dev->bridge = CX23885_BRIDGE_885;
 		/* Apply a sensible clock frequency for the PCIe bridge */
 		dev->clk_freq = 28000000;
@@ -831,8 +841,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 	}
 
 	/* PCIe stuff */
-	dev->lmmio = ioremap(pci_resource_start(dev->pci,0),
-			     pci_resource_len(dev->pci,0));
+	dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
+			     pci_resource_len(dev->pci, 0));
 
 	dev->bmmio = (u8 __iomem *)dev->lmmio;
 
@@ -862,7 +872,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 	cx23885_i2c_register(&dev->i2c_bus[1]);
 	cx23885_i2c_register(&dev->i2c_bus[2]);
 	cx23885_card_setup(dev);
-	cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
+	cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
 	cx23885_ir_init(dev);
 
 	if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -908,8 +918,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 
 static void cx23885_dev_unregister(struct cx23885_dev *dev)
 {
-	release_mem_region(pci_resource_start(dev->pci,0),
-			   pci_resource_len(dev->pci,0));
+	release_mem_region(pci_resource_start(dev->pci, 0),
+			   pci_resource_len(dev->pci, 0));
 
 	if (!atomic_dec_and_test(&dev->refcount))
 		return;
@@ -936,7 +946,7 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
 	iounmap(dev->lmmio);
 }
 
-static __le32* cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
+static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
 			       unsigned int offset, u32 sync_line,
 			       unsigned int bpl, unsigned int padding,
 			       unsigned int lines)
@@ -957,31 +967,31 @@ static __le32* cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
 		}
 		if (bpl <= sg_dma_len(sg)-offset) {
 			/* fits into current chunk */
-			*(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
-			*(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
-			*(rp++)=cpu_to_le32(0); /* bits 63-32 */
-			offset+=bpl;
+			*(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
+			*(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
+			*(rp++) = cpu_to_le32(0); /* bits 63-32 */
+			offset += bpl;
 		} else {
 			/* scanline needs to be split */
 			todo = bpl;
-			*(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
+			*(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|
 					    (sg_dma_len(sg)-offset));
-			*(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
-			*(rp++)=cpu_to_le32(0); /* bits 63-32 */
+			*(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
+			*(rp++) = cpu_to_le32(0); /* bits 63-32 */
 			todo -= (sg_dma_len(sg)-offset);
 			offset = 0;
 			sg++;
 			while (todo > sg_dma_len(sg)) {
-				*(rp++)=cpu_to_le32(RISC_WRITE|
+				*(rp++) = cpu_to_le32(RISC_WRITE|
 						    sg_dma_len(sg));
-				*(rp++)=cpu_to_le32(sg_dma_address(sg));
-				*(rp++)=cpu_to_le32(0); /* bits 63-32 */
+				*(rp++) = cpu_to_le32(sg_dma_address(sg));
+				*(rp++) = cpu_to_le32(0); /* bits 63-32 */
 				todo -= sg_dma_len(sg);
 				sg++;
 			}
-			*(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
-			*(rp++)=cpu_to_le32(sg_dma_address(sg));
-			*(rp++)=cpu_to_le32(0); /* bits 63-32 */
+			*(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
+			*(rp++) = cpu_to_le32(sg_dma_address(sg));
+			*(rp++) = cpu_to_le32(0); /* bits 63-32 */
 			offset += todo;
 		}
 		offset += padding;
@@ -1010,9 +1020,11 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 	   can cause next bpl to start close to a page border.  First DMA
 	   region may be smaller than PAGE_SIZE */
 	/* write and jump need and extra dword */
-	instructions  = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
+	instructions  = fields * (1 + ((bpl + padding) * lines)
+		/ PAGE_SIZE + lines);
 	instructions += 2;
-	if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
+	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
+	if (rc < 0)
 		return rc;
 
 	/* write risc instructions */
@@ -1026,7 +1038,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 
 	/* save pointer to jmp instruction address */
 	risc->jmp = rp;
-	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
+	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
 	return 0;
 }
 
@@ -1048,7 +1060,8 @@ static int cx23885_risc_databuffer(struct pci_dev *pci,
 	instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
 	instructions += 1;
 
-	if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
+	rc = btcx_riscmem_alloc(pci, risc, instructions*12);
+	if (rc < 0)
 		return rc;
 
 	/* write risc instructions */
@@ -1057,7 +1070,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci,
 
 	/* save pointer to jmp instruction address */
 	risc->jmp = rp;
-	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
+	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
 	return 0;
 }
 
@@ -1067,7 +1080,8 @@ int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
 	__le32 *rp;
 	int rc;
 
-	if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
+	rc = btcx_riscmem_alloc(pci, risc, 4*16);
+	if (rc < 0)
 		return rc;
 
 	/* write risc instructions */
@@ -1161,22 +1175,23 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 
 	/* setup fifo + format */
 	cx23885_sram_channel_setup(dev,
-				   &dev->sram_channels[ port->sram_chno ],
+				   &dev->sram_channels[port->sram_chno],
 				   port->ts_packet_size, buf->risc.dma);
-	if(debug > 5) {
-		cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ] );
+	if (debug > 5) {
+		cx23885_sram_channel_dump(dev,
+			&dev->sram_channels[port->sram_chno]);
 		cx23885_risc_disasm(port, &buf->risc);
 	}
 
 	/* write TS length to chip */
 	cx_write(port->reg_lngth, buf->vb.width);
 
-	if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) &&
-		(!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) {
-		printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n",
+	if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) &&
+		(!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) {
+		printk("%s() Unsupported .portb/c (0x%08x)/(0x%08x)\n",
 			__func__,
 			cx23885_boards[dev->board].portb,
-			cx23885_boards[dev->board].portc );
+			cx23885_boards[dev->board].portc);
 		return -EINVAL;
 	}
 
@@ -1186,7 +1201,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 	udelay(100);
 
 	/* If the port supports SRC SELECT, configure it */
-	if(port->reg_src_sel)
+	if (port->reg_src_sel)
 		cx_write(port->reg_src_sel, port->src_sel_val);
 
 	cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val);
@@ -1195,7 +1210,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 	cx_write(port->reg_gen_ctrl, port->gen_ctrl_val);
 	udelay(100);
 
-	// NOTE: this is 2 (reserved) for portb, does it matter?
+	/* NOTE: this is 2 (reserved) for portb, does it matter? */
 	/* reset counter to zero */
 	cx_write(port->reg_gpcnt_ctl, 3);
 	q->count = 1;
@@ -1229,11 +1244,11 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 		cx_write(ALT_PIN_OUT_SEL, 0x10100045);
 	}
 
-	switch(dev->bridge) {
+	switch (dev->bridge) {
 	case CX23885_BRIDGE_885:
 	case CX23885_BRIDGE_887:
 		/* enable irqs */
-		dprintk(1, "%s() enabling TS int's and DMA\n", __func__ );
+		dprintk(1, "%s() enabling TS int's and DMA\n", __func__);
 		cx_set(port->reg_ts_int_msk,  port->ts_int_msk_val);
 		cx_set(port->reg_dma_ctl, port->dma_ctl_val);
 		cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask);
@@ -1292,8 +1307,7 @@ int cx23885_restart_queue(struct cx23885_tsport *port,
 	struct cx23885_buffer *buf;
 
 	dprintk(5, "%s()\n", __func__);
-	if (list_empty(&q->active))
-	{
+	if (list_empty(&q->active)) {
 		struct cx23885_buffer *prev;
 		prev = NULL;
 
@@ -1311,7 +1325,7 @@ int cx23885_restart_queue(struct cx23885_tsport *port,
 				buf->vb.state = VIDEOBUF_ACTIVE;
 				buf->count    = q->count++;
 				mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
-				dprintk(5, "[%p/%d] restart_queue - first active\n",
+				dprintk(5, "[%p/%d] restart_queue - f/active\n",
 					buf, buf->vb.i);
 
 			} else if (prev->vb.width  == buf->vb.width  &&
@@ -1322,8 +1336,9 @@ int cx23885_restart_queue(struct cx23885_tsport *port,
 				buf->vb.state = VIDEOBUF_ACTIVE;
 				buf->count    = q->count++;
 				prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-				prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
-				dprintk(5,"[%p/%d] restart_queue - move to active\n",
+				/* 64 bit bits 63-32 */
+				prev->risc.jmp[2] = cpu_to_le32(0);
+				dprintk(5, "[%p/%d] restart_queue - m/active\n",
 					buf, buf->vb.i);
 			} else {
 				return 0;
@@ -1362,7 +1377,8 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port,
 		buf->vb.size   = size;
 		buf->vb.field  = field /*V4L2_FIELD_TOP*/;
 
-		if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
+		rc = videobuf_iolock(q, &buf->vb, NULL);
+		if (0 != rc)
 			goto fail;
 		cx23885_risc_databuffer(dev->pci, &buf->risc,
 					videobuf_to_dma(&buf->vb)->sglist,
@@ -1388,7 +1404,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
 	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
 
 	if (list_empty(&cx88q->active)) {
-		dprintk( 1, "queue is empty - first active\n" );
+		dprintk(1, "queue is empty - first active\n");
 		list_add_tail(&buf->vb.queue, &cx88q->active);
 		cx23885_start_dma(port, cx88q, buf);
 		buf->vb.state = VIDEOBUF_ACTIVE;
@@ -1397,7 +1413,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
 		dprintk(1, "[%p/%d] %s - first active\n",
 			buf, buf->vb.i, __func__);
 	} else {
-		dprintk( 1, "queue is not empty - append to active\n" );
+		dprintk(1, "queue is not empty - append to active\n");
 		prev = list_entry(cx88q->active.prev, struct cx23885_buffer,
 				  vb.queue);
 		list_add_tail(&buf->vb.queue, &cx88q->active);
@@ -1405,7 +1421,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
 		buf->count    = cx88q->count++;
 		prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 		prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
-		dprintk( 1, "[%p/%d] %s - append to active\n",
+		dprintk(1, "[%p/%d] %s - append to active\n",
 			 buf, buf->vb.i, __func__);
 	}
 }
@@ -1431,7 +1447,7 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
 			buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
 	}
 	if (restart) {
-		dprintk(1, "restarting queue\n" );
+		dprintk(1, "restarting queue\n");
 		cx23885_restart_queue(port, q);
 	}
 	spin_unlock_irqrestore(&port->slock, flags);
@@ -1453,10 +1469,11 @@ static void cx23885_timeout(unsigned long data)
 	struct cx23885_tsport *port = (struct cx23885_tsport *)data;
 	struct cx23885_dev *dev = port->dev;
 
-	dprintk(1, "%s()\n",__func__);
+	dprintk(1, "%s()\n", __func__);
 
 	if (debug > 5)
-		cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]);
+		cx23885_sram_channel_dump(dev,
+			&dev->sram_channels[port->sram_chno]);
 
 	cx23885_stop_dma(port);
 	do_cancel_buffers(port, "timeout", 1);
@@ -1532,16 +1549,23 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status)
 	if ((status & VID_BC_MSK_OPC_ERR) ||
 		(status & VID_BC_MSK_BAD_PKT) ||
 		(status & VID_BC_MSK_SYNC) ||
-		(status & VID_BC_MSK_OF))
-	{
+		(status & VID_BC_MSK_OF)) {
+
 		if (status & VID_BC_MSK_OPC_ERR)
-			dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR);
+			dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n",
+				VID_BC_MSK_OPC_ERR);
+
 		if (status & VID_BC_MSK_BAD_PKT)
-			dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", VID_BC_MSK_BAD_PKT);
+			dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n",
+				VID_BC_MSK_BAD_PKT);
+
 		if (status & VID_BC_MSK_SYNC)
-			dprintk(7, " (VID_BC_MSK_SYNC    0x%08x)\n", VID_BC_MSK_SYNC);
+			dprintk(7, " (VID_BC_MSK_SYNC    0x%08x)\n",
+				VID_BC_MSK_SYNC);
+
 		if (status & VID_BC_MSK_OF)
-			dprintk(7, " (VID_BC_MSK_OF      0x%08x)\n", VID_BC_MSK_OF);
+			dprintk(7, " (VID_BC_MSK_OF      0x%08x)\n",
+				VID_BC_MSK_OF);
 
 		printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name);
 
@@ -1595,7 +1619,7 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
 	ts2_status = cx_read(VID_C_INT_STAT);
 	ts2_mask = cx_read(VID_C_INT_MSK);
 
-	if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) )
+	if ((pci_status == 0) && (ts2_status == 0) && (ts1_status == 0))
 		goto out;
 
 	vida_count = cx_read(VID_A_GPCNT);
@@ -1610,38 +1634,56 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
 	dprintk(7, "ts2_status: 0x%08x  ts2_mask: 0x%08x count: 0x%x\n",
 		ts2_status, ts2_mask, ts2_count);
 
-	if ( (pci_status & PCI_MSK_RISC_RD) ||
-	     (pci_status & PCI_MSK_RISC_WR) ||
-	     (pci_status & PCI_MSK_AL_RD) ||
-	     (pci_status & PCI_MSK_AL_WR) ||
-	     (pci_status & PCI_MSK_APB_DMA) ||
-	     (pci_status & PCI_MSK_VID_C) ||
-	     (pci_status & PCI_MSK_VID_B) ||
-	     (pci_status & PCI_MSK_VID_A) ||
-	     (pci_status & PCI_MSK_AUD_INT) ||
-	     (pci_status & PCI_MSK_AUD_EXT) )
-	{
+	if ((pci_status & PCI_MSK_RISC_RD) ||
+	    (pci_status & PCI_MSK_RISC_WR) ||
+	    (pci_status & PCI_MSK_AL_RD) ||
+	    (pci_status & PCI_MSK_AL_WR) ||
+	    (pci_status & PCI_MSK_APB_DMA) ||
+	    (pci_status & PCI_MSK_VID_C) ||
+	    (pci_status & PCI_MSK_VID_B) ||
+	    (pci_status & PCI_MSK_VID_A) ||
+	    (pci_status & PCI_MSK_AUD_INT) ||
+	    (pci_status & PCI_MSK_AUD_EXT)) {
 
 		if (pci_status & PCI_MSK_RISC_RD)
-			dprintk(7, " (PCI_MSK_RISC_RD   0x%08x)\n", PCI_MSK_RISC_RD);
+			dprintk(7, " (PCI_MSK_RISC_RD   0x%08x)\n",
+				PCI_MSK_RISC_RD);
+
 		if (pci_status & PCI_MSK_RISC_WR)
-			dprintk(7, " (PCI_MSK_RISC_WR   0x%08x)\n", PCI_MSK_RISC_WR);
+			dprintk(7, " (PCI_MSK_RISC_WR   0x%08x)\n",
+				PCI_MSK_RISC_WR);
+
 		if (pci_status & PCI_MSK_AL_RD)
-			dprintk(7, " (PCI_MSK_AL_RD     0x%08x)\n", PCI_MSK_AL_RD);
+			dprintk(7, " (PCI_MSK_AL_RD     0x%08x)\n",
+				PCI_MSK_AL_RD);
+
 		if (pci_status & PCI_MSK_AL_WR)
-			dprintk(7, " (PCI_MSK_AL_WR     0x%08x)\n", PCI_MSK_AL_WR);
+			dprintk(7, " (PCI_MSK_AL_WR     0x%08x)\n",
+				PCI_MSK_AL_WR);
+
 		if (pci_status & PCI_MSK_APB_DMA)
-			dprintk(7, " (PCI_MSK_APB_DMA   0x%08x)\n", PCI_MSK_APB_DMA);
+			dprintk(7, " (PCI_MSK_APB_DMA   0x%08x)\n",
+				PCI_MSK_APB_DMA);
+
 		if (pci_status & PCI_MSK_VID_C)
-			dprintk(7, " (PCI_MSK_VID_C     0x%08x)\n", PCI_MSK_VID_C);
+			dprintk(7, " (PCI_MSK_VID_C     0x%08x)\n",
+				PCI_MSK_VID_C);
+
 		if (pci_status & PCI_MSK_VID_B)
-			dprintk(7, " (PCI_MSK_VID_B     0x%08x)\n", PCI_MSK_VID_B);
+			dprintk(7, " (PCI_MSK_VID_B     0x%08x)\n",
+				PCI_MSK_VID_B);
+
 		if (pci_status & PCI_MSK_VID_A)
-			dprintk(7, " (PCI_MSK_VID_A     0x%08x)\n", PCI_MSK_VID_A);
+			dprintk(7, " (PCI_MSK_VID_A     0x%08x)\n",
+				PCI_MSK_VID_A);
+
 		if (pci_status & PCI_MSK_AUD_INT)
-			dprintk(7, " (PCI_MSK_AUD_INT   0x%08x)\n", PCI_MSK_AUD_INT);
+			dprintk(7, " (PCI_MSK_AUD_INT   0x%08x)\n",
+				PCI_MSK_AUD_INT);
+
 		if (pci_status & PCI_MSK_AUD_EXT)
-			dprintk(7, " (PCI_MSK_AUD_EXT   0x%08x)\n", PCI_MSK_AUD_EXT);
+			dprintk(7, " (PCI_MSK_AUD_EXT   0x%08x)\n",
+				PCI_MSK_AUD_EXT);
 
 	}
 
@@ -1753,13 +1795,13 @@ static struct pci_device_id cx23885_pci_tbl[] = {
 		.device       = 0x8852,
 		.subvendor    = PCI_ANY_ID,
 		.subdevice    = PCI_ANY_ID,
-	},{
+	}, {
 		/* CX23887 Rev 2 */
 		.vendor       = 0x14f1,
 		.device       = 0x8880,
 		.subvendor    = PCI_ANY_ID,
 		.subdevice    = PCI_ANY_ID,
-	},{
+	}, {
 		/* --- end of list --- */
 	}
 };
@@ -1797,9 +1839,3 @@ module_init(cx23885_init);
 module_exit(cx23885_fini);
 
 /* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
- */

+ 116 - 74
drivers/media/video/cx23885/cx23885-dvb.c

@@ -78,19 +78,19 @@ static int dvb_buf_prepare(struct videobuf_queue *q,
 			   struct videobuf_buffer *vb, enum v4l2_field field)
 {
 	struct cx23885_tsport *port = q->priv_data;
-	return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field);
+	return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field);
 }
 
 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
 {
 	struct cx23885_tsport *port = q->priv_data;
-	cx23885_buf_queue(port, (struct cx23885_buffer*)vb);
+	cx23885_buf_queue(port, (struct cx23885_buffer *)vb);
 }
 
 static void dvb_buf_release(struct videobuf_queue *q,
 			    struct videobuf_buffer *vb)
 {
-	cx23885_free_buffer(q, (struct cx23885_buffer*)vb);
+	cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
 }
 
 static struct videobuf_queue_ops dvb_qops = {
@@ -312,19 +312,25 @@ static int dvb_register(struct cx23885_tsport *port)
 {
 	struct cx23885_dev *dev = port->dev;
 	struct cx23885_i2c *i2c_bus = NULL;
+	struct videobuf_dvb_frontend *fe0;
+
+	/* Get the first frontend */
+	fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
+	if (!fe0)
+		return -EINVAL;
 
 	/* init struct videobuf_dvb */
-	port->dvb.name = dev->name;
+	fe0->dvb.name = dev->name;
 
 	/* init frontend */
 	switch (dev->board) {
 	case CX23885_BOARD_HAUPPAUGE_HVR1250:
 		i2c_bus = &dev->i2c_bus[0];
-		port->dvb.frontend = dvb_attach(s5h1409_attach,
+		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
 						&hauppauge_generic_config,
 						&i2c_bus->i2c_adap);
-		if (port->dvb.frontend != NULL) {
-			dvb_attach(mt2131_attach, port->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(mt2131_attach, fe0->dvb.frontend,
 				   &i2c_bus->i2c_adap,
 				   &hauppauge_generic_tunerconfig, 0);
 		}
@@ -333,27 +339,27 @@ static int dvb_register(struct cx23885_tsport *port)
 		i2c_bus = &dev->i2c_bus[0];
 		switch (alt_tuner) {
 		case 1:
-			port->dvb.frontend =
+			fe0->dvb.frontend =
 				dvb_attach(s5h1409_attach,
 					   &hauppauge_ezqam_config,
 					   &i2c_bus->i2c_adap);
-			if (port->dvb.frontend != NULL) {
-				dvb_attach(tda829x_attach, port->dvb.frontend,
+			if (fe0->dvb.frontend != NULL) {
+				dvb_attach(tda829x_attach, fe0->dvb.frontend,
 					   &dev->i2c_bus[1].i2c_adap, 0x42,
 					   &tda829x_no_probe);
-				dvb_attach(tda18271_attach, port->dvb.frontend,
+				dvb_attach(tda18271_attach, fe0->dvb.frontend,
 					   0x60, &dev->i2c_bus[1].i2c_adap,
 					   &hauppauge_tda18271_config);
 			}
 			break;
 		case 0:
 		default:
-			port->dvb.frontend =
+			fe0->dvb.frontend =
 				dvb_attach(s5h1409_attach,
 					   &hauppauge_generic_config,
 					   &i2c_bus->i2c_adap);
-			if (port->dvb.frontend != NULL)
-				dvb_attach(mt2131_attach, port->dvb.frontend,
+			if (fe0->dvb.frontend != NULL)
+				dvb_attach(mt2131_attach, fe0->dvb.frontend,
 					   &i2c_bus->i2c_adap,
 					   &hauppauge_generic_tunerconfig, 0);
 			break;
@@ -361,42 +367,42 @@ static int dvb_register(struct cx23885_tsport *port)
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
 		i2c_bus = &dev->i2c_bus[0];
-		port->dvb.frontend = dvb_attach(s5h1409_attach,
+		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
 						&hauppauge_hvr1800lp_config,
 						&i2c_bus->i2c_adap);
-		if (port->dvb.frontend != NULL) {
-			dvb_attach(mt2131_attach, port->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(mt2131_attach, fe0->dvb.frontend,
 				   &i2c_bus->i2c_adap,
 				   &hauppauge_generic_tunerconfig, 0);
 		}
 		break;
 	case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
 		i2c_bus = &dev->i2c_bus[0];
-		port->dvb.frontend = dvb_attach(lgdt330x_attach,
+		fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
 						&fusionhdtv_5_express,
 						&i2c_bus->i2c_adap);
-		if (port->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, port->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 				   &i2c_bus->i2c_adap, 0x61,
 				   TUNER_LG_TDVS_H06XF);
 		}
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
 		i2c_bus = &dev->i2c_bus[1];
-		port->dvb.frontend = dvb_attach(s5h1409_attach,
+		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
 						&hauppauge_hvr1500q_config,
 						&dev->i2c_bus[0].i2c_adap);
-		if (port->dvb.frontend != NULL)
-			dvb_attach(xc5000_attach, port->dvb.frontend,
+		if (fe0->dvb.frontend != NULL)
+			dvb_attach(xc5000_attach, fe0->dvb.frontend,
 				   &i2c_bus->i2c_adap,
 				   &hauppauge_hvr1500q_tunerconfig);
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 		i2c_bus = &dev->i2c_bus[1];
-		port->dvb.frontend = dvb_attach(s5h1409_attach,
+		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
 						&hauppauge_hvr1500_config,
 						&dev->i2c_bus[0].i2c_adap);
-		if (port->dvb.frontend != NULL) {
+		if (fe0->dvb.frontend != NULL) {
 			struct dvb_frontend *fe;
 			struct xc2028_config cfg = {
 				.i2c_adap  = &i2c_bus->i2c_adap,
@@ -409,7 +415,7 @@ static int dvb_register(struct cx23885_tsport *port)
 			};
 
 			fe = dvb_attach(xc2028_attach,
-					port->dvb.frontend, &cfg);
+					fe0->dvb.frontend, &cfg);
 			if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
 				fe->ops.tuner_ops.set_config(fe, &ctl);
 		}
@@ -417,24 +423,24 @@ static int dvb_register(struct cx23885_tsport *port)
 	case CX23885_BOARD_HAUPPAUGE_HVR1200:
 	case CX23885_BOARD_HAUPPAUGE_HVR1700:
 		i2c_bus = &dev->i2c_bus[0];
-		port->dvb.frontend = dvb_attach(tda10048_attach,
+		fe0->dvb.frontend = dvb_attach(tda10048_attach,
 			&hauppauge_hvr1200_config,
 			&i2c_bus->i2c_adap);
-		if (port->dvb.frontend != NULL) {
-			dvb_attach(tda829x_attach, port->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(tda829x_attach, fe0->dvb.frontend,
 				&dev->i2c_bus[1].i2c_adap, 0x42,
 				&tda829x_no_probe);
-			dvb_attach(tda18271_attach, port->dvb.frontend,
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
 				0x60, &dev->i2c_bus[1].i2c_adap,
 				&hauppauge_hvr1200_tuner_config);
 		}
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1400:
 		i2c_bus = &dev->i2c_bus[0];
-		port->dvb.frontend = dvb_attach(dib7000p_attach,
+		fe0->dvb.frontend = dvb_attach(dib7000p_attach,
 			&i2c_bus->i2c_adap,
 			0x12, &hauppauge_hvr1400_dib7000_config);
-		if (port->dvb.frontend != NULL) {
+		if (fe0->dvb.frontend != NULL) {
 			struct dvb_frontend *fe;
 			struct xc2028_config cfg = {
 				.i2c_adap  = &dev->i2c_bus[1].i2c_adap,
@@ -444,12 +450,13 @@ static int dvb_register(struct cx23885_tsport *port)
 				.fname   = XC3028L_DEFAULT_FIRMWARE,
 				.max_len = 64,
 				.demod   = 5000,
-				/* This is true for all demods with v36 firmware? */
+				/* This is true for all demods with
+					v36 firmware? */
 				.type    = XC2028_D2633,
 			};
 
 			fe = dvb_attach(xc2028_attach,
-					port->dvb.frontend, &cfg);
+					fe0->dvb.frontend, &cfg);
 			if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
 				fe->ops.tuner_ops.set_config(fe, &ctl);
 		}
@@ -457,25 +464,25 @@ static int dvb_register(struct cx23885_tsport *port)
 	case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
 		i2c_bus = &dev->i2c_bus[port->nr - 1];
 
-		port->dvb.frontend = dvb_attach(s5h1409_attach,
+		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
 						&dvico_s5h1409_config,
 						&i2c_bus->i2c_adap);
-		if (port->dvb.frontend == NULL)
-			port->dvb.frontend = dvb_attach(s5h1411_attach,
+		if (fe0->dvb.frontend == NULL)
+			fe0->dvb.frontend = dvb_attach(s5h1411_attach,
 							&dvico_s5h1411_config,
 							&i2c_bus->i2c_adap);
-		if (port->dvb.frontend != NULL)
-			dvb_attach(xc5000_attach, port->dvb.frontend,
+		if (fe0->dvb.frontend != NULL)
+			dvb_attach(xc5000_attach, fe0->dvb.frontend,
 				   &i2c_bus->i2c_adap,
 				   &dvico_xc5000_tunerconfig);
 		break;
 	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: {
 		i2c_bus = &dev->i2c_bus[port->nr - 1];
 
-		port->dvb.frontend = dvb_attach(zl10353_attach,
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_xc3028,
 					       &i2c_bus->i2c_adap);
-		if (port->dvb.frontend != NULL) {
+		if (fe0->dvb.frontend != NULL) {
 			struct dvb_frontend      *fe;
 			struct xc2028_config	  cfg = {
 				.i2c_adap  = &i2c_bus->i2c_adap,
@@ -487,7 +494,7 @@ static int dvb_register(struct cx23885_tsport *port)
 				.demod       = XC3028_FE_ZARLINK456,
 			};
 
-			fe = dvb_attach(xc2028_attach, port->dvb.frontend,
+			fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
 					&cfg);
 			if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
 				fe->ops.tuner_ops.set_config(fe, &ctl);
@@ -497,10 +504,10 @@ static int dvb_register(struct cx23885_tsport *port)
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 		i2c_bus = &dev->i2c_bus[0];
 
-		port->dvb.frontend = dvb_attach(zl10353_attach,
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
 			&dvico_fusionhdtv_xc3028,
 			&i2c_bus->i2c_adap);
-		if (port->dvb.frontend != NULL) {
+		if (fe0->dvb.frontend != NULL) {
 			struct dvb_frontend      *fe;
 			struct xc2028_config	  cfg = {
 				.i2c_adap  = &dev->i2c_bus[1].i2c_adap,
@@ -512,73 +519,108 @@ static int dvb_register(struct cx23885_tsport *port)
 				.demod       = XC3028_FE_ZARLINK456,
 			};
 
-			fe = dvb_attach(xc2028_attach, port->dvb.frontend,
+			fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
 				&cfg);
 			if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
 				fe->ops.tuner_ops.set_config(fe, &ctl);
 		}
 		break;
 	default:
-		printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
+		printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
+			" isn't supported yet\n",
 		       dev->name);
 		break;
 	}
-	if (NULL == port->dvb.frontend) {
-		printk("%s: frontend initialization failed\n", dev->name);
+	if (NULL == fe0->dvb.frontend) {
+		printk(KERN_ERR "%s: frontend initialization failed\n",
+			dev->name);
 		return -1;
 	}
 	/* define general-purpose callback pointer */
-	port->dvb.frontend->callback = cx23885_tuner_callback;
+	fe0->dvb.frontend->callback = cx23885_tuner_callback;
 
 	/* Put the analog decoder in standby to keep it quiet */
 	cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
 
-	if (port->dvb.frontend->ops.analog_ops.standby)
-		port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend);
+	if (fe0->dvb.frontend->ops.analog_ops.standby)
+		fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
 
 	/* register everything */
-	return videobuf_dvb_register(&port->dvb, THIS_MODULE, port,
-				     &dev->pci->dev, adapter_nr);
+	return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
+		&dev->pci->dev, adapter_nr, 0);
+
 }
 
 int cx23885_dvb_register(struct cx23885_tsport *port)
 {
+
+	struct videobuf_dvb_frontend *fe0;
 	struct cx23885_dev *dev = port->dev;
-	int err;
+	int err, i;
+
+	/* Here we need to allocate the correct number of frontends,
+	 * as reflected in the cards struct. The reality is that currrently
+	 * no cx23885 boards support this - yet. But, if we don't modify this
+	 * code then the second frontend would never be allocated (later)
+	 * and fail with error before the attach in dvb_register().
+	 * Without these changes we risk an OOPS later. The changes here
+	 * are for safety, and should provide a good foundation for the
+	 * future addition of any multi-frontend cx23885 based boards.
+	 */
+	printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
+		port->num_frontends);
+
+	for (i = 1; i <= port->num_frontends; i++) {
+		if (videobuf_dvb_alloc_frontend(
+			&port->frontends, i) == NULL) {
+			printk(KERN_ERR "%s() failed to alloc\n", __func__);
+			return -ENOMEM;
+		}
 
-	dprintk(1, "%s\n", __func__);
-	dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
-		dev->board,
-		dev->name,
-		dev->pci_bus,
-		dev->pci_slot);
+		fe0 = videobuf_dvb_get_frontend(&port->frontends, i);
+		if (!fe0)
+			err = -EINVAL;
 
-	err = -ENODEV;
+		dprintk(1, "%s\n", __func__);
+		dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n",
+			dev->board,
+			dev->name,
+			dev->pci_bus,
+			dev->pci_slot);
 
-	/* dvb stuff */
-	printk("%s: cx23885 based dvb card\n", dev->name);
-	videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock,
+		err = -ENODEV;
+
+		/* dvb stuff */
+		/* We have to init the queue for each frontend on a port. */
+		printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name);
+		videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops,
+			    &dev->pci->dev, &port->slock,
 			    V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
 			    sizeof(struct cx23885_buffer), port);
+	}
 	err = dvb_register(port);
 	if (err != 0)
-		printk("%s() dvb_register failed err = %d\n", __func__, err);
+		printk(KERN_ERR "%s() dvb_register failed err = %d\n",
+			__func__, err);
 
 	return err;
 }
 
 int cx23885_dvb_unregister(struct cx23885_tsport *port)
 {
-	/* dvb */
-	if(port->dvb.frontend)
-		videobuf_dvb_unregister(&port->dvb);
+	struct videobuf_dvb_frontend *fe0;
+
+	/* FIXME: in an error condition where the we have
+	 * an expected number of frontends (attach problem)
+	 * then this might not clean up correctly, if 1
+	 * is invalid.
+	 * This comment only applies to future boards IF they
+	 * implement MFE support.
+	 */
+	fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
+	if (fe0->dvb.frontend)
+		videobuf_dvb_unregister_bus(&port->frontends);
 
 	return 0;
 }
 
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
-*/

+ 24 - 23
drivers/media/video/cx23885/cx23885-i2c.c

@@ -131,7 +131,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
 			printk(" >\n");
 	}
 
-	for (cnt = 1; cnt < msg->len; cnt++ ) {
+	for (cnt = 1; cnt < msg->len; cnt++) {
 		/* following bytes */
 		wdata = msg->buf[cnt];
 		ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
@@ -151,9 +151,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
 		if (retval == 0)
 			goto eio;
 		if (i2c_debug) {
-			printk(" %02x", msg->buf[cnt]);
+			dprintk(1, " %02x", msg->buf[cnt]);
 			if (!(ctrl & I2C_NOSTOP))
-				printk(" >\n");
+				dprintk(1, " >\n");
 		}
 	}
 	return msg->len;
@@ -162,7 +162,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
 	retval = -EIO;
  err:
 	if (i2c_debug)
-		printk(" ERR: %d\n", retval);
+		printk(KERN_ERR " ERR: %d\n", retval);
 	return retval;
 }
 
@@ -194,12 +194,12 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
 
 	if (i2c_debug) {
 		if (joined)
-			printk(" R");
+			dprintk(1, " R");
 		else
-			printk(" <R %02x", (msg->addr << 1) + 1);
+			dprintk(1, " <R %02x", (msg->addr << 1) + 1);
 	}
 
-	for(cnt = 0; cnt < msg->len; cnt++) {
+	for (cnt = 0; cnt < msg->len; cnt++) {
 
 		ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
 
@@ -216,9 +216,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
 			goto eio;
 		msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
 		if (i2c_debug) {
-			printk(" %02x", msg->buf[cnt]);
+			dprintk(1, " %02x", msg->buf[cnt]);
 			if (!(ctrl & I2C_NOSTOP))
-				printk(" >\n");
+				dprintk(1, " >\n");
 		}
 	}
 	return msg->len;
@@ -227,7 +227,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
 	retval = -EIO;
  err:
 	if (i2c_debug)
-		printk(" ERR: %d\n", retval);
+		printk(KERN_ERR " ERR: %d\n", retval);
 	return retval;
 }
 
@@ -353,17 +353,17 @@ static struct i2c_client cx23885_i2c_client_template = {
 };
 
 static char *i2c_devs[128] = {
-	[0x10 >> 1]   = "tda10048",
-	[0x12 >> 1]   = "dib7000pc",
-	[ 0x1c >> 1 ] = "lgdt3303",
-	[ 0x86 >> 1 ] = "tda9887",
-	[ 0x32 >> 1 ] = "cx24227",
-	[ 0x88 >> 1 ] = "cx25837",
-	[ 0x84 >> 1 ] = "tda8295",
-	[ 0xa0 >> 1 ] = "eeprom",
-	[ 0xc0 >> 1 ] = "tuner/mt2131/tda8275",
+	[0x10 >> 1] = "tda10048",
+	[0x12 >> 1] = "dib7000pc",
+	[0x1c >> 1] = "lgdt3303",
+	[0x86 >> 1] = "tda9887",
+	[0x32 >> 1] = "cx24227",
+	[0x88 >> 1] = "cx25837",
+	[0x84 >> 1] = "tda8295",
+	[0xa0 >> 1] = "eeprom",
+	[0xc0 >> 1] = "tuner/mt2131/tda8275",
 	[0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028",
-	[0xc8 >> 1]   = "tuner/xc3028L",
+	[0xc8 >> 1] = "tuner/xc3028L",
 };
 
 static void do_i2c_scan(char *name, struct i2c_client *c)
@@ -376,7 +376,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
 		rc = i2c_master_recv(c, &buf, 0);
 		if (rc < 0)
 			continue;
-		printk("%s: i2c scan: found device @ 0x%x  [%s]\n",
+		printk(KERN_INFO "%s: i2c scan: found device @ 0x%x  [%s]\n",
 		       name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
 	}
 }
@@ -408,11 +408,12 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
 	bus->i2c_client.adapter = &bus->i2c_adap;
 
 	if (0 == bus->i2c_rc) {
-		printk("%s: i2c bus %d registered\n", dev->name, bus->nr);
+		dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
 		if (i2c_scan)
 			do_i2c_scan(dev->name, &bus->i2c_client);
 	} else
-		printk("%s: i2c bus %d register FAILED\n", dev->name, bus->nr);
+		printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
+			dev->name, bus->nr);
 
 	return bus->i2c_rc;
 }

+ 13 - 12
drivers/media/video/cx23885/cx23885-video.c

@@ -285,11 +285,10 @@ static void cx23885_video_wakeup(struct cx23885_dev *dev,
 		list_del(&buf->vb.queue);
 		wake_up(&buf->vb.done);
 	}
-	if (list_empty(&q->active)) {
+	if (list_empty(&q->active))
 		del_timer(&q->timeout);
-	} else {
+	else
 		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
-	}
 	if (bc != 1)
 		printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
 			__func__, bc);
@@ -379,12 +378,12 @@ static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh,
 
 static int res_check(struct cx23885_fh *fh, unsigned int bit)
 {
-	return (fh->resources & bit);
+	return fh->resources & bit;
 }
 
 static int res_locked(struct cx23885_dev *dev, unsigned int bit)
 {
-	return (dev->resources & bit);
+	return dev->resources & bit;
 }
 
 static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh,
@@ -887,14 +886,16 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma)
 /* ------------------------------------------------------------------ */
 /* VIDEO CTRL IOCTLS                                                  */
 
-static int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl)
+static int cx23885_get_control(struct cx23885_dev *dev,
+	struct v4l2_control *ctl)
 {
 	dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
 	cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl);
 	return 0;
 }
 
-static int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl)
+static int cx23885_set_control(struct cx23885_dev *dev,
+	struct v4l2_control *ctl)
 {
 	dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)"
 		" (disabled - no action)\n", __func__);
@@ -1073,29 +1074,29 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 	struct v4l2_requestbuffers *p)
 {
 	struct cx23885_fh *fh = priv;
-	return (videobuf_reqbufs(get_queue(fh), p));
+	return videobuf_reqbufs(get_queue(fh), p);
 }
 
 static int vidioc_querybuf(struct file *file, void *priv,
 	struct v4l2_buffer *p)
 {
 	struct cx23885_fh *fh = priv;
-	return (videobuf_querybuf(get_queue(fh), p));
+	return videobuf_querybuf(get_queue(fh), p);
 }
 
 static int vidioc_qbuf(struct file *file, void *priv,
 	struct v4l2_buffer *p)
 {
 	struct cx23885_fh *fh = priv;
-	return (videobuf_qbuf(get_queue(fh), p));
+	return videobuf_qbuf(get_queue(fh), p);
 }
 
 static int vidioc_dqbuf(struct file *file, void *priv,
 	struct v4l2_buffer *p)
 {
 	struct cx23885_fh *fh = priv;
-	return (videobuf_dqbuf(get_queue(fh), p,
-				file->f_flags & O_NONBLOCK));
+	return videobuf_dqbuf(get_queue(fh), p,
+				file->f_flags & O_NONBLOCK);
 }
 
 static int vidioc_streamon(struct file *file, void *priv,

+ 11 - 15
drivers/media/video/cx23885/cx23885.h

@@ -37,7 +37,7 @@
 #include <linux/version.h>
 #include <linux/mutex.h>
 
-#define CX23885_VERSION_CODE KERNEL_VERSION(0,0,1)
+#define CX23885_VERSION_CODE KERNEL_VERSION(0, 0, 1)
 
 #define UNSET (-1U)
 
@@ -225,7 +225,7 @@ struct cx23885_tsport {
 	int                        nr;
 	int                        sram_chno;
 
-	struct videobuf_dvb        dvb;
+	struct videobuf_dvb_frontends frontends;
 
 	/* dma queues */
 	struct cx23885_dmaqueue    mpegq;
@@ -262,6 +262,9 @@ struct cx23885_tsport {
 	u32                        src_sel_val;
 	u32                        vld_misc_val;
 	u32                        hw_sop_ctrl_val;
+
+	/* Allow a single tsport to have multiple frontends */
+	u32                        num_frontends;
 };
 
 struct cx23885_dev {
@@ -367,14 +370,14 @@ struct sram_channel {
 /* ----------------------------------------------------------- */
 
 #define cx_read(reg)             readl(dev->lmmio + ((reg)>>2))
-#define cx_write(reg,value)      writel((value), dev->lmmio + ((reg)>>2))
+#define cx_write(reg, value)     writel((value), dev->lmmio + ((reg)>>2))
 
-#define cx_andor(reg,mask,value) \
+#define cx_andor(reg, mask, value) \
   writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
   ((value) & (mask)), dev->lmmio+((reg)>>2))
 
-#define cx_set(reg,bit)          cx_andor((reg),(bit),(bit))
-#define cx_clear(reg,bit)        cx_andor((reg),(bit),0)
+#define cx_set(reg, bit)          cx_andor((reg), (bit), (bit))
+#define cx_clear(reg, bit)        cx_andor((reg), (bit), 0)
 
 /* ----------------------------------------------------------- */
 /* cx23885-core.c                                              */
@@ -411,7 +414,8 @@ extern const unsigned int cx23885_bcount;
 extern struct cx23885_subid cx23885_subids[];
 extern const unsigned int cx23885_idcount;
 
-extern int cx23885_tuner_callback(void *priv, int component, int command, int arg);
+extern int cx23885_tuner_callback(void *priv, int component,
+	int command, int arg);
 extern void cx23885_card_list(struct cx23885_dev *dev);
 extern int  cx23885_ir_init(struct cx23885_dev *dev);
 extern void cx23885_gpio_setup(struct cx23885_dev *dev);
@@ -479,11 +483,3 @@ static inline unsigned int norm_swidth(v4l2_std_id norm)
 {
 	return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
 }
-
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
- */

+ 51 - 7
drivers/media/video/cx88/cx88-cards.c

@@ -1270,27 +1270,40 @@ static const struct cx88_board cx88_boards[] = {
 		.mpeg           = CX88_MPEG_DVB,
 	},
 	[CX88_BOARD_HAUPPAUGE_HVR3000] = {
-		/* FIXME: Add dvb & radio support */
 		.name           = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T",
 		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
+		.audio_chip     = V4L2_IDENT_WM8775,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
 			.gpio0  = 0x84bf,
+			/* 1: TV Audio / FM Mono */
+			.audioroute = 1,
 		},{
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 1,
 			.gpio0  = 0x84bf,
+			/* 2: Line-In */
+			.audioroute = 2,
 		},{
 			.type   = CX88_VMUX_SVIDEO,
 			.vmux   = 2,
 			.gpio0  = 0x84bf,
+			/* 2: Line-In */
+			.audioroute = 2,
 		}},
+		.radio = {
+			.type   = CX88_RADIO,
+			.gpio0	= 0x84bf,
+			/* 4: FM Stereo (untested) */
+			.audioroute = 8,
+		},
 		.mpeg           = CX88_MPEG_DVB,
+		.num_frontends	= 2,
 	},
 	[CX88_BOARD_NORWOOD_MICRO] = {
 		.name           = "Norwood Micro TV Tuner",
@@ -1356,23 +1369,27 @@ static const struct cx88_board cx88_boards[] = {
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
 			.gpio0	= 0xef88,
+			/* 1: TV Audio / FM Mono */
 			.audioroute = 1,
 		},{
 			.type	= CX88_VMUX_COMPOSITE1,
 			.vmux	= 1,
 			.gpio0	= 0xef88,
+			/* 2: Line-In */
 			.audioroute = 2,
 		},{
 			.type	= CX88_VMUX_SVIDEO,
 			.vmux	= 2,
 			.gpio0	= 0xef88,
+			/* 2: Line-In */
 			.audioroute = 2,
 		}},
-		/* fixme: Add radio support */
 		.mpeg           = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD,
 		.radio = {
 			.type   = CX88_RADIO,
 			.gpio0	= 0xef88,
+			/* 4: FM Stereo (untested) */
+			.audioroute = 8,
 		},
 	},
 	[CX88_BOARD_ADSTECH_PTV_390] = {
@@ -1716,6 +1733,7 @@ static const struct cx88_board cx88_boards[] = {
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
+		.audio_chip     = V4L2_IDENT_WM8775,
 		/*
 		 * GPIO0 (WINTV2000)
 		 *
@@ -1729,7 +1747,7 @@ static const struct cx88_board cx88_boards[] = {
 		 * BIT  VALUE   FUNCTION GP{x}_IO
 		 * 0    1       I:?
 		 * 1    1       I:?
-		 * 2    1       O:DVB-T DEMOD ENABLE LOW/ANALOG DEMOD ENABLE HIGH
+		 * 2    1       O:MPEG PORT 0=DVB-T 1=DVB-S
 		 * 3    1       I:?
 		 * 4    1       I:?
 		 * 5    1       I:?
@@ -1745,22 +1763,41 @@ static const struct cx88_board cx88_boards[] = {
 		 * d    0       I
 		 * e    1       O
 		 * f    1       O
+		 *
+		 * WM8775 ADC
+		 *
+		 * 1: TV Audio / FM Mono
+		 * 2: Line-In
+		 * 3: Line-In Expansion
+		 * 4: FM Stereo
 		 */
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
 			.gpio0  = 0xc4bf,
+			/* 1: TV Audio / FM Mono */
+			.audioroute = 1,
 		}, {
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 1,
 			.gpio0  = 0xc4bf,
+			/* 2: Line-In */
+			.audioroute = 2,
 		}, {
 			.type   = CX88_VMUX_SVIDEO,
 			.vmux   = 2,
 			.gpio0  = 0xc4bf,
+			/* 2: Line-In */
+			.audioroute = 2,
 		} },
-		/* fixme: Add radio support */
+		.radio = {
+			.type   = CX88_RADIO,
+			.gpio0	= 0xc4bf,
+			/* 4: FM Stereo */
+			.audioroute = 8,
+		},
 		.mpeg           = CX88_MPEG_DVB,
+		.num_frontends	= 2,
 	},
 	[CX88_BOARD_HAUPPAUGE_HVR4000LITE] = {
 		.name           = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2",
@@ -2662,10 +2699,13 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
 
 	case CX88_BOARD_HAUPPAUGE_HVR3000:
 	case CX88_BOARD_HAUPPAUGE_HVR4000:
-	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
 		/* Init GPIO */
 		cx_write(MO_GP0_IO, core->board.input[0].gpio0);
 		udelay(1000);
+		cx_clear(MO_GP0_IO, 0x00000080);
+		udelay(50);
+		cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
+		udelay(1000);
 		break;
 	}
 }
@@ -3004,10 +3044,14 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
 
 	memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
 
-	info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+	if (!core->board.num_frontends)
+		core->board.num_frontends=1;
+
+	info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n",
 		pci->subsystem_vendor, pci->subsystem_device, core->board.name,
 		core->boardnr, card[core->nr] == core->boardnr ?
-		"insmod option" : "autodetected");
+		"insmod option" : "autodetected",
+		core->board.num_frontends);
 
 	if (tuner[core->nr] != UNSET)
 		core->board.tuner_type = tuner[core->nr];

+ 2 - 1
drivers/media/video/cx88/cx88-core.c

@@ -549,7 +549,8 @@ void cx88_wakeup(struct cx88_core *core,
 		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
 	}
 	if (bc != 1)
-		printk("%s: %d buffers handled (should be 1)\n",__func__,bc);
+		dprintk(2, "%s: %d buffers handled (should be 1)\n",
+			__func__, bc);
 }
 
 void cx88_shutdown(struct cx88_core *core)

+ 273 - 132
drivers/media/video/cx88/cx88-dvb.c

@@ -116,13 +116,23 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
 	struct cx8802_dev *dev= fe->dvb->priv;
 	struct cx8802_driver *drv = NULL;
 	int ret = 0;
+	int fe_id;
+
+	fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
+	if (!fe_id) {
+		printk(KERN_ERR "%s() No frontend found\n", __func__);
+		return -EINVAL;
+	}
 
 	drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
 	if (drv) {
-		if (acquire)
+		if (acquire){
+			dev->frontends.active_fe_id = fe_id;
 			ret = drv->request_acquire(drv);
-		else
+		} else {
 			ret = drv->request_release(drv);
+			dev->frontends.active_fe_id = 0;
+		}
 	}
 
 	return ret;
@@ -396,7 +406,7 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
 			cx_write(MO_GP0_IO, 0x00006060);
 			break;
 		case SEC_VOLTAGE_OFF:
-			printk("LNB Voltage SEC_VOLTAGE_off\n");
+		   	printk("LNB Voltage SEC_VOLTAGE_off\n");
 			break;
 	}
 
@@ -483,6 +493,7 @@ static struct xc5000_config dvico_fusionhdtv7_tuner_config = {
 static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
 {
 	struct dvb_frontend *fe;
+	struct videobuf_dvb_frontend *fe0 = NULL;
 	struct xc2028_ctrl ctl;
 	struct xc2028_config cfg = {
 		.i2c_adap  = &dev->core->i2c_adap,
@@ -490,7 +501,12 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
 		.ctrl      = &ctl,
 	};
 
-	if (!dev->dvb.frontend) {
+	/* Get the first frontend */
+	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+	if (!fe0)
+		return -EINVAL;
+
+	if (!fe0->dvb.frontend) {
 		printk(KERN_ERR "%s/2: dvb frontend not attached. "
 				"Can't attach xc3028\n",
 		       dev->core->name);
@@ -504,10 +520,13 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
 	 */
 	cx88_setup_xc3028(dev->core, &ctl);
 
-	fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
+	fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
 	if (!fe) {
 		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 		       dev->core->name);
+		dvb_frontend_detach(fe0->dvb.frontend);
+		dvb_unregister_frontend(fe0->dvb.frontend);
+		fe0->dvb.frontend = NULL;
 		return -EINVAL;
 	}
 
@@ -532,8 +551,10 @@ static int cx24116_reset_device(struct dvb_frontend *fe)
 	struct cx88_core *core = dev->core;
 
 	/* Reset the part */
+	/* Put the cx24116 into reset */
 	cx_write(MO_SRST_IO, 0);
 	msleep(10);
+	/* Take the cx24116 out of reset */
 	cx_write(MO_SRST_IO, 1);
 	msleep(10);
 
@@ -554,14 +575,14 @@ static struct cx24116_config tevii_s460_config = {
 
 static struct stv0299_config tevii_tuner_sharp_config = {
 	.demod_address = 0x68,
-	.inittab = sharp_z0194a__inittab,
+	.inittab = sharp_z0194a_inittab,
 	.mclk = 88000000UL,
 	.invert = 1,
 	.skip_reinit = 0,
 	.lock_output = 1,
 	.volt13_op0_op1 = STV0299_VOLT13_OP1,
 	.min_delay_ms = 100,
-	.set_symbol_rate = sharp_z0194a__set_symbol_rate,
+	.set_symbol_rate = sharp_z0194a_set_symbol_rate,
 	.set_ts_params = cx24116_set_ts_param,
 };
 
@@ -574,19 +595,25 @@ static struct stv0288_config tevii_tuner_earda_config = {
 static int dvb_register(struct cx8802_dev *dev)
 {
 	struct cx88_core *core = dev->core;
+	struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
+	int mfe_shared = 0; /* bus not shared by default */
 
-	/* init struct videobuf_dvb */
-	dev->dvb.name = core->name;
-	dev->ts_gen_cntrl = 0x0c;
+	/* Get the first frontend */
+	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+	if (!fe0)
+		return -EINVAL;
 
-	/* init frontend */
+	/* multi-frontend gate control is undefined or defaults to fe0 */
+	dev->frontends.gate = 0;
+
+	/* init frontend(s) */
 	switch (core->boardnr) {
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
-		dev->dvb.frontend = dvb_attach(cx22702_attach,
+		fe0->dvb.frontend = dvb_attach(cx22702_attach,
 					       &connexant_refboard_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
 					0x61, &core->i2c_adap,
 					DVB_PLL_THOMSON_DTT759X))
 				goto frontend_detach;
@@ -596,11 +623,11 @@ static int dvb_register(struct cx8802_dev *dev)
 	case CX88_BOARD_CONEXANT_DVB_T1:
 	case CX88_BOARD_KWORLD_DVB_T_CX22702:
 	case CX88_BOARD_WINFAST_DTV1000:
-		dev->dvb.frontend = dvb_attach(cx22702_attach,
+		fe0->dvb.frontend = dvb_attach(cx22702_attach,
 					       &connexant_refboard_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
 					0x60, &core->i2c_adap,
 					DVB_PLL_THOMSON_DTT7579))
 				goto frontend_detach;
@@ -610,33 +637,67 @@ static int dvb_register(struct cx8802_dev *dev)
 	case CX88_BOARD_HAUPPAUGE_HVR1100:
 	case CX88_BOARD_HAUPPAUGE_HVR1100LP:
 	case CX88_BOARD_HAUPPAUGE_HVR1300:
-	case CX88_BOARD_HAUPPAUGE_HVR3000:
-		dev->dvb.frontend = dvb_attach(cx22702_attach,
+		fe0->dvb.frontend = dvb_attach(cx22702_attach,
 					       &hauppauge_hvr_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 				   &core->i2c_adap, 0x61,
 				   TUNER_PHILIPS_FMD1216ME_MK3))
 				goto frontend_detach;
 		}
 		break;
+	case CX88_BOARD_HAUPPAUGE_HVR3000:
+		/* DVB-S init */
+		fe0->dvb.frontend = dvb_attach(cx24123_attach,
+			       &hauppauge_novas_config,
+			       &dev->core->i2c_adap);
+		if (fe0->dvb.frontend) {
+			if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
+			&dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
+				dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __func__);
+			}
+		} else {
+			dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __func__);
+		}
+		/* DVB-T init */
+		fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
+		if (fe1) {
+			dev->frontends.gate = 2;
+			mfe_shared = 1;
+			fe1->dvb.frontend = dvb_attach(cx22702_attach,
+				&hauppauge_hvr_config,
+				&dev->core->i2c_adap);
+			if (fe1->dvb.frontend) {
+				fe1->dvb.frontend->id = 1;
+				if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
+						&dev->core->i2c_adap, 0x61,
+						TUNER_PHILIPS_FMD1216ME_MK3)) {
+					dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __func__);
+				}
+			} else {
+				dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __func__);
+			}
+		} else {
+			dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __func__);
+		}
+		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
-		dev->dvb.frontend = dvb_attach(mt352_attach,
+		fe0->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
 					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
 				goto frontend_detach;
 			break;
 		}
 		/* ZL10353 replaces MT352 on later cards */
-		dev->dvb.frontend = dvb_attach(zl10353_attach,
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_plus_v1_1,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
 					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
 				goto frontend_detach;
 		}
@@ -644,31 +705,31 @@ static int dvb_register(struct cx8802_dev *dev)
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
 		/* The tin box says DEE1601, but it seems to be DTT7579
 		 * compatible, with a slightly different MT352 AGC gain. */
-		dev->dvb.frontend = dvb_attach(mt352_attach,
+		fe0->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv_dual,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
 					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
 				goto frontend_detach;
 			break;
 		}
 		/* ZL10353 replaces MT352 on later cards */
-		dev->dvb.frontend = dvb_attach(zl10353_attach,
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_plus_v1_1,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
 					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
 				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
-		dev->dvb.frontend = dvb_attach(mt352_attach,
+		fe0->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
 					0x61, NULL, DVB_PLL_LG_Z201))
 				goto frontend_detach;
 		}
@@ -676,11 +737,11 @@ static int dvb_register(struct cx8802_dev *dev)
 	case CX88_BOARD_KWORLD_DVB_T:
 	case CX88_BOARD_DNTV_LIVE_DVB_T:
 	case CX88_BOARD_ADSTECH_DVB_T_PCI:
-		dev->dvb.frontend = dvb_attach(mt352_attach,
+		fe0->dvb.frontend = dvb_attach(mt352_attach,
 					       &dntv_live_dvbt_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
 					0x61, NULL, DVB_PLL_UNKNOWN_1))
 				goto frontend_detach;
 		}
@@ -688,10 +749,10 @@ static int dvb_register(struct cx8802_dev *dev)
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
 		/* MT352 is on a secondary I2C bus made from some GPIO lines */
-		dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
+		fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
 					       &dev->vp3054->adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 					&core->i2c_adap, 0x61,
 					TUNER_PHILIPS_FMD1216ME_MK3))
 				goto frontend_detach;
@@ -702,22 +763,22 @@ static int dvb_register(struct cx8802_dev *dev)
 #endif
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
-		dev->dvb.frontend = dvb_attach(zl10353_attach,
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_hybrid,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 				   &core->i2c_adap, 0x61,
 				   TUNER_THOMSON_FE6600))
 				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
-		dev->dvb.frontend = dvb_attach(zl10353_attach,
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_xc3028,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend == NULL)
-			dev->dvb.frontend = dvb_attach(mt352_attach,
+		if (fe0->dvb.frontend == NULL)
+			fe0->dvb.frontend = dvb_attach(mt352_attach,
 						&dvico_fusionhdtv_mt352_xc3028,
 						&core->i2c_adap);
 		/*
@@ -725,16 +786,16 @@ static int dvb_register(struct cx8802_dev *dev)
 		 * We must not permit gate_ctrl to be performed, or
 		 * the xc3028 cannot communicate on the bus.
 		 */
-		if (dev->dvb.frontend)
-			dev->dvb.frontend->ops.i2c_gate_ctrl = NULL;
+		if (fe0->dvb.frontend)
+			fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
 		if (attach_xc3028(0x61, dev) < 0)
 			return -EINVAL;
 		break;
 	case CX88_BOARD_PCHDTV_HD3000:
-		dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
+		fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 					&core->i2c_adap, 0x61,
 					TUNER_THOMSON_DTT761X))
 				goto frontend_detach;
@@ -751,11 +812,11 @@ static int dvb_register(struct cx8802_dev *dev)
 
 		/* Select RF connector callback */
 		fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
-		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+		fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &fusionhdtv_3_gold,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 					&core->i2c_adap, 0x61,
 					TUNER_MICROTUNE_4042FI5))
 				goto frontend_detach;
@@ -769,11 +830,11 @@ static int dvb_register(struct cx8802_dev *dev)
 		mdelay(100);
 		cx_set(MO_GP0_IO, 9);
 		mdelay(200);
-		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+		fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &fusionhdtv_3_gold,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 					&core->i2c_adap, 0x61,
 					TUNER_THOMSON_DTT761X))
 				goto frontend_detach;
@@ -787,15 +848,15 @@ static int dvb_register(struct cx8802_dev *dev)
 		mdelay(100);
 		cx_set(MO_GP0_IO, 1);
 		mdelay(200);
-		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+		fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &fusionhdtv_5_gold,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 					&core->i2c_adap, 0x61,
 					TUNER_LG_TDVS_H06XF))
 				goto frontend_detach;
-			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+			if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
 				   &core->i2c_adap, 0x43))
 				goto frontend_detach;
 		}
@@ -808,25 +869,25 @@ static int dvb_register(struct cx8802_dev *dev)
 		mdelay(100);
 		cx_set(MO_GP0_IO, 1);
 		mdelay(200);
-		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+		fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &pchdtv_hd5500,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 					&core->i2c_adap, 0x61,
 					TUNER_LG_TDVS_H06XF))
 				goto frontend_detach;
-			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+			if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
 				   &core->i2c_adap, 0x43))
 				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_ATI_HDTVWONDER:
-		dev->dvb.frontend = dvb_attach(nxt200x_attach,
+		fe0->dvb.frontend = dvb_attach(nxt200x_attach,
 					       &ati_hdtvwonder,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 					&core->i2c_adap, 0x61,
 					TUNER_PHILIPS_TUV1236D))
 				goto frontend_detach;
@@ -834,49 +895,49 @@ static int dvb_register(struct cx8802_dev *dev)
 		break;
 	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
 	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
-		dev->dvb.frontend = dvb_attach(cx24123_attach,
+		fe0->dvb.frontend = dvb_attach(cx24123_attach,
 					       &hauppauge_novas_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend) {
-			if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend) {
+			if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
 					&core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
 				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_KWORLD_DVBS_100:
-		dev->dvb.frontend = dvb_attach(cx24123_attach,
+		fe0->dvb.frontend = dvb_attach(cx24123_attach,
 					       &kworld_dvbs_100_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend) {
-			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
-			dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
+		if (fe0->dvb.frontend) {
+			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+			fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
 		}
 		break;
 	case CX88_BOARD_GENIATECH_DVBS:
-		dev->dvb.frontend = dvb_attach(cx24123_attach,
+		fe0->dvb.frontend = dvb_attach(cx24123_attach,
 					       &geniatech_dvbs_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend) {
-			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
-			dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
+		if (fe0->dvb.frontend) {
+			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+			fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
 		}
 		break;
 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
-		dev->dvb.frontend = dvb_attach(s5h1409_attach,
+		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
 					       &pinnacle_pctv_hd_800i_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
 					&core->i2c_adap,
 					&pinnacle_pctv_hd_800i_tuner_config))
 				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
-		dev->dvb.frontend = dvb_attach(s5h1409_attach,
+		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
 						&dvico_hdtv5_pci_nano_config,
 						&core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
+		if (fe0->dvb.frontend != NULL) {
 			struct dvb_frontend *fe;
 			struct xc2028_config cfg = {
 				.i2c_adap  = &core->i2c_adap,
@@ -889,17 +950,17 @@ static int dvb_register(struct cx8802_dev *dev)
 			};
 
 			fe = dvb_attach(xc2028_attach,
-					dev->dvb.frontend, &cfg);
+					fe0->dvb.frontend, &cfg);
 			if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
 				fe->ops.tuner_ops.set_config(fe, &ctl);
 		}
 		break;
 	 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
-		dev->dvb.frontend = dvb_attach(zl10353_attach,
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
 					       &cx88_pinnacle_hybrid_pctv,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend) {
-			dev->dvb.frontend->ops.i2c_gate_ctrl = NULL;
+		if (fe0->dvb.frontend) {
+			fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
 			if (attach_xc3028(0x61, dev) < 0)
 				goto frontend_detach;
 		}
@@ -907,85 +968,118 @@ static int dvb_register(struct cx8802_dev *dev)
 	 case CX88_BOARD_GENIATECH_X8000_MT:
 		dev->ts_gen_cntrl = 0x00;
 
-		dev->dvb.frontend = dvb_attach(zl10353_attach,
+		fe0->dvb.frontend = dvb_attach(zl10353_attach,
 					       &cx88_geniatech_x8000_mt,
 					       &core->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0)
 			goto frontend_detach;
 		break;
 	 case CX88_BOARD_KWORLD_ATSC_120:
-		dev->dvb.frontend = dvb_attach(s5h1409_attach,
+		fe0->dvb.frontend = dvb_attach(s5h1409_attach,
 					       &kworld_atsc_120_config,
 					       &core->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0)
 			goto frontend_detach;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
-		dev->dvb.frontend = dvb_attach(s5h1411_attach,
+		fe0->dvb.frontend = dvb_attach(s5h1411_attach,
 					       &dvico_fusionhdtv7_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
 					&core->i2c_adap,
 					&dvico_fusionhdtv7_tuner_config))
 				goto frontend_detach;
 		}
 		break;
 	case CX88_BOARD_HAUPPAUGE_HVR4000:
+		/* DVB-S/S2 Init */
+		fe0->dvb.frontend = dvb_attach(cx24116_attach,
+			&hauppauge_hvr4000_config,
+			&dev->core->i2c_adap);
+		if (fe0->dvb.frontend) {
+			if(!dvb_attach(isl6421_attach, fe0->dvb.frontend,
+				&dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
+				dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __func__);
+			}
+		} else {
+			dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __func__);
+		}
+		/* DVB-T Init */
+		fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
+		if (fe1) {
+			dev->frontends.gate = 2;
+			mfe_shared = 1;
+			fe1->dvb.frontend = dvb_attach(cx22702_attach,
+				&hauppauge_hvr_config,
+				&dev->core->i2c_adap);
+			if (fe1->dvb.frontend) {
+				fe1->dvb.frontend->id = 1;
+				if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
+					&dev->core->i2c_adap, 0x61,
+					TUNER_PHILIPS_FMD1216ME_MK3)) {
+					dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __func__);
+				}
+			} else {
+				dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __func__);
+			}
+		} else {
+			dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __func__);
+		}
+		break;
 	case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
-		/* Support for DVB-S only, not DVB-T support */
-		dev->dvb.frontend = dvb_attach(cx24116_attach,
+		fe0->dvb.frontend = dvb_attach(cx24116_attach,
 			&hauppauge_hvr4000_config,
 			&dev->core->i2c_adap);
-		if (dev->dvb.frontend) {
-			dvb_attach(isl6421_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend) {
+			dvb_attach(isl6421_attach, fe0->dvb.frontend,
 				&dev->core->i2c_adap,
 				0x08, ISL6421_DCL, 0x00);
 		}
 		break;
 	case CX88_BOARD_TEVII_S420:
-		dev->dvb.frontend = dvb_attach(stv0299_attach,
+		fe0->dvb.frontend = dvb_attach(stv0299_attach,
 						&tevii_tuner_sharp_config,
 						&core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+		if (fe0->dvb.frontend != NULL) {
+			if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
 					&core->i2c_adap, DVB_PLL_OPERA1))
 				goto frontend_detach;
-			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
-			dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+			fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
 
 		} else {
-			dev->dvb.frontend = dvb_attach(stv0288_attach,
+			fe0->dvb.frontend = dvb_attach(stv0288_attach,
 							    &tevii_tuner_earda_config,
 							    &core->i2c_adap);
-				if (dev->dvb.frontend != NULL) {
-					if (!dvb_attach(stb6000_attach, dev->dvb.frontend, 0x61,
+				if (fe0->dvb.frontend != NULL) {
+					if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
 						&core->i2c_adap))
 					goto frontend_detach;
-				core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
-				dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+				core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+				fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
 
 			}
 		}
 		break;
 	case CX88_BOARD_TEVII_S460:
-		dev->dvb.frontend = dvb_attach(cx24116_attach,
+		fe0->dvb.frontend = dvb_attach(cx24116_attach,
 					       &tevii_s460_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
-			dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+		if (fe0->dvb.frontend != NULL) {
+			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+			fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
 		}
 		break;
 	case CX88_BOARD_OMICOM_SS4_PCI:
 	case CX88_BOARD_TBS_8920:
 	case CX88_BOARD_PROF_7300:
-		dev->dvb.frontend = dvb_attach(cx24116_attach,
+		fe0->dvb.frontend = dvb_attach(cx24116_attach,
 					       &hauppauge_hvr4000_config,
 					       &core->i2c_adap);
-		if (dev->dvb.frontend != NULL) {
-			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
-			dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+		if (fe0->dvb.frontend != NULL) {
+			core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+			fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
 		}
 		break;
 	default:
@@ -993,29 +1087,32 @@ static int dvb_register(struct cx8802_dev *dev)
 		       core->name);
 		break;
 	}
-	if (NULL == dev->dvb.frontend) {
+
+        if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
 		printk(KERN_ERR
 		       "%s/2: frontend initialization failed\n",
 		       core->name);
 		return -EINVAL;
 	}
 	/* define general-purpose callback pointer */
-	dev->dvb.frontend->callback = cx88_tuner_callback;
+	fe0->dvb.frontend->callback = cx88_tuner_callback;
 
 	/* Ensure all frontends negotiate bus access */
-	dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
+	fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
+	if (fe1)
+		fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
 
 	/* Put the analog decoder in standby to keep it quiet */
 	cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
 
 	/* register everything */
-	return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
-				     &dev->pci->dev, adapter_nr);
+	return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
+		&dev->pci->dev, adapter_nr, mfe_shared);
 
 frontend_detach:
-	if (dev->dvb.frontend) {
-		dvb_frontend_detach(dev->dvb.frontend);
-		dev->dvb.frontend = NULL;
+	if (fe0->dvb.frontend) {
+		dvb_frontend_detach(fe0->dvb.frontend);
+		fe0->dvb.frontend = NULL;
 	}
 	return -EINVAL;
 }
@@ -1039,6 +1136,38 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
 		cx_clear(MO_GP0_IO, 0x00000004);
 		udelay(1000);
 		break;
+
+	case CX88_BOARD_HAUPPAUGE_HVR3000:
+	case CX88_BOARD_HAUPPAUGE_HVR4000:
+		if(core->dvbdev->frontends.active_fe_id == 1) {
+			/* DVB-S/S2 Enabled */
+
+			/* Toggle reset on cx22702 leaving i2c active */
+			cx_write(MO_GP0_IO, (core->board.input[0].gpio0 & 0x0000ff00) | 0x00000080);
+			udelay(1000);
+			cx_clear(MO_GP0_IO, 0x00000080);
+			udelay(50);
+			cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */
+			cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */
+			udelay(1000);
+
+			cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */
+			core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
+		} else
+		if (core->dvbdev->frontends.active_fe_id == 2) {
+			/* DVB-T Enabled */
+
+			/* Put the cx24116/cx24123 into reset */
+			cx_write(MO_SRST_IO, 0);
+
+			/* cx22702 out of reset and enable it */
+			cx_set(MO_GP0_IO,   0x00000080);
+			cx_clear(MO_GP0_IO, 0x00000004);
+			core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
+			udelay(1000);
+		}
+		break;
+
 	default:
 		err = -ENODEV;
 	}
@@ -1056,6 +1185,9 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
 	case CX88_BOARD_HAUPPAUGE_HVR1300:
 		/* Do Nothing, leave the cx22702 on the bus. */
 		break;
+	case CX88_BOARD_HAUPPAUGE_HVR3000:
+	case CX88_BOARD_HAUPPAUGE_HVR4000:
+		break;
 	default:
 		err = -ENODEV;
 	}
@@ -1066,7 +1198,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
 {
 	struct cx88_core *core = drv->core;
 	struct cx8802_dev *dev = drv->core->dvbdev;
-	int err;
+	int err, i;
+	struct videobuf_dvb_frontend *fe;
 
 	dprintk( 1, "%s\n", __func__);
 	dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1086,18 +1219,28 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
 
 	/* dvb stuff */
 	printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
-	videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops,
+	dev->ts_gen_cntrl = 0x0c;
+
+	for (i = 1; i <= core->board.num_frontends; i++) {
+		fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
+		if (!fe) {
+			printk(KERN_ERR "%s() failed to get frontend(%d)\n", __func__, i);
+			continue;
+		}
+		videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
 			    &dev->pci->dev, &dev->slock,
 			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
 			    V4L2_FIELD_TOP,
 			    sizeof(struct cx88_buffer),
 			    dev);
+		/* init struct videobuf_dvb */
+		fe->dvb.name = dev->core->name;
+	}
 	err = dvb_register(dev);
 	if (err != 0)
 		printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
 		       core->name, err);
-
- fail_core:
+fail_core:
 	return err;
 }
 
@@ -1105,9 +1248,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv)
 {
 	struct cx8802_dev *dev = drv->core->dvbdev;
 
-	/* dvb */
-	if (dev->dvb.frontend)
-		videobuf_dvb_unregister(&dev->dvb);
+	videobuf_dvb_unregister_bus(&dev->frontends);
 
 	vp3054_i2c_remove(dev);
 

+ 12 - 5
drivers/media/video/cx88/cx88-i2c.c

@@ -116,18 +116,25 @@ static int detach_inform(struct i2c_client *client)
 
 void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
 {
+	struct videobuf_dvb_frontends *f = &core->dvbdev->frontends;
+	struct videobuf_dvb_frontend *fe = NULL;
 	if (0 != core->i2c_rc)
 		return;
 
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
-	if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) {
-		if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
-			core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
+	if (core->dvbdev && f) {
+		if(f->gate <= 1) /* undefined or fe0 */
+			fe = videobuf_dvb_get_frontend(f, 1);
+		else
+			fe = videobuf_dvb_get_frontend(f, f->gate);
+
+		if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
+			fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 1);
 
 		i2c_clients_command(&core->i2c_adap, cmd, arg);
 
-		if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
-			core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
+		if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
+			fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 0);
 	} else
 #endif
 		i2c_clients_command(&core->i2c_adap, cmd, arg);

+ 21 - 1
drivers/media/video/cx88/cx88-mpeg.c

@@ -768,7 +768,8 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
 {
 	struct cx8802_dev *dev;
 	struct cx88_core  *core;
-	int err;
+	struct videobuf_dvb_frontend *demod;
+	int err,i;
 
 	/* general setup */
 	core = cx88_core_get(pci_dev);
@@ -781,6 +782,11 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
 	if (!core->board.mpeg)
 		goto fail_core;
 
+	if (!core->board.num_frontends) {
+		printk(KERN_ERR "%s() .num_frontends should be non-zero, err = %d\n", __func__, err);
+		goto fail_core;
+	}
+
 	err = -ENOMEM;
 	dev = kzalloc(sizeof(*dev),GFP_KERNEL);
 	if (NULL == dev)
@@ -795,6 +801,20 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
 	INIT_LIST_HEAD(&dev->drvlist);
 	list_add_tail(&dev->devlist,&cx8802_devlist);
 
+	mutex_init(&dev->frontends.lock);
+	INIT_LIST_HEAD(&dev->frontends.felist);
+
+	printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends);
+
+	for (i = 1; i <= core->board.num_frontends; i++) {
+		demod = videobuf_dvb_alloc_frontend(&dev->frontends, i);
+		if(demod == NULL) {
+			printk(KERN_ERR "%s() failed to alloc\n", __func__);
+			err = -ENOMEM;
+			goto fail_free;
+		}
+	}
+
 	/* Maintain a reference so cx88-video can query the 8802 device. */
 	core->dvbdev = dev;
 

+ 11 - 0
drivers/media/video/cx88/cx88-tvaudio.c

@@ -767,6 +767,14 @@ void cx88_set_tvaudio(struct cx88_core *core)
 	case WW_FM:
 		set_audio_standard_FM(core, radio_deemphasis);
 		break;
+	case WW_I2SADC:
+		set_audio_start(core, 0x01);
+		/* Slave/Philips/Autobaud */
+		cx_write(AUD_I2SINPUTCNTL, 0);
+		/* Switch to "I2S ADC mode" */
+		cx_write(AUD_I2SCNTL, 0x1);
+		set_audio_finish(core, EN_I2SIN_ENABLE);
+		break;
 	case WW_NONE:
 	default:
 		printk("%s/0: unknown tv audio mode [%d]\n",
@@ -895,6 +903,9 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
 			break;
 		}
 		break;
+	case WW_I2SADC:
+		/* DO NOTHING */
+		break;
 	}
 
 	if (UNSET != ctl) {

+ 30 - 22
drivers/media/video/cx88/cx88-video.c

@@ -426,24 +426,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
 
 	/* if there are audioroutes defined, we have an external
 	   ADC to deal with audio */
-
 	if (INPUT(input).audioroute) {
-
-		/* cx2388's C-ADC is connected to the tuner only.
-		   When used with S-Video, that ADC is busy dealing with
-		   chroma, so an external must be used for baseband audio */
-
-		if (INPUT(input).type != CX88_VMUX_TELEVISION &&
-			INPUT(input).type != CX88_RADIO) {
-			/* "ADC mode" */
-			cx_write(AUD_I2SCNTL, 0x1);
-			cx_set(AUD_CTL, EN_I2SIN_ENABLE);
-		} else {
-			/* Normal mode */
-			cx_write(AUD_I2SCNTL, 0x0);
-			cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
-		}
-
 		/* The wm8775 module has the "2" route hardwired into
 		   the initialization. Some boards may use different
 		   routes for different inputs. HVR-1300 surely does */
@@ -454,9 +437,19 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
 			route.input = INPUT(input).audioroute;
 			cx88_call_i2c_clients(core,
 				VIDIOC_INT_S_AUDIO_ROUTING, &route);
-
 		}
-
+		/* cx2388's C-ADC is connected to the tuner only.
+		   When used with S-Video, that ADC is busy dealing with
+		   chroma, so an external must be used for baseband audio */
+		if (INPUT(input).type != CX88_VMUX_TELEVISION ) {
+			/* "I2S ADC mode" */
+			core->tvaudio = WW_I2SADC;
+			cx88_set_tvaudio(core);
+		} else {
+			/* Normal mode */
+			cx_write(AUD_I2SCNTL, 0x0);
+			cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
+		}
 	}
 
 	return 0;
@@ -832,9 +825,24 @@ static int video_open(struct inode *inode, struct file *file)
 		cx_write(MO_GP0_IO, core->board.radio.gpio0);
 		cx_write(MO_GP1_IO, core->board.radio.gpio1);
 		cx_write(MO_GP2_IO, core->board.radio.gpio2);
-		core->tvaudio = WW_FM;
-		cx88_set_tvaudio(core);
-		cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
+		if (core->board.radio.audioroute) {
+			if(core->board.audio_chip &&
+				core->board.audio_chip == V4L2_IDENT_WM8775) {
+				struct v4l2_routing route;
+
+				route.input = core->board.radio.audioroute;
+				cx88_call_i2c_clients(core,
+					VIDIOC_INT_S_AUDIO_ROUTING, &route);
+			}
+			/* "I2S ADC mode" */
+			core->tvaudio = WW_I2SADC;
+			cx88_set_tvaudio(core);
+		} else {
+			/* FM Mode */
+			core->tvaudio = WW_FM;
+			cx88_set_tvaudio(core);
+			cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
+		}
 		cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
 	}
 	unlock_kernel();

+ 5 - 2
drivers/media/video/cx88/cx88.h

@@ -247,7 +247,7 @@ struct cx88_input {
 	enum cx88_itype type;
 	u32             gpio0, gpio1, gpio2, gpio3;
 	unsigned int    vmux:2;
-	unsigned int    audioroute:2;
+	unsigned int    audioroute:4;
 };
 
 struct cx88_board {
@@ -261,6 +261,7 @@ struct cx88_board {
 	struct cx88_input       radio;
 	enum cx88_board_type    mpeg;
 	unsigned int            audio_chip;
+	int			num_frontends;
 };
 
 struct cx88_subid {
@@ -356,6 +357,7 @@ struct cx88_core {
 	struct cx8802_dev          *dvbdev;
 	enum cx88_board_type       active_type_id;
 	int			   active_ref;
+	int			   active_fe_id;
 };
 
 struct cx8800_dev;
@@ -490,7 +492,7 @@ struct cx8802_dev {
 
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
 	/* for dvb only */
-	struct videobuf_dvb        dvb;
+	struct videobuf_dvb_frontends frontends;
 #endif
 
 #if defined(CONFIG_VIDEO_CX88_VP3054) || \
@@ -628,6 +630,7 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl);
 #define WW_EIAJ		 7
 #define WW_I2SPT	 8
 #define WW_FM		 9
+#define WW_I2SADC	 10
 
 void cx88_set_tvaudio(struct cx88_core *core);
 void cx88_newstation(struct cx88_core *core);

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

@@ -21,6 +21,7 @@
 #define MODULE_NAME "gspca"
 
 #include <linux/init.h>
+#include <linux/version.h>
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
 #include <linux/sched.h>
@@ -403,7 +404,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
 	unsigned int i;
 
 	PDEBUG(D_STREAM, "kill transfer");
-	for (i = 0; i < MAX_NURBS; ++i) {
+	for (i = 0; i < MAX_NURBS; i++) {
 		urb = gspca_dev->urb[i];
 		if (urb == NULL)
 			break;

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

@@ -2,7 +2,6 @@
 #define GSPCAV2_H
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>

+ 1 - 28
drivers/media/video/gspca/m5602/m5602_bridge.h

@@ -1,7 +1,7 @@
 /*
  * USB Driver for ALi m5602 based webcams
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -25,33 +25,6 @@
 
 /*****************************************************************************/
 
-#undef PDEBUG
-#undef info
-#undef err
-
-#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \
-	format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \
-	format "\n" , ## arg)
-
-/* Debug parameters */
-#define DBG_INIT 0x1
-#define DBG_PROBE 0x2
-#define DBG_V4L2 0x4
-#define DBG_TRACE 0x8
-#define DBG_DATA 0x10
-#define DBG_V4L2_CID 0x20
-#define DBG_GSPCA 0x40
-
-#define PDEBUG(level, fmt, args...) \
-	do { \
-		if (m5602_debug & level)     \
-			info("[%s:%d] " fmt, __func__, __LINE__ , \
-			## args); \
-	} while (0)
-
-/*****************************************************************************/
-
 #define M5602_XB_SENSOR_TYPE 0x00
 #define M5602_XB_SENSOR_CTRL 0x01
 #define M5602_XB_LINE_OF_FRAME_H 0x02

+ 21 - 25
drivers/media/video/gspca/m5602/m5602_core.c

@@ -1,7 +1,7 @@
-/*
+ /*
  * USB Driver for ALi m5602 based webcams
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -26,7 +26,6 @@
 int force_sensor;
 int dump_bridge;
 int dump_sensor;
-unsigned int m5602_debug;
 
 static const __devinitdata struct usb_device_id m5602_table[] = {
 	{USB_DEVICE(0x0402, 0x5602)},
@@ -48,7 +47,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
 			      1, M5602_URB_MSG_TIMEOUT);
 	*i2c_data = buf[0];
 
-	PDEBUG(DBG_TRACE, "Reading bridge register 0x%x containing 0x%x",
+	PDEBUG(D_CONF, "Reading bridge register 0x%x containing 0x%x",
 	       address, *i2c_data);
 
 	/* usb_control_msg(...) returns the number of bytes sent upon success,
@@ -63,7 +62,7 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
 	struct usb_device *udev = sd->gspca_dev.dev;
 	__u8 *buf = sd->gspca_dev.usb_buf;
 
-	PDEBUG(DBG_TRACE, "Writing bridge register 0x%x with 0x%x",
+	PDEBUG(D_CONF, "Writing bridge register 0x%x with 0x%x",
 	       address, i2c_data);
 
 	memcpy(buf, bridge_urb_skeleton,
@@ -91,7 +90,8 @@ static void m5602_dump_bridge(struct sd *sd)
 		m5602_read_bridge(sd, i, &val);
 		info("ALi m5602 address 0x%x contains 0x%x", i, val);
 	}
-	info("Warning: The camera probably won't work until it's power cycled");
+	info("Warning: The ALi m5602 webcam probably won't work "
+		"until it's power cycled");
 }
 
 static int m5602_probe_sensor(struct sd *sd)
@@ -135,7 +135,7 @@ static int m5602_init(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 	int err;
 
-	PDEBUG(DBG_TRACE, "Initializing ALi m5602 webcam");
+	PDEBUG(D_CONF, "Initializing ALi m5602 webcam");
 	/* Run the init sequence */
 	err = sd->sensor->init(sd);
 
@@ -146,16 +146,18 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u8 *buf = sd->gspca_dev.usb_buf;
+	int err;
 
 	/* Send start command to the camera */
 	const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01};
 	memcpy(buf, buffer, sizeof(buffer));
-	usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
-			0x04, 0x40, 0x19, 0x0000, buf,
-			4, M5602_URB_MSG_TIMEOUT);
+	err = usb_control_msg(gspca_dev->dev,
+			      usb_sndctrlpipe(gspca_dev->dev, 0),
+			      0x04, 0x40, 0x19, 0x0000, buf,
+			      4, M5602_URB_MSG_TIMEOUT);
 
-	PDEBUG(DBG_V4L2, "Transfer started");
-	return 0;
+	PDEBUG(D_STREAM, "Transfer started");
+	return (err < 0) ? err : 0;
 }
 
 static void m5602_urb_complete(struct gspca_dev *gspca_dev,
@@ -165,14 +167,14 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	if (len < 6) {
-		PDEBUG(DBG_DATA, "Packet is less than 6 bytes");
+		PDEBUG(D_PACK, "Packet is less than 6 bytes");
 		return;
 	}
 
 	/* Frame delimiter: ff xx xx xx ff ff */
 	if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff &&
 	    data[2] != sd->frame_id) {
-		PDEBUG(DBG_DATA, "Frame delimiter detected");
+		PDEBUG(D_FRAM, "Frame delimiter detected");
 		sd->frame_id = data[2];
 
 		/* Remove the extra fluff appended on each header */
@@ -187,7 +189,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
 		/* Create a new frame */
 		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
 
-		PDEBUG(DBG_V4L2, "Starting new frame %d",
+		PDEBUG(D_FRAM, "Starting new frame %d",
 		       sd->frame_count);
 
 	} else {
@@ -198,7 +200,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
 		len -= 4;
 
 		if (cur_frame_len + len <= frame->v4l2_buf.length) {
-			PDEBUG(DBG_DATA, "Continuing frame %d copying %d bytes",
+			PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
 			       sd->frame_count, len);
 
 			gspca_frame_add(gspca_dev, INTER_PACKET, frame,
@@ -234,8 +236,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
 	struct cam *cam;
 	int err;
 
-	PDEBUG(DBG_GSPCA, "m5602_configure start");
-
 	cam = &gspca_dev->cam;
 	cam->epaddr = M5602_ISOC_ENDPOINT_ADDR;
 	sd->desc = &sd_desc;
@@ -248,11 +248,10 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
 	if (err)
 		goto fail;
 
-	PDEBUG(DBG_GSPCA, "m5602_configure end");
 	return 0;
 
 fail:
-	PDEBUG(DBG_GSPCA, "m5602_configure failed");
+	PDEBUG(D_ERR, "ALi m5602 webcam failed");
 	cam->cam_mode = NULL;
 	cam->nmodes = 0;
 
@@ -282,13 +281,13 @@ static int __init mod_m5602_init(void)
 {
 	if (usb_register(&sd_driver) < 0)
 		return -1;
-	PDEBUG(D_PROBE, "m5602 module registered");
+	PDEBUG(D_PROBE, "registered");
 	return 0;
 }
 static void __exit mod_m5602_exit(void)
 {
 	usb_deregister(&sd_driver);
-	PDEBUG(D_PROBE, "m5602 module deregistered");
+	PDEBUG(D_PROBE, "deregistered");
 }
 
 module_init(mod_m5602_init);
@@ -297,9 +296,6 @@ module_exit(mod_m5602_exit);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
-module_param_named(debug, m5602_debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "toggles debug on/off");
-
 module_param(force_sensor, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(force_sensor,
 		"force detection of sensor, "

+ 9 - 9
drivers/media/video/gspca/m5602/m5602_mt9m111.c

@@ -1,7 +1,7 @@
 /*
  * Driver for the mt9m111 sensor
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -107,7 +107,7 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 	err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
 				  data, 2);
 	*val = data[0] & MT9M111_RMB_MIRROR_ROWS;
-	PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
+	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -118,7 +118,7 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data[2] = {0x00, 0x00};
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
+	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
 
 	/* Set the correct page map */
 	err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -145,7 +145,7 @@ int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 	err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
 				  data, 2);
 	*val = data[0] & MT9M111_RMB_MIRROR_COLS;
-	PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
+	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -156,7 +156,7 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data[2] = {0x00, 0x00};
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val);
+	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
 
 	/* Set the correct page map */
 	err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -188,7 +188,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 	      ((tmp & (1 <<  8)) * 2) |
 	       (tmp & 0x7f);
 
-	PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+	PDEBUG(D_V4L2, "Read gain %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -222,7 +222,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 
 	data[1] = (tmp & 0xff00) >> 8;
 	data[0] = (tmp & 0xff);
-	PDEBUG(DBG_V4L2_CID, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
+	PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
 	       data[1], data[0]);
 
 	err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
@@ -257,7 +257,7 @@ int mt9m111_read_sensor(struct sd *sd, const u8 address,
 	for (i = 0; i < len && !err; i++) {
 		err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
 
-		PDEBUG(DBG_TRACE, "Reading sensor register "
+		PDEBUG(D_CONF, "Reading sensor register "
 		       "0x%x contains 0x%x ", address, *i2c_data);
 	}
 out:
@@ -290,7 +290,7 @@ int mt9m111_write_sensor(struct sd *sd, const u8 address,
 		memcpy(p, sensor_urb_skeleton + 16, 4);
 		p[3] = i2c_data[i];
 		p += 4;
-		PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+		PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
 		       address, i2c_data[i]);
 	}
 

+ 3 - 4
drivers/media/video/gspca/m5602/m5602_mt9m111.h

@@ -1,7 +1,7 @@
 /*
  * Driver for the mt9m111 sensor
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -82,7 +82,6 @@
 /* Kernel module parameters */
 extern int force_sensor;
 extern int dump_sensor;
-extern unsigned int m5602_debug;
 
 int mt9m111_probe(struct sd *sd);
 int mt9m111_init(struct sd *sd);
@@ -152,8 +151,8 @@ static struct m5602_sensor mt9m111 = {
 			.default_value  = DEFAULT_GAIN,
 			.flags          = V4L2_CTRL_FLAG_SLIDER
 		},
-		.set = mt9m111_set_hflip,
-		.get = mt9m111_get_hflip
+		.set = mt9m111_set_gain,
+		.get = mt9m111_get_gain
 	}
 	},
 

+ 20 - 20
drivers/media/video/gspca/m5602/m5602_ov9650.c

@@ -1,7 +1,7 @@
 /*
  * Driver for the ov9650 sensor
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -40,7 +40,7 @@ int ov9650_read_sensor(struct sd *sd, const u8 address,
 	for (i = 0; i < len; i++) {
 		err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
 
-		PDEBUG(DBG_TRACE, "Reading sensor register "
+		PDEBUG(D_CONF, "Reading sensor register "
 				"0x%x containing 0x%x ", address, *i2c_data);
 	}
 	return (err < 0) ? err : 0;
@@ -72,7 +72,7 @@ int ov9650_write_sensor(struct sd *sd, const u8 address,
 		memcpy(p, sensor_urb_skeleton + 16, 4);
 		p[3] = i2c_data[i];
 		p += 4;
-		PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+		PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
 		       address, i2c_data[i]);
 	}
 
@@ -199,7 +199,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 		goto out;
 	*val |= (i2c_data & 0x3f) << 10;
 
-	PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val);
+	PDEBUG(D_V4L2, "Read exposure %d", *val);
 out:
 	return (err < 0) ? err : 0;
 }
@@ -210,7 +210,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	int err;
 
-	PDEBUG(DBG_V4L2_CID, "Set exposure to %d",
+	PDEBUG(D_V4L2, "Set exposure to %d",
 	       val & 0xffff);
 
 	/* The 6 MSBs */
@@ -246,7 +246,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 
 	err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
 	*val |= i2c_data;
-	PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+	PDEBUG(D_V4L2, "Read gain %d", *val);
 	return (err < 0) ? err : 0;
 }
 
@@ -280,7 +280,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1);
 	*val = i2c_data;
 
-	PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val);
+	PDEBUG(D_V4L2, "Read red gain %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -291,7 +291,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(DBG_V4L2_CID, "Set red gain to %d",
+	PDEBUG(D_V4L2, "Set red gain to %d",
 			     val & 0xff);
 
 	i2c_data = val & 0xff;
@@ -309,7 +309,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1);
 	*val = i2c_data;
 
-	PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val);
+	PDEBUG(D_V4L2, "Read blue gain %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -320,7 +320,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(DBG_V4L2_CID, "Set blue gain to %d",
+	PDEBUG(D_V4L2, "Set blue gain to %d",
 	       val & 0xff);
 
 	i2c_data = val & 0xff;
@@ -340,7 +340,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 		*val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1;
 	else
 		*val = (i2c_data & OV9650_HFLIP) >> 5;
-	PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
+	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -351,7 +351,7 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val);
+	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
 	err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
 	if (err < 0)
 		goto out;
@@ -379,7 +379,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 		*val = ((i2c_data & 0x10) >> 4) ? 0 : 1;
 	else
 		*val = (i2c_data & 0x10) >> 4;
-	PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
+	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -390,7 +390,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
+	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
 	err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
 	if (err < 0)
 		goto out;
@@ -420,7 +420,7 @@ int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
 
 	err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
 	*val |= i2c_data;
-	PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+	PDEBUG(D_V4L2, "Read gain %d", *val);
 out:
 	return (err < 0) ? err : 0;
 }
@@ -431,7 +431,7 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(DBG_V4L2_CID, "Set gain to %d", val & 0x3ff);
+	PDEBUG(D_V4L2, "Set gain to %d", val & 0x3ff);
 
 	/* Read the OV9650_VREF register first to avoid
 		corrupting the VREF high and low bits */
@@ -461,7 +461,7 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
 
 	err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 	*val = (i2c_data & OV9650_AWB_EN) >> 1;
-	PDEBUG(DBG_V4L2_CID, "Read auto white balance %d", *val);
+	PDEBUG(D_V4L2, "Read auto white balance %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -472,7 +472,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(DBG_V4L2_CID, "Set auto white balance to %d", val);
+	PDEBUG(D_V4L2, "Set auto white balance to %d", val);
 	err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 	if (err < 0)
 		goto out;
@@ -491,7 +491,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
 
 	err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 	*val = (i2c_data & OV9650_AGC_EN) >> 2;
-	PDEBUG(DBG_V4L2_CID, "Read auto gain control %d", *val);
+	PDEBUG(D_V4L2, "Read auto gain control %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -502,7 +502,7 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(DBG_V4L2_CID, "Set auto gain control to %d", val);
+	PDEBUG(D_V4L2, "Set auto gain control to %d", val);
 	err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 	if (err < 0)
 		goto out;

+ 1 - 2
drivers/media/video/gspca/m5602/m5602_ov9650.h

@@ -1,7 +1,7 @@
 /*
  * Driver for the ov9650 sensor
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -121,7 +121,6 @@
 /* Kernel module parameters */
 extern int force_sensor;
 extern int dump_sensor;
-extern unsigned int m5602_debug;
 
 int ov9650_probe(struct sd *sd);
 int ov9650_init(struct sd *sd);

+ 77 - 13
drivers/media/video/gspca/m5602/m5602_po1030.c

@@ -1,7 +1,7 @@
 /*
  * Driver for the po1030 sensor
  *
- * Copyright (c) 2008 Erik Andren
+ * Copyright (c) 2008 Erik Andrén
  * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -82,7 +82,7 @@ int po1030_read_sensor(struct sd *sd, const u8 address,
 	for (i = 0; i < len; i++) {
 		err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
 
-		PDEBUG(DBG_TRACE, "Reading sensor register "
+		PDEBUG(D_CONF, "Reading sensor register "
 				"0x%x containing 0x%x ", address, *i2c_data);
 	}
 	return (err < 0) ? err : 0;
@@ -112,7 +112,7 @@ int po1030_write_sensor(struct sd *sd, const u8 address,
 		memcpy(p, sensor_urb_skeleton + 16, 4);
 		p[3] = i2c_data[i];
 		p += 4;
-		PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+		PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
 		       address, i2c_data[i]);
 	}
 
@@ -185,7 +185,7 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 				 &i2c_data, 1);
 	*val |= i2c_data;
 
-	PDEBUG(DBG_V4L2_CID, "Exposure read as %d", *val);
+	PDEBUG(D_V4L2, "Exposure read as %d", *val);
 out:
 	return (err < 0) ? err : 0;
 }
@@ -196,10 +196,10 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	int err;
 
-	PDEBUG(DBG_V4L2, "Set exposure to %d", val & 0xffff);
+	PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
 
 	i2c_data = ((val & 0xff00) >> 8);
-	PDEBUG(DBG_V4L2, "Set exposure to high byte to 0x%x",
+	PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
 	       i2c_data);
 
 	err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H,
@@ -208,7 +208,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 		goto out;
 
 	i2c_data = (val & 0xff);
-	PDEBUG(DBG_V4L2, "Set exposure to low byte to 0x%x",
+	PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
 	       i2c_data);
 	err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M,
 				  &i2c_data, 1);
@@ -226,7 +226,71 @@ int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 	err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
 				 &i2c_data, 1);
 	*val = i2c_data;
-	PDEBUG(DBG_V4L2_CID, "Read global gain %d", *val);
+	PDEBUG(D_V4L2, "Read global gain %d", *val);
+
+	return (err < 0) ? err : 0;
+}
+
+int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 i2c_data;
+	int err;
+
+	err = po1030_read_sensor(sd, PO1030_REG_CONTROL2,
+				 &i2c_data, 1);
+
+	*val = (i2c_data >> 7) & 0x01 ;
+
+	PDEBUG(D_V4L2, "Read hflip %d", *val);
+
+	return (err < 0) ? err : 0;
+}
+
+int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 i2c_data;
+	int err;
+
+	PDEBUG(D_V4L2, "Set hflip %d", val);
+
+	i2c_data = (val & 0x01) << 7;
+
+	err = po1030_write_sensor(sd, PO1030_REG_CONTROL2,
+				  &i2c_data, 1);
+
+	return (err < 0) ? err : 0;
+}
+
+int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 i2c_data;
+	int err;
+
+	err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
+				 &i2c_data, 1);
+
+	*val = (i2c_data >> 6) & 0x01;
+
+	PDEBUG(D_V4L2, "Read vflip %d", *val);
+
+	return (err < 0) ? err : 0;
+}
+
+int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 i2c_data;
+	int err;
+
+	PDEBUG(D_V4L2, "Set vflip %d", val);
+
+	i2c_data = (val & 0x01) << 6;
+
+	err = po1030_write_sensor(sd, PO1030_REG_CONTROL2,
+				  &i2c_data, 1);
 
 	return (err < 0) ? err : 0;
 }
@@ -238,7 +302,7 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 
 	i2c_data = val & 0xff;
-	PDEBUG(DBG_V4L2, "Set global gain to %d", i2c_data);
+	PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
 	err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN,
 				  &i2c_data, 1);
 	return (err < 0) ? err : 0;
@@ -253,7 +317,7 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN,
 				 &i2c_data, 1);
 	*val = i2c_data;
-	PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val);
+	PDEBUG(D_V4L2, "Read red gain %d", *val);
 	return (err < 0) ? err : 0;
 }
 
@@ -264,7 +328,7 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 
 	i2c_data = val & 0xff;
-	PDEBUG(DBG_V4L2, "Set red gain to %d", i2c_data);
+	PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
 	err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN,
 				  &i2c_data, 1);
 	return (err < 0) ? err : 0;
@@ -279,7 +343,7 @@ int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 	err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN,
 				 &i2c_data, 1);
 	*val = i2c_data;
-	PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val);
+	PDEBUG(D_V4L2, "Read blue gain %d", *val);
 
 	return (err < 0) ? err : 0;
 }
@@ -290,7 +354,7 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	int err;
 	i2c_data = val & 0xff;
-	PDEBUG(DBG_V4L2, "Set blue gain to %d", i2c_data);
+	PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
 	err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN,
 				  &i2c_data, 1);
 

+ 38 - 8
drivers/media/video/gspca/m5602/m5602_po1030.h

@@ -1,8 +1,7 @@
 /*
  * Driver for the po1030 sensor.
- * This is probably a pixel plus sensor but we haven't identified it yet
  *
- * Copyright (c) 2008 Erik Andren
+ * Copyright (c) 2008 Erik Andrén
  * Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -109,10 +108,13 @@
 #define PO1030_REG_YCONTRAST		0x74
 #define PO1030_REG_YSATURATION		0x75
 
+#define PO1030_HFLIP			(1 << 7)
+#define PO1030_VFLIP			(1 << 6)
+
 /*****************************************************************************/
 
 #define PO1030_GLOBAL_GAIN_DEFAULT	0x12
-#define PO1030_EXPOSURE_DEFAULT		0xf0ff
+#define PO1030_EXPOSURE_DEFAULT		0x0085
 #define PO1030_BLUE_GAIN_DEFAULT 	0x40
 #define PO1030_RED_GAIN_DEFAULT 	0x40
 
@@ -121,7 +123,6 @@
 /* Kernel module parameters */
 extern int force_sensor;
 extern int dump_sensor;
-extern unsigned int m5602_debug;
 
 int po1030_probe(struct sd *sd);
 int po1030_init(struct sd *sd);
@@ -142,6 +143,10 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
 int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
 int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
 int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
 
 static struct m5602_sensor po1030 = {
 	.name = "PO1030",
@@ -152,7 +157,7 @@ static struct m5602_sensor po1030 = {
 	.init = po1030_init,
 	.power_down = po1030_power_down,
 
-	.nctrls = 4,
+	.nctrls = 6,
 	.ctrls = {
 	{
 		{
@@ -160,7 +165,7 @@ static struct m5602_sensor po1030 = {
 			.type 		= V4L2_CTRL_TYPE_INTEGER,
 			.name 		= "gain",
 			.minimum 	= 0x00,
-			.maximum 	= 0xff,
+			.maximum 	= 0x4f,
 			.step 		= 0x1,
 			.default_value 	= PO1030_GLOBAL_GAIN_DEFAULT,
 			.flags         	= V4L2_CTRL_FLAG_SLIDER
@@ -173,7 +178,7 @@ static struct m5602_sensor po1030 = {
 			.type 		= V4L2_CTRL_TYPE_INTEGER,
 			.name 		= "exposure",
 			.minimum 	= 0x00,
-			.maximum 	= 0xffff,
+			.maximum 	= 0x02ff,
 			.step 		= 0x1,
 			.default_value 	= PO1030_EXPOSURE_DEFAULT,
 			.flags         	= V4L2_CTRL_FLAG_SLIDER
@@ -206,8 +211,33 @@ static struct m5602_sensor po1030 = {
 		},
 		.set = po1030_set_blue_balance,
 		.get = po1030_get_blue_balance
+	}, {
+		{
+			.id 		= V4L2_CID_HFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "horizontal flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0,
+		},
+		.set = po1030_set_hflip,
+		.get = po1030_get_hflip
+	}, {
+		{
+			.id 		= V4L2_CID_VFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "vertical flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0,
+		},
+		.set = po1030_set_vflip,
+		.get = po1030_get_vflip
 	}
 	},
+
 	.nmodes = 1,
 	.modes = {
 	{
@@ -381,7 +411,7 @@ static const unsigned char init_po1030[][4] =
 
 	/* Set the y window to 1 */
 	{SENSOR, PO1030_REG_WINDOWY_H, 0x00},
-	{SENSOR, PO1030_REG_WINDOWX_L, 0x01},
+	{SENSOR, PO1030_REG_WINDOWY_L, 0x01},
 
 	{SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02},
 	{SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87},

+ 11 - 11
drivers/media/video/gspca/m5602/m5602_s5k4aa.c

@@ -1,7 +1,7 @@
 /*
  * Driver for the s5k4aa sensor
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -117,7 +117,7 @@ int s5k4aa_read_sensor(struct sd *sd, const u8 address,
 	for (i = 0; (i < len) & !err; i++) {
 		err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
 
-		PDEBUG(DBG_TRACE, "Reading sensor register "
+		PDEBUG(D_CONF, "Reading sensor register "
 				  "0x%x containing 0x%x ", address, *i2c_data);
 	}
 out:
@@ -150,7 +150,7 @@ int s5k4aa_write_sensor(struct sd *sd, const u8 address,
 		memcpy(p, sensor_urb_skeleton + 16, 4);
 		p[3] = i2c_data[i];
 		p += 4;
-		PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+		PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
 		       address, i2c_data[i]);
 	}
 
@@ -248,7 +248,7 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 	*val = data << 8;
 	err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
 	*val |= data;
-	PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val);
+	PDEBUG(D_V4L2, "Read exposure %d", *val);
 out:
 	return (err < 0) ? err : 0;
 }
@@ -259,7 +259,7 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
-	PDEBUG(DBG_V4L2_CID, "Set exposure to %d", val);
+	PDEBUG(D_V4L2, "Set exposure to %d", val);
 	err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
 		goto out;
@@ -285,7 +285,7 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 
 	err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	*val = (data & S5K4AA_RM_V_FLIP) >> 7;
-	PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
+	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
 
 out:
 	return (err < 0) ? err : 0;
@@ -297,7 +297,7 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
-	PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
+	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
 	err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
 		goto out;
@@ -341,7 +341,7 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 
 	err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	*val = (data & S5K4AA_RM_H_FLIP) >> 6;
-	PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
+	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
 out:
 	return (err < 0) ? err : 0;
 }
@@ -352,7 +352,7 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
-	PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d",
+	PDEBUG(D_V4L2, "Set horizontal flip to %d",
 	       val);
 	err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
@@ -397,7 +397,7 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 
 	err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
 	*val = data;
-	PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+	PDEBUG(D_V4L2, "Read gain %d", *val);
 
 out:
 	return (err < 0) ? err : 0;
@@ -409,7 +409,7 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
-	PDEBUG(DBG_V4L2_CID, "Set gain to %d", val);
+	PDEBUG(D_V4L2, "Set gain to %d", val);
 	err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
 		goto out;

+ 1 - 2
drivers/media/video/gspca/m5602/m5602_s5k4aa.h

@@ -1,7 +1,7 @@
 /*
  * Driver for the s5k4aa sensor
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -63,7 +63,6 @@
 /* Kernel module parameters */
 extern int force_sensor;
 extern int dump_sensor;
-extern unsigned int m5602_debug;
 
 int s5k4aa_probe(struct sd *sd);
 int s5k4aa_init(struct sd *sd);

+ 3 - 3
drivers/media/video/gspca/m5602/m5602_s5k83a.c

@@ -1,7 +1,7 @@
 /*
  * Driver for the s5k83a sensor
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -101,7 +101,7 @@ int s5k83a_read_sensor(struct sd *sd, const u8 address,
 	for (i = 0; i < len && !len; i++) {
 		err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
 
-		PDEBUG(DBG_TRACE, "Reading sensor register "
+		PDEBUG(D_CONF, "Reading sensor register "
 				  "0x%x containing 0x%x ", address, *i2c_data);
 	}
 
@@ -135,7 +135,7 @@ int s5k83a_write_sensor(struct sd *sd, const u8 address,
 		memcpy(p, sensor_urb_skeleton + 16, 4);
 		p[3] = i2c_data[i];
 		p += 4;
-		PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+		PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
 		       address, i2c_data[i]);
 	}
 

+ 1 - 3
drivers/media/video/gspca/m5602/m5602_s5k83a.h

@@ -1,7 +1,7 @@
 /*
  * Driver for the s5k83a sensor
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *
@@ -41,8 +41,6 @@
 /* Kernel module parameters */
 extern int force_sensor;
 extern int dump_sensor;
-extern unsigned int m5602_debug;
-
 
 int s5k83a_probe(struct sd *sd);
 int s5k83a_init(struct sd *sd);

+ 1 - 1
drivers/media/video/gspca/m5602/m5602_sensor.h

@@ -1,7 +1,7 @@
 /*
  * USB Driver for ALi m5602 based webcams
  *
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
  *

+ 239 - 136
drivers/media/video/gspca/t613.c

@@ -50,7 +50,7 @@ struct sd {
 
 	__u8 sensor;
 #define SENSOR_TAS5130A 0
-#define SENSOR_OTHER 1
+#define SENSOR_OM6802 1
 };
 
 /* V4L2 controls supported by the driver */
@@ -188,7 +188,7 @@ static struct ctrl sd_ctrls[] = {
 	  .minimum = 0,
 	  .maximum = 1,
 	  .step = 1,
-	  .default_value = 1,
+	  .default_value = 0,
 	  },
 	 .set = sd_setwhitebalance,
 	 .get = sd_getwhitebalance
@@ -261,6 +261,59 @@ static struct v4l2_pix_format vga_mode_t16[] = {
 		.priv = 0},
 };
 
+/* sensor specific data */
+struct additional_sensor_data {
+	const __u8 data1[20];
+	const __u8 data2[18];
+	const __u8 data3[18];
+	const __u8 data4[4];
+	const __u8 data5[6];
+	const __u8 stream[4];
+};
+
+const static struct additional_sensor_data sensor_data[] = {
+    {				/* TAS5130A */
+	.data1 =
+		{0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
+		 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
+		 0xd8, 0xc8, 0xd9, 0xfc},
+	.data2 =
+		{0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
+		 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
+		 0xe8, 0xe0},
+	.data3 =
+		{0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
+		 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
+		 0xcf, 0xe0},
+	.data4 =	/* Freq (50/60Hz). Splitted for test purpose */
+		{0x66, 0x00, 0xa8, 0xe8},
+	.data5 =
+		{0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
+	.stream =
+		{0x0b, 0x04, 0x0a, 0x40},
+    },
+    {				/* OM6802 */
+	.data1 =
+		{0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
+		 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
+		 0xd8, 0xb3, 0xd9, 0xfc},
+	.data2 =
+		{0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
+		 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
+		 0xe8, 0xff},
+	.data3 =
+		{0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
+		 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
+		 0xcf, 0xff},
+	.data4 =	/*Freq (50/60Hz). Splitted for test purpose */
+		{0x66, 0xca, 0xa8, 0xf0 },
+	.data5 =	/* this could be removed later */
+		{0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
+	.stream =
+		{0x0b, 0x04, 0x0a, 0x78},
+    }
+};
+
 #define MAX_EFFECTS 7
 /* easily done by soft, this table could be removed,
  * i keep it here just in case */
@@ -365,6 +418,8 @@ static const __u8 tas5130a_sensor_init[][8] = {
 	{},
 };
 
+static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
+
 /* read 1 byte */
 static int reg_r(struct gspca_dev *gspca_dev,
 		   __u16 index)
@@ -385,12 +440,12 @@ static void reg_w(struct gspca_dev *gspca_dev,
 	usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			0,
-			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			0, index,
 			NULL, 0, 500);
 }
 
-static void i2c_w(struct gspca_dev *gspca_dev,
+static void reg_w_buf(struct gspca_dev *gspca_dev,
 		  const __u8 *buffer, __u16 len)
 {
 	if (len <= USB_BUF_SZ) {
@@ -398,7 +453,7 @@ static void i2c_w(struct gspca_dev *gspca_dev,
 		usb_control_msg(gspca_dev->dev,
 				usb_sndctrlpipe(gspca_dev->dev, 0),
 				0,
-			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 				0x01, 0,
 				gspca_dev->usb_buf, len, 500);
 	} else {
@@ -409,14 +464,15 @@ static void i2c_w(struct gspca_dev *gspca_dev,
 		usb_control_msg(gspca_dev->dev,
 				usb_sndctrlpipe(gspca_dev->dev, 0),
 				0,
-			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 				0x01, 0,
 				tmpbuf, len, 500);
 		kfree(tmpbuf);
 	}
 }
 
-static void other_sensor_init(struct gspca_dev *gspca_dev)
+/* Reported as OM6802*/
+static void om6802_sensor_init(struct gspca_dev *gspca_dev)
 {
 	int i;
 	const __u8 *p;
@@ -436,19 +492,32 @@ static void other_sensor_init(struct gspca_dev *gspca_dev)
 		0x90, 0x24,
 		0x91, 0xb2,
 		0x82, 0x32,
-		0xfd, 0x00,
-		0xfd, 0x01,
 		0xfd, 0x41,
 		0x00			/* table end */
 	};
 
+	reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
+	msleep(5);
+	i = 4;
+	while (--i < 0) {
+		byte = reg_r(gspca_dev, 0x0060);
+		if (!(byte & 0x01))
+			break;
+		msleep(100);
+	}
+	byte = reg_r(gspca_dev, 0x0063);
+	if (byte != 0x17) {
+		err("Bad sensor reset %02x", byte);
+		/* continue? */
+	}
+
 	p = sensor_init;
 	while (*p != 0) {
 		val[1] = *p++;
 		val[3] = *p++;
 		if (*p == 0)
 			reg_w(gspca_dev, 0x3c80);
-		i2c_w(gspca_dev, val, sizeof val);
+		reg_w_buf(gspca_dev, val, sizeof val);
 		i = 4;
 		while (--i >= 0) {
 			msleep(15);
@@ -457,7 +526,8 @@ static void other_sensor_init(struct gspca_dev *gspca_dev)
 				break;
 		}
 	}
-			reg_w(gspca_dev, 0x3c80);
+	msleep(15);
+	reg_w(gspca_dev, 0x3c80);
 }
 
 /* this function is called at probe time */
@@ -485,12 +555,75 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	return 0;
 }
 
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	unsigned int brightness;
+	__u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
+
+	brightness = sd->brightness;
+	if (brightness < 7) {
+		set6[1] = 0x26;
+		set6[3] = 0x70 - brightness * 0x10;
+	} else {
+		set6[3] = 0x00 + ((brightness - 7) * 0x10);
+	}
+
+	reg_w_buf(gspca_dev, set6, sizeof set6);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	unsigned int contrast = sd->contrast;
+	__u16 reg_to_write;
+
+	if (contrast < 7)
+		reg_to_write = 0x8ea9 - contrast * 0x200;
+	else
+		reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
+
+	reg_w(gspca_dev, reg_to_write);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	__u16 reg_to_write;
+
+	reg_to_write = 0x80bb + sd->colors * 0x100;	/* was 0xc0 */
+	reg_w(gspca_dev, reg_to_write);
+}
+
 static void setgamma(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
-	i2c_w(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+	reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+}
+
+static void setwhitebalance(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	__u8 white_balance[8] =
+		{0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
+
+	if (sd->whitebalance)
+		white_balance[7] = 0x3c;
+
+	reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
+}
+
+static void setsharpness(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	__u16 reg_to_write;
+
+	reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
+
+	reg_w(gspca_dev, reg_to_write);
 }
 
 /* this function is called at probe and resume time */
@@ -511,8 +644,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
 			{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
 	static const __u8 n2[] =
 			{0x08, 0x00};
-	static const __u8 nset[] =
-			{ 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
 	static const __u8 n3[] =
 			{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
 	static const __u8 n4[] =
@@ -525,51 +656,29 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
 		 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
 		 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
-	static const __u8 nset4[] = {
-		0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
-		0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
-		0xe8, 0xe0
-	};
-	/* ojo puede ser 0xe6 en vez de 0xe9 */
-	static const __u8 nset2[] = {
-		0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
-		0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
-		0xd8, 0xc8, 0xd9, 0xfc
-	};
-	static const __u8 missing[] =
-		{ 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
-	static const __u8 nset3[] = {
-		0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
-		0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
-		0xcf, 0xe0
-	};
-	static const __u8 nset5[] =
-			{ 0x8f, 0x24, 0xc3, 0x00 };	/* bright */
-	static const __u8 nset7[4] =
-			{ 0x66, 0xca, 0xa8, 0xf8 };	/* 50/60 Hz */
 	static const __u8 nset9[4] =
 			{ 0x0b, 0x04, 0x0a, 0x78 };
 	static const __u8 nset8[6] =
 			{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
-	static const __u8 nset10[6] =
-			{ 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
 
 	byte = reg_r(gspca_dev, 0x06);
 	test_byte = reg_r(gspca_dev, 0x07);
 	if (byte == 0x08 && test_byte == 0x07) {
-		PDEBUG(D_CONF, "other sensor");
-		sd->sensor = SENSOR_OTHER;
+		PDEBUG(D_CONF, "sensor om6802");
+		sd->sensor = SENSOR_OM6802;
+	} else if (byte == 0x08 && test_byte == 0x01) {
+		PDEBUG(D_CONF, "sensor tas5130a");
+		sd->sensor = SENSOR_TAS5130A;
 	} else {
-		PDEBUG(D_CONF, "sensor %02x %02x", byte, test_byte);
+		PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
 		sd->sensor = SENSOR_TAS5130A;
 	}
 
-	i2c_w(gspca_dev, n1, sizeof n1);
+	reg_w_buf(gspca_dev, n1, sizeof n1);
 	test_byte = 0;
 	i = 5;
 	while (--i >= 0) {
-		i2c_w(gspca_dev, nset, sizeof nset);
-		msleep(5);
+		reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
 		test_byte = reg_r(gspca_dev, 0x0063);
 		msleep(100);
 		if (test_byte == 0x17)
@@ -580,7 +689,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 /*		return -EIO; */
 /*fixme: test - continue */
 	}
-	i2c_w(gspca_dev, n2, sizeof n2);
+	reg_w_buf(gspca_dev, n2, sizeof n2);
 
 	i = 0;
 	while (read_indexs[i] != 0x00) {
@@ -590,56 +699,50 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		i++;
 	}
 
-	i2c_w(gspca_dev, n3, sizeof n3);
-	i2c_w(gspca_dev, n4, sizeof n4);
+	reg_w_buf(gspca_dev, n3, sizeof n3);
+	reg_w_buf(gspca_dev, n4, sizeof n4);
 	reg_r(gspca_dev, 0x0080);
 	reg_w(gspca_dev, 0x2c80);
-	i2c_w(gspca_dev, nset2, sizeof nset2);
-	i2c_w(gspca_dev, nset3, sizeof nset3);
-	i2c_w(gspca_dev, nset4, sizeof nset4);
+
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+			sizeof sensor_data[sd->sensor].data1);
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
+			sizeof sensor_data[sd->sensor].data3);
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+			sizeof sensor_data[sd->sensor].data2);
+
 	reg_w(gspca_dev, 0x3880);
 	reg_w(gspca_dev, 0x3880);
 	reg_w(gspca_dev, 0x338e);
-	i2c_w(gspca_dev, nset5, sizeof nset5);
-	reg_w(gspca_dev, 0x00a9);
-	setgamma(gspca_dev);
-	reg_w(gspca_dev, 0x86bb);
-	reg_w(gspca_dev, 0x4aa6);
 
-	i2c_w(gspca_dev, missing, sizeof missing);
+	setbrightness(gspca_dev);
+	setcontrast(gspca_dev);
+	setgamma(gspca_dev);
+	setcolors(gspca_dev);
+	setsharpness(gspca_dev);
+	setwhitebalance(gspca_dev);
 
-	reg_w(gspca_dev, 0x2087);
+	reg_w(gspca_dev, 0x2087);	/* tied to white balance? */
 	reg_w(gspca_dev, 0x2088);
 	reg_w(gspca_dev, 0x2089);
 
-	i2c_w(gspca_dev, nset7, sizeof nset7);
-	i2c_w(gspca_dev, nset10, sizeof nset10);
-	i2c_w(gspca_dev, nset8, sizeof nset8);
-	i2c_w(gspca_dev, nset9, sizeof nset9);
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
+			sizeof sensor_data[sd->sensor].data4);
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
+			sizeof sensor_data[sd->sensor].data5);
+	reg_w_buf(gspca_dev, nset8, sizeof nset8);
+	reg_w_buf(gspca_dev, nset9, sizeof nset9);
 
 	reg_w(gspca_dev, 0x2880);
-	i2c_w(gspca_dev, nset2, sizeof nset2);
-	i2c_w(gspca_dev, nset3, sizeof nset3);
-	i2c_w(gspca_dev, nset4, sizeof nset4);
-
-	return 0;
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	unsigned int brightness;
-	__u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x00 };
 
-	brightness = sd->brightness;
-	if (brightness < 7) {
-		set6[3] = 0x70 - brightness * 0x10;
-	} else {
-		set6[1] = 0x24;
-		set6[3] = 0x00 + ((brightness - 7) * 0x10);
-	}
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+			sizeof sensor_data[sd->sensor].data1);
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
+			sizeof sensor_data[sd->sensor].data3);
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+			sizeof sensor_data[sd->sensor].data2);
 
-	i2c_w(gspca_dev, set6, sizeof set6);
+	return 0;
 }
 
 static void setflip(struct gspca_dev *gspca_dev)
@@ -651,14 +754,15 @@ static void setflip(struct gspca_dev *gspca_dev)
 	if (sd->mirror)
 		flipcmd[3] = 0x01;
 
-	i2c_w(gspca_dev, flipcmd, sizeof flipcmd);
+	reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
 }
 
 static void seteffect(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	i2c_w(gspca_dev, effects_table[sd->effect], sizeof effects_table[0]);
+	reg_w_buf(gspca_dev, effects_table[sd->effect],
+				sizeof effects_table[0]);
 	if (sd->effect == 1 || sd->effect == 5) {
 		PDEBUG(D_CONF,
 		       "This effect have been disabled for webcam \"safety\"");
@@ -671,19 +775,6 @@ static void seteffect(struct gspca_dev *gspca_dev)
 		reg_w(gspca_dev, 0xfaa6);
 }
 
-static void setwhitebalance(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	__u8 white_balance[8] =
-	    { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
-
-	if (sd->whitebalance == 1)
-		white_balance[7] = 0x3c;
-
-	i2c_w(gspca_dev, white_balance, sizeof white_balance);
-}
-
 static void setlightfreq(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -692,52 +783,46 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
 	if (sd->freq == 2)	/* 60hz */
 		freq[1] = 0x00;
 
-	i2c_w(gspca_dev, freq, sizeof freq);
+	reg_w_buf(gspca_dev, freq, sizeof freq);
 }
 
-static void setcontrast(struct gspca_dev *gspca_dev)
+/* Is this really needed?
+ * i added some module parameters for test with some users */
+static void poll_sensor(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	unsigned int contrast = sd->contrast;
-	__u16 reg_to_write;
-
-	if (contrast < 7)
-		reg_to_write = 0x8ea9 - (0x200 * contrast);
-	else
-		reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
-
-	reg_w(gspca_dev, reg_to_write);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	__u16 reg_to_write;
-
-	reg_to_write = 0xc0bb + sd->colors * 0x100;
-	reg_w(gspca_dev, reg_to_write);
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	__u16 reg_to_write;
-
-	reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
-
-	reg_w(gspca_dev, reg_to_write);
+	static const __u8 poll1[] =
+		{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
+		 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
+		 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
+		 0x60, 0x14};
+	static const __u8 poll2[] =
+		{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
+		 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
+	static const __u8 poll3[] =
+		{0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
+	static const __u8 poll4[] =
+		{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
+		 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
+		 0xc2, 0x80, 0xc3, 0x10};
+
+	if (sd->sensor != SENSOR_TAS5130A) {
+		PDEBUG(D_STREAM, "[Sensor requires polling]");
+		reg_w_buf(gspca_dev, poll1, sizeof poll1);
+		reg_w_buf(gspca_dev, poll2, sizeof poll2);
+		reg_w_buf(gspca_dev, poll3, sizeof poll3);
+		reg_w_buf(gspca_dev, poll4, sizeof poll4);
+	}
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i, mode;
-	static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
 	__u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
 	static const __u8 t3[] =
 		{ 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
 		  0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
-	static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
 
 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
 	switch (mode) {
@@ -760,25 +845,29 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	if (sd->sensor == SENSOR_TAS5130A) {
 		i = 0;
 		while (tas5130a_sensor_init[i][0] != 0) {
-			i2c_w(gspca_dev, tas5130a_sensor_init[i],
+			reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
 					 sizeof tas5130a_sensor_init[0]);
 			i++;
 		}
 		reg_w(gspca_dev, 0x3c80);
 		/* just in case and to keep sync with logs (for mine) */
-		i2c_w(gspca_dev, tas5130a_sensor_init[3],
+		reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
 				 sizeof tas5130a_sensor_init[0]);
 		reg_w(gspca_dev, 0x3c80);
 	} else {
-		other_sensor_init(gspca_dev);
+		om6802_sensor_init(gspca_dev);
 	}
-	/* just in case and to keep sync with logs  (for mine) */
-	i2c_w(gspca_dev, t1, sizeof t1);
-	i2c_w(gspca_dev, t2, sizeof t2);
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
+			sizeof sensor_data[sd->sensor].data4);
 	reg_r(gspca_dev, 0x0012);
-	i2c_w(gspca_dev, t3, sizeof t3);
+	reg_w_buf(gspca_dev, t2, sizeof t2);
+	reg_w_buf(gspca_dev, t3, sizeof t3);
 	reg_w(gspca_dev, 0x0013);
-	i2c_w(gspca_dev, t4, sizeof t4);
+	msleep(15);
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
+			sizeof sensor_data[sd->sensor].stream);
+	poll_sensor(gspca_dev);
+
 	/* restart on each start, just in case, sometimes regs goes wrong
 	 * when using controls from app */
 	setbrightness(gspca_dev);
@@ -787,6 +876,19 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	return 0;
 }
 
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
+			sizeof sensor_data[sd->sensor].stream);
+	msleep(20);
+	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
+			sizeof sensor_data[sd->sensor].stream);
+	msleep(20);
+	reg_w(gspca_dev, 0x0309);
+}
+
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
@@ -1036,6 +1138,7 @@ static const struct sd_desc sd_desc = {
 	.config = sd_config,
 	.init = sd_init,
 	.start = sd_start,
+	.stopN = sd_stopN,
 	.pkt_scan = sd_pkt_scan,
 	.querymenu = sd_querymenu,
 };

+ 8 - 7
drivers/media/video/ivtv/ivtv-fileops.c

@@ -600,13 +600,14 @@ retry:
 	since we may get here before the stream has been fully set-up */
 	if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) {
 		while (count >= itv->dma_data_req_size) {
-			if (!ivtv_yuv_udma_stream_frame (itv, (void __user *)user_buf)) {
-				bytes_written += itv->dma_data_req_size;
-				user_buf += itv->dma_data_req_size;
-				count -= itv->dma_data_req_size;
-			} else {
-				break;
-			}
+			rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf);
+
+			if (rc < 0)
+				return rc;
+
+			bytes_written += itv->dma_data_req_size;
+			user_buf += itv->dma_data_req_size;
+			count -= itv->dma_data_req_size;
 		}
 		if (count == 0) {
 			IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);

+ 16 - 2
drivers/media/video/ivtv/ivtv-ioctl.c

@@ -509,7 +509,6 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_
 static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
 {
 	struct ivtv_open_id *id = fh;
-	struct ivtv *itv = id->itv;
 	s32 w = fmt->fmt.pix.width;
 	s32 h = fmt->fmt.pix.height;
 	int field = fmt->fmt.pix.field;
@@ -517,7 +516,22 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format
 
 	w = min(w, 720);
 	w = max(w, 2);
-	h = min(h, itv->is_out_50hz ? 576 : 480);
+	/* Why can the height be 576 even when the output is NTSC?
+
+	   Internally the buffers of the PVR350 are always set to 720x576. The
+	   decoded video frame will always be placed in the top left corner of
+	   this buffer. For any video which is not 720x576, the buffer will
+	   then be cropped to remove the unused right and lower areas, with
+	   the remaining image being scaled by the hardware to fit the display
+	   area. The video can be scaled both up and down, so a 720x480 video
+	   can be displayed full-screen on PAL and a 720x576 video can be
+	   displayed without cropping on NTSC.
+
+	   Note that the scaling only occurs on the video stream, the osd
+	   resolution is locked to the broadcast standard and not scaled.
+
+	   Thanks to Ian Armstrong for this explanation. */
+	h = min(h, 576);
 	h = max(h, 2);
 	if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
 		fmt->fmt.pix.field = field;

+ 212 - 264
drivers/media/video/ks0127.c

@@ -33,27 +33,20 @@
  * V1.1 Gerard v.d. Horst  Added some debugoutput, reset the video-standard
  */
 
-#ifndef __KERNEL__
-#define __KERNEL__
-#endif
-
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include "ks0127.h"
-
 #include <linux/i2c.h>
 #include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#include "ks0127.h"
 
-#define dprintk     if (debug) printk
-
-/* i2c identification */
-#define I2C_KS0127_ADDON   0xD8
-#define I2C_KS0127_ONBOARD 0xDA
+MODULE_DESCRIPTION("KS0127 video decoder driver");
+MODULE_AUTHOR("Ryan Drake");
+MODULE_LICENSE("GPL");
 
 #define KS_TYPE_UNKNOWN	0
 #define KS_TYPE_0122S	1
@@ -204,8 +197,6 @@ struct adjust {
 };
 
 struct ks0127 {
-	struct i2c_client *client;
-	unsigned char	addr;
 	int		format_width;
 	int		format_height;
 	int		cap_width;
@@ -220,16 +211,18 @@ static int debug; /* insmod parameter */
 
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug output");
-MODULE_LICENSE("GPL");
 
 static u8 reg_defaults[64];
 
-
-
 static void init_reg_defaults(void)
 {
+	static int initialized;
 	u8 *table = reg_defaults;
 
+	if (initialized)
+		return;
+	initialized = 1;
+
 	table[KS_CMDA]     = 0x2c;  /* VSE=0, CCIR 601, autodetect standard */
 	table[KS_CMDB]     = 0x12;  /* VALIGN=0, AGC control and input */
 	table[KS_CMDC]     = 0x00;  /* Test options */
@@ -308,50 +301,53 @@ static void init_reg_defaults(void)
  * An explanation from kayork@mail.utexas.edu:
  *
  * During I2C reads, the KS0127 only samples for a stop condition
- * during the place where the acknoledge bit should be. Any standard
+ * during the place where the acknowledge bit should be. Any standard
  * I2C implementation (correctly) throws in another clock transition
  * at the 9th bit, and the KS0127 will not recognize the stop condition
  * and will continue to clock out data.
  *
  * So we have to do the read ourself.  Big deal.
-	   workaround in i2c-algo-bit
+ *	   workaround in i2c-algo-bit
  */
 
 
-static u8 ks0127_read(struct ks0127 *ks, u8 reg)
+static u8 ks0127_read(struct i2c_client *c, u8 reg)
 {
-	struct i2c_client *c = ks->client;
 	char val = 0;
 	struct i2c_msg msgs[] = {
-		{c->addr, 0, sizeof(reg), &reg},
-		{c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}};
+		{ c->addr, 0, sizeof(reg), &reg },
+		{ c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
+	};
 	int ret;
 
 	ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs));
 	if (ret != ARRAY_SIZE(msgs))
-		dprintk("ks0127_write error\n");
+		v4l_dbg(1, debug, c, "read error\n");
 
 	return val;
 }
 
 
-static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val)
+static void ks0127_write(struct i2c_client *c, u8 reg, u8 val)
 {
-	char msg[] = {reg, val};
+	struct ks0127 *ks = i2c_get_clientdata(c);
+	char msg[] = { reg, val };
 
-	if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg))
-		dprintk("ks0127_write error\n");
+	if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg))
+		v4l_dbg(1, debug, c, "write error\n");
 
 	ks->regs[reg] = val;
 }
 
 
 /* generic bit-twiddling */
-static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v)
+static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v)
 {
+	struct ks0127 *ks = i2c_get_clientdata(client);
+
 	u8 val = ks->regs[reg];
 	val = (val & and_v) | or_v;
-	ks0127_write(ks, reg, val);
+	ks0127_write(client, reg, val);
 }
 
 
@@ -359,73 +355,69 @@ static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v)
 /****************************************************************************
 * ks0127 private api
 ****************************************************************************/
-static void ks0127_reset(struct ks0127* ks)
+static void ks0127_reset(struct i2c_client *c)
 {
-	int i;
+	struct ks0127 *ks = i2c_get_clientdata(c);
 	u8 *table = reg_defaults;
+	int i;
 
 	ks->ks_type = KS_TYPE_UNKNOWN;
 
-	dprintk("ks0127: reset\n");
+	v4l_dbg(1, debug, c, "reset\n");
 	msleep(1);
 
 	/* initialize all registers to known values */
 	/* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
 
-	for(i = 1; i < 33; i++)
-		ks0127_write(ks, i, table[i]);
+	for (i = 1; i < 33; i++)
+		ks0127_write(c, i, table[i]);
 
-	for(i = 35; i < 40; i++)
-		ks0127_write(ks, i, table[i]);
+	for (i = 35; i < 40; i++)
+		ks0127_write(c, i, table[i]);
 
-	for(i = 41; i < 56; i++)
-		ks0127_write(ks, i, table[i]);
+	for (i = 41; i < 56; i++)
+		ks0127_write(c, i, table[i]);
 
-	for(i = 58; i < 64; i++)
-		ks0127_write(ks, i, table[i]);
+	for (i = 58; i < 64; i++)
+		ks0127_write(c, i, table[i]);
 
 
-	if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) {
+	if ((ks0127_read(c, KS_STAT) & 0x80) == 0) {
 		ks->ks_type = KS_TYPE_0122S;
-		dprintk("ks0127: ks0122s Found\n");
+		v4l_dbg(1, debug, c, "ks0122s found\n");
 		return;
 	}
 
-	switch(ks0127_read(ks, KS_CMDE) & 0x0f) {
-
+	switch (ks0127_read(c, KS_CMDE) & 0x0f) {
 	case 0:
 		ks->ks_type = KS_TYPE_0127;
-		dprintk("ks0127: ks0127 found\n");
+		v4l_dbg(1, debug, c, "ks0127 found\n");
 		break;
 
 	case 9:
 		ks->ks_type = KS_TYPE_0127B;
-		dprintk("ks0127: ks0127B Revision A found\n");
+		v4l_dbg(1, debug, c, "ks0127B Revision A found\n");
 		break;
 
 	default:
-		dprintk("ks0127: unknown revision\n");
+		v4l_dbg(1, debug, c, "unknown revision\n");
 		break;
 	}
 }
 
-static int ks0127_command(struct i2c_client *client,
-			  unsigned int cmd, void *arg)
+static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
 {
-	struct ks0127 *ks = i2c_get_clientdata(client);
-
-	int		*iarg = (int*)arg;
-
+	struct ks0127 *ks = i2c_get_clientdata(c);
+	int		*iarg = (int *)arg;
 	int		status;
 
 	if (!ks)
 		return -ENODEV;
 
 	switch (cmd) {
-
 	case DECODER_INIT:
-		dprintk("ks0127: command DECODER_INIT\n");
-		ks0127_reset(ks);
+		v4l_dbg(1, debug, c, "DECODER_INIT\n");
+		ks0127_reset(c);
 		break;
 
 	case DECODER_SET_INPUT:
@@ -436,161 +428,160 @@ static int ks0127_command(struct i2c_client *client,
 		case KS_INPUT_COMPOSITE_4:
 		case KS_INPUT_COMPOSITE_5:
 		case KS_INPUT_COMPOSITE_6:
-			dprintk("ks0127: command DECODER_SET_INPUT %d: "
-				"Composite\n", *iarg);
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_INPUT %d: Composite\n", *iarg);
 			/* autodetect 50/60 Hz */
-			ks0127_and_or(ks, KS_CMDA,   0xfc, 0x00);
+			ks0127_and_or(c, KS_CMDA,   0xfc, 0x00);
 			/* VSE=0 */
-			ks0127_and_or(ks, KS_CMDA,   ~0x40, 0x00);
+			ks0127_and_or(c, KS_CMDA,   ~0x40, 0x00);
 			/* set input line */
-			ks0127_and_or(ks, KS_CMDB,   0xb0, *iarg);
+			ks0127_and_or(c, KS_CMDB,   0xb0, *iarg);
 			/* non-freerunning mode */
-			ks0127_and_or(ks, KS_CMDC,   0x70, 0x0a);
+			ks0127_and_or(c, KS_CMDC,   0x70, 0x0a);
 			/* analog input */
-			ks0127_and_or(ks, KS_CMDD,   0x03, 0x00);
+			ks0127_and_or(c, KS_CMDD,   0x03, 0x00);
 			/* enable chroma demodulation */
-			ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
+			ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
 			/* chroma trap, HYBWR=1 */
-			ks0127_and_or(ks, KS_LUMA,   0x00,
+			ks0127_and_or(c, KS_LUMA,   0x00,
 				       (reg_defaults[KS_LUMA])|0x0c);
 			/* scaler fullbw, luma comb off */
-			ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
+			ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
 			/* manual chroma comb .25 .5 .25 */
-			ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90);
+			ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90);
 
 			/* chroma path delay */
-			ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90);
+			ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90);
 
-			ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
-			ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
-			ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
-			ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+			ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
+			ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
+			ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+			ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
 			break;
 
 		case KS_INPUT_SVIDEO_1:
 		case KS_INPUT_SVIDEO_2:
 		case KS_INPUT_SVIDEO_3:
-			dprintk("ks0127: command DECODER_SET_INPUT %d: "
-				"S-Video\n", *iarg);
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_INPUT %d: S-Video\n", *iarg);
 			/* autodetect 50/60 Hz */
-			ks0127_and_or(ks, KS_CMDA,   0xfc, 0x00);
+			ks0127_and_or(c, KS_CMDA,   0xfc, 0x00);
 			/* VSE=0 */
-			ks0127_and_or(ks, KS_CMDA,   ~0x40, 0x00);
+			ks0127_and_or(c, KS_CMDA,   ~0x40, 0x00);
 			/* set input line */
-			ks0127_and_or(ks, KS_CMDB,   0xb0, *iarg);
+			ks0127_and_or(c, KS_CMDB,   0xb0, *iarg);
 			/* non-freerunning mode */
-			ks0127_and_or(ks, KS_CMDC,   0x70, 0x0a);
+			ks0127_and_or(c, KS_CMDC,   0x70, 0x0a);
 			/* analog input */
-			ks0127_and_or(ks, KS_CMDD,   0x03, 0x00);
+			ks0127_and_or(c, KS_CMDD,   0x03, 0x00);
 			/* enable chroma demodulation */
-			ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
-			ks0127_and_or(ks, KS_LUMA, 0x00,
+			ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
+			ks0127_and_or(c, KS_LUMA, 0x00,
 				       reg_defaults[KS_LUMA]);
 			/* disable luma comb */
-			ks0127_and_or(ks, KS_VERTIA, 0x08,
+			ks0127_and_or(c, KS_VERTIA, 0x08,
 				       (reg_defaults[KS_VERTIA]&0xf0)|0x01);
-			ks0127_and_or(ks, KS_VERTIC, 0x0f,
+			ks0127_and_or(c, KS_VERTIC, 0x0f,
 				       reg_defaults[KS_VERTIC]&0xf0);
 
-			ks0127_and_or(ks, KS_CHROMB, 0x0f,
+			ks0127_and_or(c, KS_CHROMB, 0x0f,
 				       reg_defaults[KS_CHROMB]&0xf0);
 
-			ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
-			ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
-			ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
-			ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+			ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
+			ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
+			ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+			ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
 			break;
 
 		case KS_INPUT_YUV656:
-			dprintk("ks0127: command DECODER_SET_INPUT 15: "
-				"YUV656\n");
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_INPUT 15: YUV656\n");
 			if (ks->norm == VIDEO_MODE_NTSC ||
 			    ks->norm == KS_STD_PAL_M)
 				/* force 60 Hz */
-				ks0127_and_or(ks, KS_CMDA,   0xfc, 0x03);
+				ks0127_and_or(c, KS_CMDA,   0xfc, 0x03);
 			else
 				/* force 50 Hz */
-				ks0127_and_or(ks, KS_CMDA,   0xfc, 0x02);
+				ks0127_and_or(c, KS_CMDA,   0xfc, 0x02);
 
-			ks0127_and_or(ks, KS_CMDA,   0xff, 0x40); /* VSE=1 */
+			ks0127_and_or(c, KS_CMDA,   0xff, 0x40); /* VSE=1 */
 			/* set input line and VALIGN */
-			ks0127_and_or(ks, KS_CMDB,   0xb0, (*iarg | 0x40));
+			ks0127_and_or(c, KS_CMDB,   0xb0, (*iarg | 0x40));
 			/* freerunning mode, */
 			/* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0  VMEM=1*/
-			ks0127_and_or(ks, KS_CMDC,   0x70, 0x87);
+			ks0127_and_or(c, KS_CMDC,   0x70, 0x87);
 			/* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
-			ks0127_and_or(ks, KS_CMDD,   0x03, 0x08);
+			ks0127_and_or(c, KS_CMDD,   0x03, 0x08);
 			/* disable chroma demodulation */
-			ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30);
+			ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30);
 			/* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
-			ks0127_and_or(ks, KS_LUMA,   0x00, 0x71);
-			ks0127_and_or(ks, KS_VERTIC, 0x0f,
+			ks0127_and_or(c, KS_LUMA,   0x00, 0x71);
+			ks0127_and_or(c, KS_VERTIC, 0x0f,
 				       reg_defaults[KS_VERTIC]&0xf0);
 
 			/* scaler fullbw, luma comb off */
-			ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
+			ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
 
-			ks0127_and_or(ks, KS_CHROMB, 0x0f,
+			ks0127_and_or(c, KS_CHROMB, 0x0f,
 				       reg_defaults[KS_CHROMB]&0xf0);
 
-			ks0127_and_or(ks, KS_CON, 0x00, 0x00);
-			ks0127_and_or(ks, KS_BRT, 0x00, 32);	/* spec: 34 */
+			ks0127_and_or(c, KS_CON, 0x00, 0x00);
+			ks0127_and_or(c, KS_BRT, 0x00, 32);	/* spec: 34 */
 				/* spec: 229 (e5) */
-			ks0127_and_or(ks, KS_SAT, 0x00, 0xe8);
-			ks0127_and_or(ks, KS_HUE, 0x00, 0);
+			ks0127_and_or(c, KS_SAT, 0x00, 0xe8);
+			ks0127_and_or(c, KS_HUE, 0x00, 0);
 
-			ks0127_and_or(ks, KS_UGAIN, 0x00, 238);
-			ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00);
+			ks0127_and_or(c, KS_UGAIN, 0x00, 238);
+			ks0127_and_or(c, KS_VGAIN, 0x00, 0x00);
 
 			/*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
-			ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f);
-			ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00);
+			ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f);
+			ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00);
 			break;
 
 		default:
-			dprintk("ks0127: command DECODER_SET_INPUT: "
-				"Unknown input %d\n", *iarg);
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_INPUT: Unknown input %d\n", *iarg);
 			break;
 		}
 
 		/* hack: CDMLPF sometimes spontaneously switches on; */
 		/* force back off */
-		ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]);
+		ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]);
 		break;
 
 	case DECODER_SET_OUTPUT:
 		switch(*iarg) {
 		case KS_OUTPUT_YUV656E:
-			dprintk("ks0127: command DECODER_SET_OUTPUT: "
-				"OUTPUT_YUV656E (Missing)\n");
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n");
 			return -EINVAL;
-			break;
 
 		case KS_OUTPUT_EXV:
-			dprintk("ks0127: command DECODER_SET_OUTPUT: "
-				"OUTPUT_EXV\n");
-			ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09);
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_OUTPUT: OUTPUT_EXV\n");
+			ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09);
 			break;
 		}
 		break;
 
-	case DECODER_SET_NORM: //sam This block mixes old and new norm names...
+	case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */
 		/* Set to automatic SECAM/Fsc mode */
-		ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
+		ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
 
 		ks->norm = *iarg;
-		switch(*iarg)
-		{
+		switch (*iarg) {
 		/* this is untested !! */
 		/* It just detects PAL_N/NTSC_M (no special frequencies) */
 		/* And you have to set the standard a second time afterwards */
 		case VIDEO_MODE_AUTO:
-			dprintk("ks0127: command DECODER_SET_NORM: AUTO\n");
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_NORM: AUTO\n");
 
 			/* The chip determines the format */
 			/* based on the current field rate */
-			ks0127_and_or(ks, KS_CMDA,   0xfc, 0x00);
-			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+			ks0127_and_or(c, KS_CMDA,   0xfc, 0x00);
+			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
 			/* This is wrong for PAL ! As I said, */
 			/* you need to set the standard once again !! */
 			ks->format_height = 240;
@@ -598,84 +589,86 @@ static int ks0127_command(struct i2c_client *client,
 			break;
 
 		case VIDEO_MODE_NTSC:
-			dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n");
-			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_NORM: NTSC_M\n");
+			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
 			ks->format_height = 240;
 			ks->format_width = 704;
 			break;
 
 		case KS_STD_NTSC_N:
-			dprintk("ks0127: command KS0127_SET_STANDARD: "
-				"NTSC_N (fixme)\n");
-			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
+			v4l_dbg(1, debug, c,
+				"KS0127_SET_NORM: NTSC_N (fixme)\n");
+			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
 			ks->format_height = 240;
 			ks->format_width = 704;
 			break;
 
 		case VIDEO_MODE_PAL:
-			dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n");
-			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_NORM: PAL_N\n");
+			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
 			ks->format_height = 290;
 			ks->format_width = 704;
 			break;
 
 		case KS_STD_PAL_M:
-			dprintk("ks0127: command KS0127_SET_STANDARD: "
-				"PAL_M (fixme)\n");
-			ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
+			v4l_dbg(1, debug, c,
+				"KS0127_SET_NORM: PAL_M (fixme)\n");
+			ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
 			ks->format_height = 290;
 			ks->format_width = 704;
 			break;
 
 		case VIDEO_MODE_SECAM:
-			dprintk("ks0127: command KS0127_SET_STANDARD: "
-				"SECAM\n");
+			v4l_dbg(1, debug, c,
+				"KS0127_SET_NORM: SECAM\n");
 			ks->format_height = 290;
 			ks->format_width = 704;
 
 			/* set to secam autodetection */
-			ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20);
-			ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
+			ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20);
+			ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
 			schedule_timeout_interruptible(HZ/10+1);
 
 			/* did it autodetect? */
-			if (ks0127_read(ks, KS_DEMOD) & 0x40)
+			if (ks0127_read(c, KS_DEMOD) & 0x40)
 				break;
 
 			/* force to secam mode */
-			ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f);
+			ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f);
 			break;
 
 		default:
-			dprintk("ks0127: command DECODER_SET_NORM: "
-				"Unknown norm %d\n", *iarg);
+			v4l_dbg(1, debug, c,
+				"DECODER_SET_NORM: Unknown norm %d\n", *iarg);
 			break;
 		}
 		break;
 
 	case DECODER_SET_PICTURE:
-		dprintk("ks0127: command DECODER_SET_PICTURE "
-			"not yet supported (fixme)\n");
+		v4l_dbg(1, debug, c,
+			"DECODER_SET_PICTURE: not yet supported\n");
 		return -EINVAL;
 
-	//sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE
-	//sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE
-	//sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE?
-	//sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE
-	//sam todo: KS0127_SET_AGC_MODE:
-	//sam todo: KS0127_SET_AGC:
-	//sam todo: KS0127_SET_CHROMA_MODE:
-	//sam todo: KS0127_SET_PIXCLK_MODE:
-	//sam todo: KS0127_SET_GAMMA_MODE:
-	//sam todo: KS0127_SET_UGAIN:
-	//sam todo: KS0127_SET_VGAIN:
-	//sam todo: KS0127_SET_INVALY:
-	//sam todo: KS0127_SET_INVALU:
-	//sam todo: KS0127_SET_INVALV:
-	//sam todo: KS0127_SET_UNUSEY:
-	//sam todo: KS0127_SET_UNUSEU:
-	//sam todo: KS0127_SET_UNUSEV:
-	//sam todo: KS0127_SET_VSALIGN_MODE:
+	/* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */
+	/* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */
+	/* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */
+	/* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */
+	/* sam todo: KS0127_SET_AGC_MODE: */
+	/* sam todo: KS0127_SET_AGC: */
+	/* sam todo: KS0127_SET_CHROMA_MODE: */
+	/* sam todo: KS0127_SET_PIXCLK_MODE: */
+	/* sam todo: KS0127_SET_GAMMA_MODE: */
+	/* sam todo: KS0127_SET_UGAIN: */
+	/* sam todo: KS0127_SET_VGAIN: */
+	/* sam todo: KS0127_SET_INVALY: */
+	/* sam todo: KS0127_SET_INVALU: */
+	/* sam todo: KS0127_SET_INVALV: */
+	/* sam todo: KS0127_SET_UNUSEY: */
+	/* sam todo: KS0127_SET_UNUSEU: */
+	/* sam todo: KS0127_SET_UNUSEV: */
+	/* sam todo: KS0127_SET_VSALIGN_MODE: */
 
 	case DECODER_ENABLE_OUTPUT:
 	{
@@ -684,34 +677,32 @@ static int ks0127_command(struct i2c_client *client,
 		iarg = arg;
 		enable = (*iarg != 0);
 		if (enable) {
-			dprintk("ks0127: command "
-					"DECODER_ENABLE_OUTPUT on "
-					"(%d)\n", enable);
+			v4l_dbg(1, debug, c,
+				"DECODER_ENABLE_OUTPUT on\n");
 			/* All output pins on */
-			ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30);
+			ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30);
 			/* Obey the OEN pin */
-			ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00);
+			ks0127_and_or(c, KS_CDEM, 0x7f, 0x00);
 		} else {
-			dprintk("ks0127: command "
-					"DECODER_ENABLE_OUTPUT off "
-					"(%d)\n", enable);
+			v4l_dbg(1, debug, c,
+				"DECODER_ENABLE_OUTPUT off\n");
 			/* Video output pins off */
-			ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00);
+			ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00);
 			/* Ignore the OEN pin */
-			ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80);
+			ks0127_and_or(c, KS_CDEM, 0x7f, 0x80);
 		}
-	}
 		break;
+	}
 
-	//sam todo: KS0127_SET_OUTPUT_MODE:
-	//sam todo: KS0127_SET_WIDTH:
-	//sam todo: KS0127_SET_HEIGHT:
-	//sam todo: KS0127_SET_HSCALE:
+	/* sam todo: KS0127_SET_OUTPUT_MODE: */
+	/* sam todo: KS0127_SET_WIDTH: */
+	/* sam todo: KS0127_SET_HEIGHT: */
+	/* sam todo: KS0127_SET_HSCALE: */
 
 	case DECODER_GET_STATUS:
-		dprintk("ks0127: command DECODER_GET_STATUS\n");
+		v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n");
 		*iarg = 0;
-		status = ks0127_read(ks, KS_STAT);
+		status = ks0127_read(c, KS_STAT);
 		if (!(status & 0x20))		 /* NOVID not set */
 			*iarg = (*iarg | DECODER_STATUS_GOOD);
 		if ((status & 0x01))		      /* CLOCK set */
@@ -722,124 +713,81 @@ static int ks0127_command(struct i2c_client *client,
 			*iarg = (*iarg | DECODER_STATUS_NTSC);
 		break;
 
-	//Catch any unknown command
+	/* Catch any unknown command */
 	default:
-		dprintk("ks0127: command unknown: %04X\n", cmd);
+		v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd);
 		return -EINVAL;
 	}
 	return 0;
 }
 
 
-
-
-static int ks0127_probe(struct i2c_adapter *adapter);
-static int ks0127_detach(struct i2c_client *client);
-static int ks0127_command(struct i2c_client *client,
-			  unsigned int cmd, void *arg);
-
-
-
 /* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1,
-				       I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END};
-static unsigned short probe[2] =	{I2C_CLIENT_END, I2C_CLIENT_END};
-static unsigned short ignore[2] = 	{I2C_CLIENT_END, I2C_CLIENT_END};
-static struct i2c_client_address_data addr_data = {
-	normal_i2c,
-	probe,
-	ignore,
-};
+#define I2C_KS0127_ADDON   0xD8
+#define I2C_KS0127_ONBOARD 0xDA
 
-static struct i2c_driver i2c_driver_ks0127 = {
-	.driver.name = "ks0127",
-	.id             = I2C_DRIVERID_KS0127,
-	.attach_adapter = ks0127_probe,
-	.detach_client  = ks0127_detach,
-	.command        = ks0127_command
+static unsigned short normal_i2c[] = {
+	I2C_KS0127_ADDON >> 1,
+	I2C_KS0127_ONBOARD >> 1,
+	I2C_CLIENT_END
 };
 
-static struct i2c_client ks0127_client_tmpl =
-{
-	.name = "(ks0127 unset)",
-	.addr = 0,
-	.adapter = NULL,
-	.driver = &i2c_driver_ks0127,
-};
+I2C_CLIENT_INSMOD;
 
-static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind)
+static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id)
 {
 	struct ks0127 *ks;
-	struct i2c_client *client;
 
-	client = kzalloc(sizeof(*client), GFP_KERNEL);
-	if (client == NULL)
-		return -ENOMEM;
-	memcpy(client, &ks0127_client_tmpl, sizeof(*client));
+	v4l_info(c, "%s chip found @ 0x%x (%s)\n",
+		c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
+		c->addr << 1, c->adapter->name);
 
 	ks = kzalloc(sizeof(*ks), GFP_KERNEL);
-	if (ks == NULL) {
-		kfree(client);
+	if (ks == NULL)
 		return -ENOMEM;
-	}
 
-	i2c_set_clientdata(client, ks);
-	client->adapter = adapter;
-	client->addr = addr;
-	sprintf(client->name, "ks0127-%02x", adapter->id);
+	i2c_set_clientdata(c, ks);
 
-	ks->client = client;
-	ks->addr = addr;
 	ks->ks_type = KS_TYPE_UNKNOWN;
 
 	/* power up */
-	ks0127_write(ks, KS_CMDA, 0x2c);
+	init_reg_defaults();
+	ks0127_write(c, KS_CMDA, 0x2c);
 	mdelay(10);
 
 	/* reset the device */
-	ks0127_reset(ks);
-	printk(KERN_INFO "ks0127: attach: %s video decoder\n",
-	       ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board");
-
-	i2c_attach_client(client);
+	ks0127_reset(c);
 	return 0;
 }
 
-
-static int ks0127_probe(struct i2c_adapter *adapter)
+static int ks0127_remove(struct i2c_client *c)
 {
-	if (adapter->id == I2C_HW_B_ZR36067)
-		return i2c_probe(adapter, &addr_data, ks0127_found_proc);
-	return 0;
-}
-
-static int ks0127_detach(struct i2c_client *client)
-{
-	struct ks0127 *ks = i2c_get_clientdata(client);
+	struct ks0127 *ks = i2c_get_clientdata(c);
 
-	ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/
-	ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */
+	ks0127_write(c, KS_OFMTA, 0x20); /* tristate */
+	ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */
 
-	i2c_detach_client(client);
 	kfree(ks);
-	kfree(client);
-
-	dprintk("ks0127: detach\n");
 	return 0;
 }
 
-
-static int __devinit ks0127_init_module(void)
+static int ks0127_legacy_probe(struct i2c_adapter *adapter)
 {
-	init_reg_defaults();
-	return i2c_add_driver(&i2c_driver_ks0127);
+	return adapter->id == I2C_HW_B_ZR36067;
 }
 
-static void __devexit ks0127_cleanup_module(void)
-{
-	i2c_del_driver(&i2c_driver_ks0127);
-}
-
-
-module_init(ks0127_init_module);
-module_exit(ks0127_cleanup_module);
+static const struct i2c_device_id ks0127_id[] = {
+	{ "ks0127", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ks0127_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "ks0127",
+	.driverid = I2C_DRIVERID_KS0127,
+	.command = ks0127_command,
+	.probe = ks0127_probe,
+	.remove = ks0127_remove,
+	.legacy_probe = ks0127_legacy_probe,
+	.id_table = ks0127_id,
+};

+ 64 - 178
drivers/media/video/saa7110.c

@@ -31,36 +31,24 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
-#include <asm/io.h>
 #include <asm/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
 
 MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
 MODULE_AUTHOR("Pauline Middelink");
 MODULE_LICENSE("GPL");
 
-#include <linux/i2c.h>
-
-#define I2C_NAME(s) (s)->name
-
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <linux/video_decoder.h>
-
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
-	do { \
-		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
-
 #define SAA7110_MAX_INPUT	9	/* 6 CVBS, 3 SVHS */
 #define SAA7110_MAX_OUTPUT	0	/* its a decoder only */
 
-#define	I2C_SAA7110		0x9C	/* or 0x9E */
-
 #define SAA7110_NR_REG		0x35
 
 struct saa7110 {
@@ -81,10 +69,7 @@ struct saa7110 {
 /* I2C support functions						   */
 /* ----------------------------------------------------------------------- */
 
-static int
-saa7110_write (struct i2c_client *client,
-	       u8                 reg,
-	       u8                 value)
+static int saa7110_write(struct i2c_client *client, u8 reg, u8 value)
 {
 	struct saa7110 *decoder = i2c_get_clientdata(client);
 
@@ -92,10 +77,7 @@ saa7110_write (struct i2c_client *client,
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static int
-saa7110_write_block (struct i2c_client *client,
-		     const u8          *data,
-		     unsigned int       len)
+static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
 {
 	int ret = -1;
 	u8 reg = *data;		/* first register to write to */
@@ -115,8 +97,8 @@ saa7110_write_block (struct i2c_client *client,
 		memcpy(decoder->reg + reg, data + 1, len - 1);
 	} else {
 		for (++data, --len; len; len--) {
-			if ((ret = saa7110_write(client, reg++,
-						 *data++)) < 0)
+			ret = saa7110_write(client, reg++, *data++);
+			if (ret < 0)
 				break;
 		}
 	}
@@ -124,8 +106,7 @@ saa7110_write_block (struct i2c_client *client,
 	return ret;
 }
 
-static inline int
-saa7110_read (struct i2c_client *client)
+static inline int saa7110_read(struct i2c_client *client)
 {
 	return i2c_smbus_read_byte(client);
 }
@@ -138,9 +119,7 @@ saa7110_read (struct i2c_client *client)
 #define FRESP_06H_SVIDEO 0x83	//0xC0
 
 
-static int
-saa7110_selmux (struct i2c_client *client,
-		int                chan)
+static int saa7110_selmux(struct i2c_client *client, int chan)
 {
 	static const unsigned char modes[9][8] = {
 		/* mode 0 */
@@ -197,8 +176,7 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = {
 	/* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
 };
 
-static int
-determine_norm (struct i2c_client *client)
+static int determine_norm(struct i2c_client *client)
 {
 	DEFINE_WAIT(wait);
 	struct saa7110 *decoder = i2c_get_clientdata(client);
@@ -212,29 +190,23 @@ determine_norm (struct i2c_client *client)
 	finish_wait(&decoder->wq, &wait);
 	status = saa7110_read(client);
 	if (status & 0x40) {
-		dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n",
-			I2C_NAME(client), status);
+		v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status);
 		return decoder->norm;	// no change
 	}
 	if ((status & 3) == 0) {
 		saa7110_write(client, 0x06, 0x83);
 		if (status & 0x20) {
-			dprintk(1,
-				KERN_INFO
-				"%s: status=0x%02x (NTSC/no color)\n",
-				I2C_NAME(client), status);
+			v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status);
 			//saa7110_write(client,0x2E,0x81);
 			return VIDEO_MODE_NTSC;
 		}
-		dprintk(1, KERN_INFO "%s: status=0x%02x (PAL/no color)\n",
-			I2C_NAME(client), status);
+		v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status);
 		//saa7110_write(client,0x2E,0x9A);
 		return VIDEO_MODE_PAL;
 	}
 	//saa7110_write(client,0x06,0x03);
 	if (status & 0x20) {	/* 60Hz */
-		dprintk(1, KERN_INFO "%s: status=0x%02x (NTSC)\n",
-			I2C_NAME(client), status);
+		v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status);
 		saa7110_write(client, 0x0D, 0x86);
 		saa7110_write(client, 0x0F, 0x50);
 		saa7110_write(client, 0x11, 0x2C);
@@ -254,13 +226,11 @@ determine_norm (struct i2c_client *client)
 
 	status = saa7110_read(client);
 	if ((status & 0x03) == 0x01) {
-		dprintk(1, KERN_INFO "%s: status=0x%02x (SECAM)\n",
-			I2C_NAME(client), status);
+		v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status);
 		saa7110_write(client, 0x0D, 0x87);
 		return VIDEO_MODE_SECAM;
 	}
-	dprintk(1, KERN_INFO "%s: status=0x%02x (PAL)\n", I2C_NAME(client),
-		status);
+	v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status);
 	return VIDEO_MODE_PAL;
 }
 
@@ -286,8 +256,8 @@ saa7110_command (struct i2c_client *client,
 		    VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
 		dc->inputs = SAA7110_MAX_INPUT;
 		dc->outputs = SAA7110_MAX_OUTPUT;
-	}
 		break;
+	}
 
 	case DECODER_GET_STATUS:
 	{
@@ -295,8 +265,8 @@ saa7110_command (struct i2c_client *client,
 		int res = 0;
 
 		status = saa7110_read(client);
-		dprintk(1, KERN_INFO "%s: status=0x%02x norm=%d\n",
-			I2C_NAME(client), status, decoder->norm);
+		v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n",
+			       status, decoder->norm);
 		if (!(status & 0x40))
 			res |= DECODER_STATUS_GOOD;
 		if (status & 0x03)
@@ -314,8 +284,8 @@ saa7110_command (struct i2c_client *client,
 			break;
 		}
 		*(int *) arg = res;
-	}
 		break;
+	}
 
 	case DECODER_SET_NORM:
 		v = *(int *) arg;
@@ -328,34 +298,24 @@ saa7110_command (struct i2c_client *client,
 				saa7110_write(client, 0x0F, 0x50);
 				saa7110_write(client, 0x11, 0x2C);
 				//saa7110_write(client, 0x2E, 0x81);
-				dprintk(1,
-					KERN_INFO "%s: switched to NTSC\n",
-					I2C_NAME(client));
+				v4l_dbg(1, debug, client, "switched to NTSC\n");
 				break;
 			case VIDEO_MODE_PAL:
 				saa7110_write(client, 0x0D, 0x86);
 				saa7110_write(client, 0x0F, 0x10);
 				saa7110_write(client, 0x11, 0x59);
 				//saa7110_write(client, 0x2E, 0x9A);
-				dprintk(1,
-					KERN_INFO "%s: switched to PAL\n",
-					I2C_NAME(client));
+				v4l_dbg(1, debug, client, "switched to PAL\n");
 				break;
 			case VIDEO_MODE_SECAM:
 				saa7110_write(client, 0x0D, 0x87);
 				saa7110_write(client, 0x0F, 0x10);
 				saa7110_write(client, 0x11, 0x59);
 				//saa7110_write(client, 0x2E, 0x9A);
-				dprintk(1,
-					KERN_INFO
-					"%s: switched to SECAM\n",
-					I2C_NAME(client));
+				v4l_dbg(1, debug, client, "switched to SECAM\n");
 				break;
 			case VIDEO_MODE_AUTO:
-				dprintk(1,
-					KERN_INFO
-					"%s: TV standard detection...\n",
-					I2C_NAME(client));
+				v4l_dbg(1, debug, client, "switched to AUTO\n");
 				decoder->norm = determine_norm(client);
 				*(int *) arg = decoder->norm;
 				break;
@@ -368,15 +328,12 @@ saa7110_command (struct i2c_client *client,
 	case DECODER_SET_INPUT:
 		v = *(int *) arg;
 		if (v < 0 || v > SAA7110_MAX_INPUT) {
-			dprintk(1,
-				KERN_INFO "%s: input=%d not available\n",
-				I2C_NAME(client), v);
+			v4l_dbg(1, debug, client, "input=%d not available\n", v);
 			return -EINVAL;
 		}
 		if (decoder->input != v) {
 			saa7110_selmux(client, v);
-			dprintk(1, KERN_INFO "%s: switched to input=%d\n",
-				I2C_NAME(client), v);
+			v4l_dbg(1, debug, client, "switched to input=%d\n", v);
 		}
 		break;
 
@@ -392,8 +349,7 @@ saa7110_command (struct i2c_client *client,
 		if (decoder->enable != v) {
 			decoder->enable = v;
 			saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
-			dprintk(1, KERN_INFO "%s: YUV %s\n", I2C_NAME(client),
-				v ? "on" : "off");
+			v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off");
 		}
 		break;
 
@@ -423,23 +379,23 @@ saa7110_command (struct i2c_client *client,
 			saa7110_write(client, 0x07,
 				      (decoder->hue >> 8) - 128);
 		}
-	}
 		break;
+	}
 
 	case DECODER_DUMP:
+		if (!debug)
+			break;
 		for (v = 0; v < SAA7110_NR_REG; v += 16) {
 			int j;
-			dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client),
-				v);
+			v4l_dbg(1, debug, client, "%02x:", v);
 			for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++)
-				dprintk(1, " %02x", decoder->reg[v + j]);
-			dprintk(1, "\n");
+				printk(KERN_CONT " %02x", decoder->reg[v + j]);
+			printk(KERN_CONT "\n");
 		}
 		break;
 
 	default:
-		dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n",
-			cmd);
+		v4l_dbg(1, debug, client, "unknown command %08x\n", cmd);
 		return -EINVAL;
 	}
 	return 0;
@@ -451,55 +407,28 @@ saa7110_command (struct i2c_client *client,
  * Generic i2c probe
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
-static unsigned short normal_i2c[] = {
-	I2C_SAA7110 >> 1,
-	(I2C_SAA7110 >> 1) + 1,
-	I2C_CLIENT_END
-};
-
-static unsigned short ignore = I2C_CLIENT_END;
 
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.probe			= &ignore,
-	.ignore			= &ignore,
-};
+static unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END };
 
-static struct i2c_driver i2c_driver_saa7110;
+I2C_CLIENT_INSMOD;
 
-static int
-saa7110_detect_client (struct i2c_adapter *adapter,
-		       int                 address,
-		       int                 kind)
+static int saa7110_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
-	struct i2c_client *client;
 	struct saa7110 *decoder;
 	int rv;
 
-	dprintk(1,
-		KERN_INFO
-		"saa7110.c: detecting saa7110 client on address 0x%x\n",
-		address << 1);
-
 	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality
-	    (adapter,
-	     I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
-		return 0;
+	if (!i2c_check_functionality(client->adapter,
+		I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+		return -ENODEV;
 
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = &i2c_driver_saa7110;
-	strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
 	decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
-	if (!decoder) {
-		kfree(client);
+	if (!decoder)
 		return -ENOMEM;
-	}
 	decoder->norm = VIDEO_MODE_PAL;
 	decoder->input = 0;
 	decoder->enable = 1;
@@ -510,18 +439,10 @@ saa7110_detect_client (struct i2c_adapter *adapter,
 	init_waitqueue_head(&decoder->wq);
 	i2c_set_clientdata(client, decoder);
 
-	rv = i2c_attach_client(client);
-	if (rv) {
-		kfree(client);
-		kfree(decoder);
-		return rv;
-	}
-
 	rv = saa7110_write_block(client, initseq, sizeof(initseq));
-	if (rv < 0)
-		dprintk(1, KERN_ERR "%s_attach: init status %d\n",
-			I2C_NAME(client), rv);
-	else {
+	if (rv < 0) {
+		v4l_dbg(1, debug, client, "init status %d\n", rv);
+	} else {
 		int ver, status;
 		saa7110_write(client, 0x21, 0x10);
 		saa7110_write(client, 0x0e, 0x18);
@@ -530,10 +451,8 @@ saa7110_detect_client (struct i2c_adapter *adapter,
 		saa7110_write(client, 0x0D, 0x06);
 		//mdelay(150);
 		status = saa7110_read(client);
-		dprintk(1,
-			KERN_INFO
-			"%s_attach: SAA7110A version %x at 0x%02x, status=0x%02x\n",
-			I2C_NAME(client), ver, client->addr << 1, status);
+		v4l_dbg(1, debug, client, "version %x, status=0x%02x\n",
+			       ver, status);
 		saa7110_write(client, 0x0D, 0x86);
 		saa7110_write(client, 0x0F, 0x10);
 		saa7110_write(client, 0x11, 0x59);
@@ -547,58 +466,25 @@ saa7110_detect_client (struct i2c_adapter *adapter,
 	return 0;
 }
 
-static int
-saa7110_attach_adapter (struct i2c_adapter *adapter)
-{
-	dprintk(1,
-		KERN_INFO
-		"saa7110.c: starting probe for adapter %s (0x%x)\n",
-		I2C_NAME(adapter), adapter->id);
-	return i2c_probe(adapter, &addr_data, &saa7110_detect_client);
-}
-
-static int
-saa7110_detach_client (struct i2c_client *client)
+static int saa7110_remove(struct i2c_client *client)
 {
-	struct saa7110 *decoder = i2c_get_clientdata(client);
-	int err;
-
-	err = i2c_detach_client(client);
-	if (err) {
-		return err;
-	}
-
-	kfree(decoder);
-	kfree(client);
-
+	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver i2c_driver_saa7110 = {
-	.driver = {
-		.name = "saa7110",
-	},
-
-	.id = I2C_DRIVERID_SAA7110,
+static const struct i2c_device_id saa7110_id[] = {
+	{ "saa7110", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, saa7110_id);
 
-	.attach_adapter = saa7110_attach_adapter,
-	.detach_client = saa7110_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "saa7110",
+	.driverid = I2C_DRIVERID_SAA7110,
 	.command = saa7110_command,
+	.probe = saa7110_probe,
+	.remove = saa7110_remove,
+	.id_table = saa7110_id,
 };
-
-static int __init
-saa7110_init (void)
-{
-	return i2c_add_driver(&i2c_driver_saa7110);
-}
-
-static void __exit
-saa7110_exit (void)
-{
-	i2c_del_driver(&i2c_driver_saa7110);
-}
-
-module_init(saa7110_init);
-module_exit(saa7110_exit);

+ 58 - 166
drivers/media/video/saa7111.c

@@ -28,43 +28,24 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
 #include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
 #include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
 #include <linux/videodev.h>
 #include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
 
 MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
 MODULE_AUTHOR("Dave Perks");
 MODULE_LICENSE("GPL");
 
-
-#define I2C_NAME(s) (s)->name
-
-
 static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
-	do { \
-		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
-
 /* ----------------------------------------------------------------------- */
 
 #define SAA7111_NR_REG		0x18
@@ -77,14 +58,9 @@ struct saa7111 {
 	int enable;
 };
 
-#define   I2C_SAA7111        0x48
-
 /* ----------------------------------------------------------------------- */
 
-static inline int
-saa7111_write (struct i2c_client *client,
-	       u8                 reg,
-	       u8                 value)
+static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value)
 {
 	struct saa7111 *decoder = i2c_get_clientdata(client);
 
@@ -92,8 +68,7 @@ saa7111_write (struct i2c_client *client,
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline void
-saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
+static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
 {
 	struct saa7111 *decoder = i2c_get_clientdata(client);
 
@@ -103,10 +78,7 @@ saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
 	}
 }
 
-static int
-saa7111_write_block (struct i2c_client *client,
-		     const u8          *data,
-		     unsigned int       len)
+static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
 {
 	int ret = -1;
 	u8 reg;
@@ -127,18 +99,17 @@ saa7111_write_block (struct i2c_client *client,
 				    decoder->reg[reg++] = data[1];
 				len -= 2;
 				data += 2;
-			} while (len >= 2 && data[0] == reg &&
-				 block_len < 32);
-			if ((ret = i2c_master_send(client, block_data,
-						   block_len)) < 0)
+			} while (len >= 2 && data[0] == reg && block_len < 32);
+			ret = i2c_master_send(client, block_data, block_len);
+			if (ret < 0)
 				break;
 		}
 	} else {
 		/* do some slow I2C emulation kind of thing */
 		while (len >= 2) {
 			reg = *data++;
-			if ((ret = saa7111_write(client, reg,
-						 *data++)) < 0)
+			ret = saa7111_write(client, reg, *data++);
+			if (ret < 0)
 				break;
 			len -= 2;
 		}
@@ -147,16 +118,13 @@ saa7111_write_block (struct i2c_client *client,
 	return ret;
 }
 
-static int
-saa7111_init_decoder (struct i2c_client *client,
-	      struct video_decoder_init *init)
+static int saa7111_init_decoder(struct i2c_client *client,
+		struct video_decoder_init *init)
 {
 	return saa7111_write_block(client, init->data, init->len);
 }
 
-static inline int
-saa7111_read (struct i2c_client *client,
-	      u8                 reg)
+static inline int saa7111_read(struct i2c_client *client, u8 reg)
 {
 	return i2c_smbus_read_byte_data(client, reg);
 }
@@ -203,28 +171,23 @@ static const unsigned char saa7111_i2c_init[] = {
 	0x17, 0x00,		/* 17 - VBI */
 };
 
-static int
-saa7111_command (struct i2c_client *client,
-		 unsigned int       cmd,
-		 void              *arg)
+static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
 	struct saa7111 *decoder = i2c_get_clientdata(client);
 
 	switch (cmd) {
-
 	case 0:
 		break;
 	case DECODER_INIT:
 	{
 		struct video_decoder_init *init = arg;
+		struct video_decoder_init vdi;
+
 		if (NULL != init)
 			return saa7111_init_decoder(client, init);
-		else {
-			struct video_decoder_init vdi;
-			vdi.data = saa7111_i2c_init;
-			vdi.len = sizeof(saa7111_i2c_init);
-			return saa7111_init_decoder(client, &vdi);
-		}
+		vdi.data = saa7111_i2c_init;
+		vdi.len = sizeof(saa7111_i2c_init);
+		return saa7111_init_decoder(client, &vdi);
 	}
 
 	case DECODER_DUMP:
@@ -234,15 +197,15 @@ saa7111_command (struct i2c_client *client,
 		for (i = 0; i < SAA7111_NR_REG; i += 16) {
 			int j;
 
-			printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
+			v4l_info(client, "%03x", i);
 			for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) {
-				printk(" %02x",
+				printk(KERN_CONT " %02x",
 				       saa7111_read(client, i + j));
 			}
-			printk("\n");
+			printk(KERN_CONT "\n");
 		}
-	}
 		break;
+	}
 
 	case DECODER_GET_CAPABILITIES:
 	{
@@ -255,8 +218,8 @@ saa7111_command (struct i2c_client *client,
 			     VIDEO_DECODER_CCIR;
 		cap->inputs = 8;
 		cap->outputs = 1;
-	}
 		break;
+	}
 
 	case DECODER_GET_STATUS:
 	{
@@ -265,8 +228,7 @@ saa7111_command (struct i2c_client *client,
 		int res;
 
 		status = saa7111_read(client, 0x1f);
-		dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
-			status);
+		v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
 		res = 0;
 		if ((status & (1 << 6)) == 0) {
 			res |= DECODER_STATUS_GOOD;
@@ -294,8 +256,8 @@ saa7111_command (struct i2c_client *client,
 			res |= DECODER_STATUS_COLOR;
 		}
 		*iarg = res;
-	}
 		break;
+	}
 
 	case DECODER_SET_GPIO:
 	{
@@ -362,8 +324,8 @@ saa7111_command (struct i2c_client *client,
 
 		}
 		decoder->norm = *iarg;
-	}
 		break;
+	}
 
 	case DECODER_SET_INPUT:
 	{
@@ -387,8 +349,8 @@ saa7111_command (struct i2c_client *client,
 							     3) ? 0x80 :
 							    0));
 		}
-	}
 		break;
+	}
 
 	case DECODER_SET_OUTPUT:
 	{
@@ -398,8 +360,8 @@ saa7111_command (struct i2c_client *client,
 		if (*iarg != 0) {
 			return -EINVAL;
 		}
-	}
 		break;
+	}
 
 	case DECODER_ENABLE_OUTPUT:
 	{
@@ -439,8 +401,8 @@ saa7111_command (struct i2c_client *client,
 					      (decoder->reg[0x11] & 0xf3));
 			}
 		}
-	}
 		break;
+	}
 
 	case DECODER_SET_PICTURE:
 	{
@@ -454,8 +416,8 @@ saa7111_command (struct i2c_client *client,
 		saa7111_write(client, 0x0c, pic->colour >> 9);
 		/* We want -128 to 127 we get 0-65535 */
 		saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
-	}
 		break;
+	}
 
 	default:
 		return -EINVAL;
@@ -466,48 +428,23 @@ saa7111_command (struct i2c_client *client,
 
 /* ----------------------------------------------------------------------- */
 
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END };
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.probe			= &ignore,
-	.ignore			= &ignore,
-};
+static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END };
 
-static struct i2c_driver i2c_driver_saa7111;
+I2C_CLIENT_INSMOD;
 
-static int
-saa7111_detect_client (struct i2c_adapter *adapter,
-		       int                 address,
-		       int                 kind)
+static int saa7111_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	int i;
-	struct i2c_client *client;
 	struct saa7111 *decoder;
 	struct video_decoder_init vdi;
 
-	dprintk(1,
-		KERN_INFO
-		"saa7111.c: detecting saa7111 client on address 0x%x\n",
-		address << 1);
-
 	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
 
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = &i2c_driver_saa7111;
-	strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client)));
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
 	decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL);
 	if (decoder == NULL) {
@@ -519,82 +456,37 @@ saa7111_detect_client (struct i2c_adapter *adapter,
 	decoder->enable = 1;
 	i2c_set_clientdata(client, decoder);
 
-	i = i2c_attach_client(client);
-	if (i) {
-		kfree(client);
-		kfree(decoder);
-		return i;
-	}
-
 	vdi.data = saa7111_i2c_init;
 	vdi.len = sizeof(saa7111_i2c_init);
 	i = saa7111_init_decoder(client, &vdi);
 	if (i < 0) {
-		dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
-			I2C_NAME(client), i);
+		v4l_dbg(1, debug, client, "init status %d\n", i);
 	} else {
-		dprintk(1,
-			KERN_INFO
-			"%s_attach: chip version %x at address 0x%x\n",
-			I2C_NAME(client), saa7111_read(client, 0x00) >> 4,
-			client->addr << 1);
+		v4l_dbg(1, debug, client, "revision %x\n",
+			saa7111_read(client, 0x00) >> 4);
 	}
-
 	return 0;
 }
 
-static int
-saa7111_attach_adapter (struct i2c_adapter *adapter)
+static int saa7111_remove(struct i2c_client *client)
 {
-	dprintk(1,
-		KERN_INFO
-		"saa7111.c: starting probe for adapter %s (0x%x)\n",
-		I2C_NAME(adapter), adapter->id);
-	return i2c_probe(adapter, &addr_data, &saa7111_detect_client);
-}
-
-static int
-saa7111_detach_client (struct i2c_client *client)
-{
-	struct saa7111 *decoder = i2c_get_clientdata(client);
-	int err;
-
-	err = i2c_detach_client(client);
-	if (err) {
-		return err;
-	}
-
-	kfree(decoder);
-	kfree(client);
-
+	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver i2c_driver_saa7111 = {
-	.driver = {
-		.name = "saa7111",
-	},
-
-	.id = I2C_DRIVERID_SAA7111A,
+static const struct i2c_device_id saa7111_id[] = {
+	{ "saa7111_old", 0 },	/* "saa7111" maps to the saa7115 driver */
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, saa7111_id);
 
-	.attach_adapter = saa7111_attach_adapter,
-	.detach_client = saa7111_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "saa7111",
+	.driverid = I2C_DRIVERID_SAA7111A,
 	.command = saa7111_command,
+	.probe = saa7111_probe,
+	.remove = saa7111_remove,
+	.id_table = saa7111_id,
 };
-
-static int __init
-saa7111_init (void)
-{
-	return i2c_add_driver(&i2c_driver_saa7111);
-}
-
-static void __exit
-saa7111_exit (void)
-{
-	i2c_del_driver(&i2c_driver_saa7111);
-}
-
-module_init(saa7111_init);
-module_exit(saa7111_exit);

+ 108 - 256
drivers/media/video/saa7114.c

@@ -29,43 +29,24 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
 #include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
 #include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
 #include <linux/videodev.h>
 #include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
 
 MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
 MODULE_AUTHOR("Maxim Yevtyushkin");
 MODULE_LICENSE("GPL");
 
-
-#define I2C_NAME(x) (x)->name
-
-
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
-	do { \
-		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
-
 /* ----------------------------------------------------------------------- */
 
 struct saa7114 {
@@ -81,9 +62,6 @@ struct saa7114 {
 	int playback;
 };
 
-#define   I2C_SAA7114        0x42
-#define   I2C_SAA7114A       0x40
-
 #define   I2C_DELAY   10
 
 
@@ -129,18 +107,12 @@ struct saa7114 {
 
 /* ----------------------------------------------------------------------- */
 
-static inline int
-saa7114_write (struct i2c_client *client,
-	       u8                 reg,
-	       u8                 value)
+static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value)
 {
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static int
-saa7114_write_block (struct i2c_client *client,
-		     const u8          *data,
-		     unsigned int       len)
+static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
 {
 	int ret = -1;
 	u8 reg;
@@ -160,18 +132,17 @@ saa7114_write_block (struct i2c_client *client,
 				reg++;
 				len -= 2;
 				data += 2;
-			} while (len >= 2 && data[0] == reg &&
-				 block_len < 32);
-			if ((ret = i2c_master_send(client, block_data,
-						   block_len)) < 0)
+			} while (len >= 2 && data[0] == reg && block_len < 32);
+			ret = i2c_master_send(client, block_data, block_len);
+			if (ret < 0)
 				break;
 		}
 	} else {
 		/* do some slow I2C emulation kind of thing */
 		while (len >= 2) {
 			reg = *data++;
-			if ((ret = saa7114_write(client, reg,
-						 *data++)) < 0)
+			ret = saa7114_write(client, reg, *data++);
+			if (ret < 0)
 				break;
 			len -= 2;
 		}
@@ -180,9 +151,7 @@ saa7114_write_block (struct i2c_client *client,
 	return ret;
 }
 
-static inline int
-saa7114_read (struct i2c_client *client,
-	      u8                 reg)
+static inline int saa7114_read(struct i2c_client *client, u8 reg)
 {
 	return i2c_smbus_read_byte_data(client, reg);
 }
@@ -452,15 +421,11 @@ static const unsigned char init[] = {
 	0xef, 0x00
 };
 
-static int
-saa7114_command (struct i2c_client *client,
-		 unsigned int       cmd,
-		 void              *arg)
+static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
 	struct saa7114 *decoder = i2c_get_clientdata(client);
 
 	switch (cmd) {
-
 	case 0:
 		//dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
 		//saa7114_write_block(client, init, sizeof(init));
@@ -470,27 +435,28 @@ saa7114_command (struct i2c_client *client,
 	{
 		int i;
 
-		dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
+		if (!debug)
+			break;
+		v4l_info(client, "decoder dump\n");
 
 		for (i = 0; i < 32; i += 16) {
 			int j;
 
-			printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
+			v4l_info(client, "%03x", i);
 			for (j = 0; j < 16; ++j) {
-				printk(" %02x",
+				printk(KERN_CONT " %02x",
 				       saa7114_read(client, i + j));
 			}
-			printk("\n");
+			printk(KERN_CONT "\n");
 		}
-	}
 		break;
+	}
 
 	case DECODER_GET_CAPABILITIES:
 	{
 		struct video_decoder_capability *cap = arg;
 
-		dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
-			I2C_NAME(client));
+		v4l_dbg(1, debug, client, "get capabilities\n");
 
 		cap->flags = VIDEO_DECODER_PAL |
 			     VIDEO_DECODER_NTSC |
@@ -498,8 +464,8 @@ saa7114_command (struct i2c_client *client,
 			     VIDEO_DECODER_CCIR;
 		cap->inputs = 8;
 		cap->outputs = 1;
-	}
 		break;
+	}
 
 	case DECODER_GET_STATUS:
 	{
@@ -509,8 +475,7 @@ saa7114_command (struct i2c_client *client,
 
 		status = saa7114_read(client, 0x1f);
 
-		dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
-			status);
+		v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
 		res = 0;
 		if ((status & (1 << 6)) == 0) {
 			res |= DECODER_STATUS_GOOD;
@@ -538,8 +503,8 @@ saa7114_command (struct i2c_client *client,
 			res |= DECODER_STATUS_COLOR;
 		}
 		*iarg = res;
-	}
 		break;
+	}
 
 	case DECODER_SET_NORM:
 	{
@@ -547,12 +512,11 @@ saa7114_command (struct i2c_client *client,
 
 		short int hoff = 0, voff = 0, w = 0, h = 0;
 
-		dprintk(1, KERN_DEBUG "%s: decoder set norm ",
-			I2C_NAME(client));
-		switch (*iarg) {
+		v4l_dbg(1, debug, client, "set norm\n");
 
+		switch (*iarg) {
 		case VIDEO_MODE_NTSC:
-			dprintk(1, "NTSC\n");
+			v4l_dbg(1, debug, client, "NTSC\n");
 			decoder->reg[REG_ADDR(0x06)] =
 			    SAA_7114_NTSC_HSYNC_START;
 			decoder->reg[REG_ADDR(0x07)] =
@@ -571,7 +535,7 @@ saa7114_command (struct i2c_client *client,
 			break;
 
 		case VIDEO_MODE_PAL:
-			dprintk(1, "PAL\n");
+			v4l_dbg(1, debug, client, "PAL\n");
 			decoder->reg[REG_ADDR(0x06)] =
 			    SAA_7114_PAL_HSYNC_START;
 			decoder->reg[REG_ADDR(0x07)] =
@@ -590,9 +554,8 @@ saa7114_command (struct i2c_client *client,
 			break;
 
 		default:
-			dprintk(1, " Unknown video mode!!!\n");
+			v4l_dbg(1, debug, client, "Unknown video mode\n");
 			return -EINVAL;
-
 		}
 
 
@@ -644,22 +607,20 @@ saa7114_command (struct i2c_client *client,
 		saa7114_write(client, 0x80, 0x36);	// i-port and scaler back end clock selection
 
 		decoder->norm = *iarg;
-	}
 		break;
+	}
 
 	case DECODER_SET_INPUT:
 	{
 		int *iarg = arg;
 
-		dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n",
-			I2C_NAME(client), *iarg);
+		v4l_dbg(1, debug, client, "set input (%d)\n", *iarg);
 		if (*iarg < 0 || *iarg > 7) {
 			return -EINVAL;
 		}
 
 		if (decoder->input != *iarg) {
-			dprintk(1, KERN_DEBUG "%s: now setting %s input\n",
-				I2C_NAME(client),
+			v4l_dbg(1, debug, client, "now setting %s input\n",
 				*iarg >= 6 ? "S-Video" : "Composite");
 			decoder->input = *iarg;
 
@@ -690,30 +651,29 @@ saa7114_command (struct i2c_client *client,
 			saa7114_write(client, 0x0e,
 				      decoder->reg[REG_ADDR(0x0e)]);
 		}
-	}
 		break;
+	}
 
 	case DECODER_SET_OUTPUT:
 	{
 		int *iarg = arg;
 
-		dprintk(1, KERN_DEBUG "%s: decoder set output\n",
-			I2C_NAME(client));
+		v4l_dbg(1, debug, client, "set output\n");
 
 		/* not much choice of outputs */
 		if (*iarg != 0) {
 			return -EINVAL;
 		}
-	}
 		break;
+	}
 
 	case DECODER_ENABLE_OUTPUT:
 	{
 		int *iarg = arg;
 		int enable = (*iarg != 0);
 
-		dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
-			I2C_NAME(client), enable ? "enable" : "disable");
+		v4l_dbg(1, debug, client, "%s output\n",
+			enable ? "enable" : "disable");
 
 		decoder->playback = !enable;
 
@@ -754,18 +714,16 @@ saa7114_command (struct i2c_client *client,
 			saa7114_write(client, 0x80, 0x36);
 
 		}
-	}
 		break;
+	}
 
 	case DECODER_SET_PICTURE:
 	{
 		struct video_picture *pic = arg;
 
-		dprintk(1,
-			KERN_DEBUG
-			"%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
-			I2C_NAME(client), pic->brightness, pic->contrast,
-			pic->colour, pic->hue);
+		v4l_dbg(1, debug, client,
+			"decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
+			pic->brightness, pic->contrast, pic->colour, pic->hue);
 
 		if (decoder->bright != pic->brightness) {
 			/* We want 0 to 255 we get 0-65535 */
@@ -789,8 +747,8 @@ saa7114_command (struct i2c_client *client,
 			saa7114_write(client, 0x0d,
 				      (decoder->hue - 32768) >> 8);
 		}
-	}
 		break;
+	}
 
 	default:
 		return -EINVAL;
@@ -801,58 +759,30 @@ saa7114_command (struct i2c_client *client,
 
 /* ----------------------------------------------------------------------- */
 
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] =
-    { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.probe			= &ignore,
-	.ignore			= &ignore,
-};
+static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
 
-static struct i2c_driver i2c_driver_saa7114;
+I2C_CLIENT_INSMOD;
 
-static int
-saa7114_detect_client (struct i2c_adapter *adapter,
-		       int                 address,
-		       int                 kind)
+static int saa7114_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	int i, err[30];
 	short int hoff = SAA_7114_NTSC_HOFFSET;
 	short int voff = SAA_7114_NTSC_VOFFSET;
 	short int w = SAA_7114_NTSC_WIDTH;
 	short int h = SAA_7114_NTSC_HEIGHT;
-	struct i2c_client *client;
 	struct saa7114 *decoder;
 
-	dprintk(1,
-		KERN_INFO
-		"saa7114.c: detecting saa7114 client on address 0x%x\n",
-		address << 1);
-
 	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
 
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = &i2c_driver_saa7114;
-	strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
 	decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
-	if (decoder == NULL) {
-		kfree(client);
+	if (decoder == NULL)
 		return -ENOMEM;
-	}
 	decoder->norm = VIDEO_MODE_NTSC;
 	decoder->input = -1;
 	decoder->enable = 1;
@@ -937,8 +867,7 @@ saa7114_detect_client (struct i2c_adapter *adapter,
 	decoder->reg[REG_ADDR(0x0e)] |= 1;	// combfilter on
 
 
-	dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
-		I2C_NAME(client));
+	v4l_dbg(1, debug, client, "starting init\n");
 
 	err[0] =
 	    saa7114_write_block(client, decoder->reg + (0x20 << 1),
@@ -962,28 +891,23 @@ saa7114_detect_client (struct i2c_adapter *adapter,
 
 	for (i = 0; i <= 5; i++) {
 		if (err[i] < 0) {
-			dprintk(1,
-				KERN_ERR
-				"%s_attach: init error %d at stage %d, leaving attach.\n",
-				I2C_NAME(client), i, err[i]);
+			v4l_dbg(1, debug, client,
+				"init error %d at stage %d, leaving attach.\n",
+				i, err[i]);
 			kfree(decoder);
-			kfree(client);
-			return 0;
+			return -EIO;
 		}
 	}
 
 	for (i = 6; i < 8; i++) {
-		dprintk(1,
-			KERN_DEBUG
-			"%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
-			I2C_NAME(client), i, saa7114_read(client, i),
+		v4l_dbg(1, debug, client,
+			"reg[0x%02x] = 0x%02x (0x%02x)\n",
+			i, saa7114_read(client, i),
 			decoder->reg[REG_ADDR(i)]);
 	}
 
-	dprintk(1,
-		KERN_DEBUG
-		"%s_attach: performing decoder reset sequence\n",
-		I2C_NAME(client));
+	v4l_dbg(1, debug, client,
+		"performing decoder reset sequence\n");
 
 	err[6] = saa7114_write(client, 0x80, 0x06);	// i-port and scaler backend clock selection, task A&B off
 	err[7] = saa7114_write(client, 0x88, 0xd8);	// sw reset scaler
@@ -991,19 +915,15 @@ saa7114_detect_client (struct i2c_adapter *adapter,
 
 	for (i = 6; i <= 8; i++) {
 		if (err[i] < 0) {
-			dprintk(1,
-				KERN_ERR
-				"%s_attach: init error %d at stage %d, leaving attach.\n",
-				I2C_NAME(client), i, err[i]);
+			v4l_dbg(1, debug, client,
+				"init error %d at stage %d, leaving attach.\n",
+				i, err[i]);
 			kfree(decoder);
-			kfree(client);
-			return 0;
+			return -EIO;
 		}
 	}
 
-	dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
-		I2C_NAME(client));
-
+	v4l_dbg(1, debug, client, "performing the rest of init\n");
 
 	err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
 	err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1);	// big seq
@@ -1039,37 +959,32 @@ saa7114_detect_client (struct i2c_adapter *adapter,
 
 	for (i = 9; i <= 18; i++) {
 		if (err[i] < 0) {
-			dprintk(1,
-				KERN_ERR
-				"%s_attach: init error %d at stage %d, leaving attach.\n",
-				I2C_NAME(client), i, err[i]);
+			v4l_dbg(1, debug, client,
+				"init error %d at stage %d, leaving attach.\n",
+				i, err[i]);
 			kfree(decoder);
-			kfree(client);
-			return 0;
+			return -EIO;
 		}
 	}
 
 
 	for (i = 6; i < 8; i++) {
-		dprintk(1,
-			KERN_DEBUG
-			"%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
-			I2C_NAME(client), i, saa7114_read(client, i),
+		v4l_dbg(1, debug, client,
+			"reg[0x%02x] = 0x%02x (0x%02x)\n",
+			i, saa7114_read(client, i),
 			decoder->reg[REG_ADDR(i)]);
 	}
 
 
 	for (i = 0x11; i <= 0x13; i++) {
-		dprintk(1,
-			KERN_DEBUG
-			"%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
-			I2C_NAME(client), i, saa7114_read(client, i),
+		v4l_dbg(1, debug, client,
+			"reg[0x%02x] = 0x%02x (0x%02x)\n",
+			i, saa7114_read(client, i),
 			decoder->reg[REG_ADDR(i)]);
 	}
 
 
-	dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
-		I2C_NAME(client));
+	v4l_dbg(1, debug, client, "setting video input\n");
 
 	err[19] =
 	    saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
@@ -1080,20 +995,15 @@ saa7114_detect_client (struct i2c_adapter *adapter,
 
 	for (i = 19; i <= 21; i++) {
 		if (err[i] < 0) {
-			dprintk(1,
-				KERN_ERR
-				"%s_attach: init error %d at stage %d, leaving attach.\n",
-				I2C_NAME(client), i, err[i]);
+			v4l_dbg(1, debug, client,
+				"init error %d at stage %d, leaving attach.\n",
+				i, err[i]);
 			kfree(decoder);
-			kfree(client);
-			return 0;
+			return -EIO;
 		}
 	}
 
-	dprintk(1,
-		KERN_DEBUG
-		"%s_attach: performing decoder reset sequence\n",
-		I2C_NAME(client));
+	v4l_dbg(1, debug, client, "performing decoder reset sequence\n");
 
 	err[22] = saa7114_write(client, 0x88, 0xd8);	// sw reset scaler
 	err[23] = saa7114_write(client, 0x88, 0xf8);	// sw reset scaler release
@@ -1102,13 +1012,11 @@ saa7114_detect_client (struct i2c_adapter *adapter,
 
 	for (i = 22; i <= 24; i++) {
 		if (err[i] < 0) {
-			dprintk(1,
-				KERN_ERR
-				"%s_attach: init error %d at stage %d, leaving attach.\n",
-				I2C_NAME(client), i, err[i]);
+			v4l_dbg(1, debug, client,
+				"init error %d at stage %d, leaving attach.\n",
+				i, err[i]);
 			kfree(decoder);
-			kfree(client);
-			return 0;
+			return -EIO;
 		}
 	}
 
@@ -1116,101 +1024,45 @@ saa7114_detect_client (struct i2c_adapter *adapter,
 	err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
 	err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
 
-	dprintk(1,
-		KERN_INFO
-		"%s_attach: chip version %x, decoder status 0x%02x\n",
-		I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
+	v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n",
+		saa7114_read(client, 0x00) >> 4,
 		saa7114_read(client, 0x1f));
-	dprintk(1,
-		KERN_DEBUG
-		"%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
-		I2C_NAME(client), saa7114_read(client, 0x88),
+	v4l_dbg(1, debug, client,
+		"power save control: 0x%02x, scaler status: 0x%02x\n",
+		saa7114_read(client, 0x88),
 		saa7114_read(client, 0x8f));
 
 
 	for (i = 0x94; i < 0x96; i++) {
-		dprintk(1,
-			KERN_DEBUG
-			"%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
-			I2C_NAME(client), i, saa7114_read(client, i),
+		v4l_dbg(1, debug, client,
+			"reg[0x%02x] = 0x%02x (0x%02x)\n",
+			i, saa7114_read(client, i),
 			decoder->reg[REG_ADDR(i)]);
 	}
 
-	i = i2c_attach_client(client);
-	if (i) {
-		kfree(client);
-		kfree(decoder);
-		return i;
-	}
-
 	//i = saa7114_write_block(client, init, sizeof(init));
-	i = 0;
-	if (i < 0) {
-		dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
-			I2C_NAME(client), i);
-	} else {
-		dprintk(1,
-			KERN_INFO
-			"%s_attach: chip version %x at address 0x%x\n",
-			I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
-			client->addr << 1);
-	}
-
 	return 0;
 }
 
-static int
-saa7114_attach_adapter (struct i2c_adapter *adapter)
-{
-	dprintk(1,
-		KERN_INFO
-		"saa7114.c: starting probe for adapter %s (0x%x)\n",
-		I2C_NAME(adapter), adapter->id);
-	return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
-}
-
-static int
-saa7114_detach_client (struct i2c_client *client)
+static int saa7114_remove(struct i2c_client *client)
 {
-	struct saa7114 *decoder = i2c_get_clientdata(client);
-	int err;
-
-	err = i2c_detach_client(client);
-	if (err) {
-		return err;
-	}
-
-	kfree(decoder);
-	kfree(client);
-
+	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver i2c_driver_saa7114 = {
-	.driver = {
-		.name = "saa7114",
-	},
-
-	.id = I2C_DRIVERID_SAA7114,
+static const struct i2c_device_id saa7114_id[] = {
+	{ "saa7114_old", 0 },	/* "saa7114" maps to the saa7115 driver */
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, saa7114_id);
 
-	.attach_adapter = saa7114_attach_adapter,
-	.detach_client = saa7114_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "saa7114",
+	.driverid = I2C_DRIVERID_SAA7114,
 	.command = saa7114_command,
+	.probe = saa7114_probe,
+	.remove = saa7114_remove,
+	.id_table = saa7114_id,
 };
-
-static int __init
-saa7114_init (void)
-{
-	return i2c_add_driver(&i2c_driver_saa7114);
-}
-
-static void __exit
-saa7114_exit (void)
-{
-	i2c_del_driver(&i2c_driver_saa7114);
-}
-
-module_init(saa7114_init);
-module_exit(saa7114_exit);

+ 1 - 1
drivers/media/video/saa7127.c

@@ -29,7 +29,7 @@
  * Note: the saa7126 is identical to the saa7127, and the saa7128 is
  * identical to the saa7129, except that the saa7126 and saa7128 have
  * macrovision anti-taping support. This driver will almost certainly
- * work find for those chips, except of course for the missing anti-taping
+ * work fine for those chips, except of course for the missing anti-taping
  * support.
  *
  * This program is free software; you can redistribute it and/or modify

+ 123 - 93
drivers/media/video/saa7134/saa7134-dvb.c

@@ -535,11 +535,16 @@ static int configure_tda827x_fe(struct saa7134_dev *dev,
 				struct tda1004x_config *cdec_conf,
 				struct tda827x_config *tuner_conf)
 {
-	dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
-	if (dev->dvb.frontend) {
+	struct videobuf_dvb_frontend *fe0;
+
+	/* Get the first frontend */
+	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+
+	fe0->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
+	if (fe0->dvb.frontend) {
 		if (cdec_conf->i2c_gate)
-			dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
-		if (dvb_attach(tda827x_attach, dev->dvb.frontend,
+			fe0->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
+		if (dvb_attach(tda827x_attach, fe0->dvb.frontend,
 			       cdec_conf->tuner_address,
 			       &dev->i2c_adap, tuner_conf))
 			return 0;
@@ -944,12 +949,30 @@ static int dvb_init(struct saa7134_dev *dev)
 {
 	int ret;
 	int attach_xc3028 = 0;
+	struct videobuf_dvb_frontend *fe0;
+
+	/* FIXME: add support for multi-frontend */
+	mutex_init(&dev->frontends.lock);
+	INIT_LIST_HEAD(&dev->frontends.felist);
+	dev->frontends.active_fe_id = 0;
+
+	printk(KERN_INFO "%s() allocating 1 frontend\n", __func__);
+
+	if (videobuf_dvb_alloc_frontend(&dev->frontends, 1) == NULL) {
+		printk(KERN_ERR "%s() failed to alloc\n", __func__);
+		return -ENOMEM;
+	}
+
+	/* Get the first frontend */
+	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+	if (!fe0)
+		return -EINVAL;
 
 	/* init struct videobuf_dvb */
 	dev->ts.nr_bufs    = 32;
 	dev->ts.nr_packets = 32*4;
-	dev->dvb.name = dev->name;
-	videobuf_queue_sg_init(&dev->dvb.dvbq, &saa7134_ts_qops,
+	fe0->dvb.name = dev->name;
+	videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops,
 			    &dev->pci->dev, &dev->slock,
 			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
 			    V4L2_FIELD_ALTERNATE,
@@ -959,47 +982,47 @@ static int dvb_init(struct saa7134_dev *dev)
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
 		dprintk("pinnacle 300i dvb setup\n");
-		dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
+		fe0->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
+		if (fe0->dvb.frontend) {
+			fe0->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
 		}
 		break;
 	case SAA7134_BOARD_AVERMEDIA_777:
 	case SAA7134_BOARD_AVERMEDIA_A16AR:
 		dprintk("avertv 777 dvb setup\n");
-		dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
+		fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend) {
+			dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 				   &dev->i2c_adap, 0x61,
 				   TUNER_PHILIPS_TD1316);
 		}
 		break;
 	case SAA7134_BOARD_AVERMEDIA_A16D:
 		dprintk("AverMedia A16D dvb setup\n");
-		dev->dvb.frontend = dvb_attach(mt352_attach,
+		fe0->dvb.frontend = dvb_attach(mt352_attach,
 						&avermedia_xc3028_mt352_dev,
 						&dev->i2c_adap);
 		attach_xc3028 = 1;
 		break;
 	case SAA7134_BOARD_MD7134:
-		dev->dvb.frontend = dvb_attach(tda10046_attach,
+		fe0->dvb.frontend = dvb_attach(tda10046_attach,
 					       &medion_cardbus,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend) {
+			dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 				   &dev->i2c_adap, medion_cardbus.tuner_address,
 				   TUNER_PHILIPS_FMD1216ME_MK3);
 		}
 		break;
 	case SAA7134_BOARD_PHILIPS_TOUGH:
-		dev->dvb.frontend = dvb_attach(tda10046_attach,
+		fe0->dvb.frontend = dvb_attach(tda10046_attach,
 					       &philips_tu1216_60_config,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
-			dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
+		if (fe0->dvb.frontend) {
+			fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
+			fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
 		}
 		break;
 	case SAA7134_BOARD_FLYDVBTDUO:
@@ -1010,24 +1033,24 @@ static int dvb_init(struct saa7134_dev *dev)
 		break;
 	case SAA7134_BOARD_PHILIPS_EUROPA:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
-		dev->dvb.frontend = dvb_attach(tda10046_attach,
+		fe0->dvb.frontend = dvb_attach(tda10046_attach,
 					       &philips_europa_config,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
-			dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
-			dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
-			dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
-			dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
+		if (fe0->dvb.frontend) {
+			dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
+			fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+			fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
+			fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
+			fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
 		}
 		break;
 	case SAA7134_BOARD_VIDEOMATE_DVBT_200:
-		dev->dvb.frontend = dvb_attach(tda10046_attach,
+		fe0->dvb.frontend = dvb_attach(tda10046_attach,
 					       &philips_tu1216_61_config,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
-			dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
+		if (fe0->dvb.frontend) {
+			fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
+			fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
 		}
 		break;
 	case SAA7134_BOARD_KWORLD_DVBT_210:
@@ -1066,14 +1089,14 @@ static int dvb_init(struct saa7134_dev *dev)
 						 &tda827x_cfg_0) < 0)
 				goto dettach_frontend;
 		} else {  		/* satellite */
-			dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
-			if (dev->dvb.frontend) {
-				if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
+			fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
+			if (fe0->dvb.frontend) {
+				if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63,
 									&dev->i2c_adap, 0) == NULL) {
 					wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
 					goto dettach_frontend;
 				}
-				if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
+				if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap,
 										0x08, 0, 0) == NULL) {
 					wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
 					goto dettach_frontend;
@@ -1083,11 +1106,11 @@ static int dvb_init(struct saa7134_dev *dev)
 		break;
 	case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
 	case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
-		dev->dvb.frontend = dvb_attach(tda10046_attach,
+		fe0->dvb.frontend = dvb_attach(tda10046_attach,
 					       &ads_tech_duo_config,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			if (dvb_attach(tda827x_attach,dev->dvb.frontend,
+		if (fe0->dvb.frontend) {
+			if (dvb_attach(tda827x_attach,fe0->dvb.frontend,
 				   ads_tech_duo_config.tuner_address, &dev->i2c_adap,
 								&ads_duo_cfg) == NULL) {
 				wprintk("no tda827x tuner found at addr: %02x\n",
@@ -1108,15 +1131,15 @@ static int dvb_init(struct saa7134_dev *dev)
 						 &tda827x_cfg_0) < 0)
 				goto dettach_frontend;
 		} else {        /* satellite */
-			dev->dvb.frontend = dvb_attach(tda10086_attach,
+			fe0->dvb.frontend = dvb_attach(tda10086_attach,
 							&flydvbs, &dev->i2c_adap);
-			if (dev->dvb.frontend) {
-				struct dvb_frontend *fe = dev->dvb.frontend;
+			if (fe0->dvb.frontend) {
+				struct dvb_frontend *fe = fe0->dvb.frontend;
 				u8 dev_id = dev->eedata[2];
 				u8 data = 0xc4;
 				struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
 
-				if (dvb_attach(tda826x_attach, dev->dvb.frontend,
+				if (dvb_attach(tda826x_attach, fe0->dvb.frontend,
 						0x60, &dev->i2c_adap, 0) == NULL) {
 					wprintk("%s: Medion Quadro, no tda826x "
 						"found !\n", __func__);
@@ -1150,31 +1173,31 @@ static int dvb_init(struct saa7134_dev *dev)
 		}
 		break;
 	case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
-		dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
+		fe0->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend)
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+		if (fe0->dvb.frontend)
+			dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61,
 				   NULL, DVB_PLL_TDHU2);
 		break;
 	case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
 	case SAA7134_BOARD_KWORLD_ATSC110:
-		dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
+		fe0->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend)
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+		if (fe0->dvb.frontend)
+			dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 				   &dev->i2c_adap, 0x61,
 				   TUNER_PHILIPS_TUV1236D);
 		break;
 	case SAA7134_BOARD_FLYDVBS_LR300:
-		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+		fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+		if (fe0->dvb.frontend) {
+			if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
 				       &dev->i2c_adap, 0) == NULL) {
 				wprintk("%s: No tda826x found!\n", __func__);
 				goto dettach_frontend;
 			}
-			if (dvb_attach(isl6421_attach, dev->dvb.frontend,
+			if (dvb_attach(isl6421_attach, fe0->dvb.frontend,
 				       &dev->i2c_adap, 0x08, 0, 0) == NULL) {
 				wprintk("%s: No ISL6421 found!\n", __func__);
 				goto dettach_frontend;
@@ -1182,25 +1205,25 @@ static int dvb_init(struct saa7134_dev *dev)
 		}
 		break;
 	case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
-		dev->dvb.frontend = dvb_attach(tda10046_attach,
+		fe0->dvb.frontend = dvb_attach(tda10046_attach,
 					       &medion_cardbus,
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
-			dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+		if (fe0->dvb.frontend) {
+			dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
+			fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
 
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+			dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 				   &dev->i2c_adap, medion_cardbus.tuner_address,
 				   TUNER_PHILIPS_FMD1216ME_MK3);
 		}
 		break;
 	case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
-		dev->dvb.frontend = dvb_attach(tda10046_attach,
+		fe0->dvb.frontend = dvb_attach(tda10046_attach,
 				&philips_europa_config,
 				&dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			dev->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
-			dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
+		if (fe0->dvb.frontend) {
+			fe0->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
+			fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
 		}
 		break;
 	case SAA7134_BOARD_CINERGY_HT_PCMCIA:
@@ -1239,15 +1262,15 @@ static int dvb_init(struct saa7134_dev *dev)
 			goto dettach_frontend;
 		break;
 	case SAA7134_BOARD_PHILIPS_SNAKE:
-		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+		fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
 						&dev->i2c_adap);
-		if (dev->dvb.frontend) {
-			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+		if (fe0->dvb.frontend) {
+			if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
 					&dev->i2c_adap, 0) == NULL) {
 				wprintk("%s: No tda826x found!\n", __func__);
 				goto dettach_frontend;
 			}
-			if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
+			if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
 					&dev->i2c_adap, 0, 0) == NULL) {
 				wprintk("%s: No lnbp21 found!\n", __func__);
 				goto dettach_frontend;
@@ -1269,24 +1292,24 @@ static int dvb_init(struct saa7134_dev *dev)
 		saa7134_set_gpio(dev, 25, 0);
 		msleep(10);
 		saa7134_set_gpio(dev, 25, 1);
-		dev->dvb.frontend = dvb_attach(mt352_attach,
+		fe0->dvb.frontend = dvb_attach(mt352_attach,
 						&avermedia_xc3028_mt352_dev,
 						&dev->i2c_adap);
 		attach_xc3028 = 1;
 		break;
 	case SAA7134_BOARD_MD7134_BRIDGE_2:
-		dev->dvb.frontend = dvb_attach(tda10086_attach,
+		fe0->dvb.frontend = dvb_attach(tda10086_attach,
 						&sd1878_4m, &dev->i2c_adap);
-		if (dev->dvb.frontend) {
+		if (fe0->dvb.frontend) {
 			struct dvb_frontend *fe;
-			if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+			if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
 				  &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
 				wprintk("%s: MD7134 DVB-S, no SD1878 "
 					"found !\n", __func__);
 				goto dettach_frontend;
 			}
 			/* we need to open the i2c gate (we know it exists) */
-			fe = dev->dvb.frontend;
+			fe = fe0->dvb.frontend;
 			fe->ops.i2c_gate_ctrl(fe, 1);
 			if (dvb_attach(isl6405_attach, fe,
 					&dev->i2c_adap, 0x08, 0, 0) == NULL) {
@@ -1305,7 +1328,7 @@ static int dvb_init(struct saa7134_dev *dev)
 		saa7134_set_gpio(dev, 25, 0);
 		msleep(10);
 		saa7134_set_gpio(dev, 25, 1);
-		dev->dvb.frontend = dvb_attach(mt352_attach,
+		fe0->dvb.frontend = dvb_attach(mt352_attach,
 						&avermedia_xc3028_mt352_dev,
 						&dev->i2c_adap);
 		attach_xc3028 = 1;
@@ -1316,17 +1339,17 @@ static int dvb_init(struct saa7134_dev *dev)
 							&tda827x_cfg_2) < 0)
 				goto dettach_frontend;
 		} else {  		/* satellite */
-			dev->dvb.frontend = dvb_attach(tda10086_attach,
+			fe0->dvb.frontend = dvb_attach(tda10086_attach,
 						&flydvbs, &dev->i2c_adap);
-			if (dev->dvb.frontend) {
+			if (fe0->dvb.frontend) {
 				if (dvb_attach(tda826x_attach,
-						dev->dvb.frontend, 0x60,
+						fe0->dvb.frontend, 0x60,
 						&dev->i2c_adap, 0) == NULL) {
 					wprintk("%s: Asus Tiger 3in1, no "
 						"tda826x found!\n", __func__);
 					goto dettach_frontend;
 				}
-				if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
+				if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
 						&dev->i2c_adap, 0, 0) == NULL) {
 					wprintk("%s: Asus Tiger 3in1, no lnbp21"
 						" found!\n", __func__);
@@ -1352,10 +1375,10 @@ static int dvb_init(struct saa7134_dev *dev)
 			.i2c_addr  = 0x61,
 		};
 
-		if (!dev->dvb.frontend)
+		if (!fe0->dvb.frontend)
 			return -1;
 
-		fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
+		fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
 		if (!fe) {
 			printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 			       dev->name);
@@ -1363,40 +1386,47 @@ static int dvb_init(struct saa7134_dev *dev)
 		}
 	}
 
-	if (NULL == dev->dvb.frontend) {
+	if (NULL == fe0->dvb.frontend) {
 		printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name);
 		return -1;
 	}
 	/* define general-purpose callback pointer */
-	dev->dvb.frontend->callback = saa7134_tuner_callback;
+	fe0->dvb.frontend->callback = saa7134_tuner_callback;
 
 	/* register everything else */
-	ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev,
-				    adapter_nr);
+	ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
+		&dev->pci->dev, adapter_nr, 0);
 
 	/* this sequence is necessary to make the tda1004x load its firmware
 	 * and to enter analog mode of hybrid boards
 	 */
 	if (!ret) {
-		if (dev->dvb.frontend->ops.init)
-			dev->dvb.frontend->ops.init(dev->dvb.frontend);
-		if (dev->dvb.frontend->ops.sleep)
-			dev->dvb.frontend->ops.sleep(dev->dvb.frontend);
-		if (dev->dvb.frontend->ops.tuner_ops.sleep)
-			dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
+		if (fe0->dvb.frontend->ops.init)
+			fe0->dvb.frontend->ops.init(fe0->dvb.frontend);
+		if (fe0->dvb.frontend->ops.sleep)
+			fe0->dvb.frontend->ops.sleep(fe0->dvb.frontend);
+		if (fe0->dvb.frontend->ops.tuner_ops.sleep)
+			fe0->dvb.frontend->ops.tuner_ops.sleep(fe0->dvb.frontend);
 	}
 	return ret;
 
 dettach_frontend:
-	if (dev->dvb.frontend)
-		dvb_frontend_detach(dev->dvb.frontend);
-	dev->dvb.frontend = NULL;
+	if (fe0->dvb.frontend)
+		dvb_frontend_detach(fe0->dvb.frontend);
+	fe0->dvb.frontend = NULL;
 
 	return -1;
 }
 
 static int dvb_fini(struct saa7134_dev *dev)
 {
+	struct videobuf_dvb_frontend *fe0;
+
+	/* Get the first frontend */
+	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+	if (!fe0)
+		return -EINVAL;
+
 	/* FIXME: I suspect that this code is bogus, since the entry for
 	   Pinnacle 300I DVB-T PAL already defines the proper init to allow
 	   the detection of mt2032 (TDA9887_PORT2_INACTIVE)
@@ -1416,7 +1446,7 @@ static int dvb_fini(struct saa7134_dev *dev)
 			u8 data = 0x80;
 			struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1};
 			struct dvb_frontend *fe;
-			fe = dev->dvb.frontend;
+			fe = fe0->dvb.frontend;
 			if (fe->ops.i2c_gate_ctrl) {
 				fe->ops.i2c_gate_ctrl(fe, 1);
 				i2c_transfer(&dev->i2c_adap, &msg, 1);
@@ -1424,8 +1454,8 @@ static int dvb_fini(struct saa7134_dev *dev)
 			}
 		}
 	}
-	if (dev->dvb.frontend)
-		videobuf_dvb_unregister(&dev->dvb);
+	if (fe0->dvb.frontend)
+		videobuf_dvb_unregister_bus(&dev->frontends);
 	return 0;
 }
 

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

@@ -581,7 +581,7 @@ struct saa7134_dev {
 
 #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE)
 	/* SAA7134_MPEG_DVB only */
-	struct videobuf_dvb        dvb;
+	struct videobuf_dvb_frontends frontends;
 	int (*original_demod_sleep)(struct dvb_frontend *fe);
 	int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
 	int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);

+ 50 - 160
drivers/media/video/saa7185.c

@@ -25,43 +25,25 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
 #include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
 #include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
 #include <linux/videodev.h>
 #include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
 
 MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
 MODULE_AUTHOR("Dave Perks");
 MODULE_LICENSE("GPL");
 
 
-#define I2C_NAME(s) (s)->name
-
-
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
-	do { \
-		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
-
 /* ----------------------------------------------------------------------- */
 
 struct saa7185 {
@@ -75,32 +57,24 @@ struct saa7185 {
 	int sat;
 };
 
-#define   I2C_SAA7185        0x88
-
 /* ----------------------------------------------------------------------- */
 
-static inline int
-saa7185_read (struct i2c_client *client)
+static inline int saa7185_read(struct i2c_client *client)
 {
 	return i2c_smbus_read_byte(client);
 }
 
-static int
-saa7185_write (struct i2c_client *client,
-	       u8                 reg,
-	       u8                 value)
+static int saa7185_write(struct i2c_client *client, u8 reg, u8 value)
 {
 	struct saa7185 *encoder = i2c_get_clientdata(client);
 
-	dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value);
+	v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value);
 	encoder->reg[reg] = value;
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static int
-saa7185_write_block (struct i2c_client *client,
-		     const u8          *data,
-		     unsigned int       len)
+static int saa7185_write_block(struct i2c_client *client,
+		const u8 *data, unsigned int len)
 {
 	int ret = -1;
 	u8 reg;
@@ -121,18 +95,17 @@ saa7185_write_block (struct i2c_client *client,
 				    encoder->reg[reg++] = data[1];
 				len -= 2;
 				data += 2;
-			} while (len >= 2 && data[0] == reg &&
-				 block_len < 32);
-			if ((ret = i2c_master_send(client, block_data,
-						   block_len)) < 0)
+			} while (len >= 2 && data[0] == reg && block_len < 32);
+			ret = i2c_master_send(client, block_data, block_len);
+			if (ret < 0)
 				break;
 		}
 	} else {
 		/* do some slow I2C emulation kind of thing */
 		while (len >= 2) {
 			reg = *data++;
-			if ((ret = saa7185_write(client, reg,
-						 *data++)) < 0)
+			ret = saa7185_write(client, reg, *data++);
+			if (ret < 0)
 				break;
 			len -= 2;
 		}
@@ -240,15 +213,11 @@ static const unsigned char init_ntsc[] = {
 	0x66, 0x21,		/* FSC3 */
 };
 
-static int
-saa7185_command (struct i2c_client *client,
-		 unsigned int       cmd,
-		 void              *arg)
+static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
 	struct saa7185 *encoder = i2c_get_clientdata(client);
 
 	switch (cmd) {
-
 	case 0:
 		saa7185_write_block(client, init_common,
 				    sizeof(init_common));
@@ -264,7 +233,6 @@ saa7185_command (struct i2c_client *client,
 					    sizeof(init_pal));
 			break;
 		}
-
 		break;
 
 	case ENCODER_GET_CAPABILITIES:
@@ -276,8 +244,8 @@ saa7185_command (struct i2c_client *client,
 		    VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
 		cap->inputs = 1;
 		cap->outputs = 1;
-	}
 		break;
+	}
 
 	case ENCODER_SET_NORM:
 	{
@@ -286,7 +254,6 @@ saa7185_command (struct i2c_client *client,
 		//saa7185_write_block(client, init_common, sizeof(init_common));
 
 		switch (*iarg) {
-
 		case VIDEO_MODE_NTSC:
 			saa7185_write_block(client, init_ntsc,
 					    sizeof(init_ntsc));
@@ -300,11 +267,10 @@ saa7185_command (struct i2c_client *client,
 		case VIDEO_MODE_SECAM:
 		default:
 			return -EINVAL;
-
 		}
 		encoder->norm = *iarg;
-	}
 		break;
+	}
 
 	case ENCODER_SET_INPUT:
 	{
@@ -314,7 +280,6 @@ saa7185_command (struct i2c_client *client,
 		 *iarg = 1: input is from ZR36060 */
 
 		switch (*iarg) {
-
 		case 0:
 			/* Switch RTCE to 1 */
 			saa7185_write(client, 0x61,
@@ -332,21 +297,19 @@ saa7185_command (struct i2c_client *client,
 
 		default:
 			return -EINVAL;
-
 		}
-	}
 		break;
+	}
 
 	case ENCODER_SET_OUTPUT:
 	{
 		int *iarg = arg;
 
 		/* not much choice of outputs */
-		if (*iarg != 0) {
+		if (*iarg != 0)
 			return -EINVAL;
-		}
-	}
 		break;
+	}
 
 	case ENCODER_ENABLE_OUTPUT:
 	{
@@ -356,8 +319,8 @@ saa7185_command (struct i2c_client *client,
 		saa7185_write(client, 0x61,
 			      (encoder->reg[0x61] & 0xbf) |
 			      (encoder->enable ? 0x00 : 0x40));
-	}
 		break;
+	}
 
 	default:
 		return -EINVAL;
@@ -368,138 +331,65 @@ saa7185_command (struct i2c_client *client,
 
 /* ----------------------------------------------------------------------- */
 
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
 
-static unsigned short ignore = I2C_CLIENT_END;
+I2C_CLIENT_INSMOD;
 
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.probe			= &ignore,
-	.ignore			= &ignore,
-};
-
-static struct i2c_driver i2c_driver_saa7185;
-
-static int
-saa7185_detect_client (struct i2c_adapter *adapter,
-		       int                 address,
-		       int                 kind)
+static int saa7185_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	int i;
-	struct i2c_client *client;
 	struct saa7185 *encoder;
 
-	dprintk(1,
-		KERN_INFO
-		"saa7185.c: detecting saa7185 client on address 0x%x\n",
-		address << 1);
-
 	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
 
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!client)
-		return -ENOMEM;
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = &i2c_driver_saa7185;
-	strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client)));
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
 
 	encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
-	if (encoder == NULL) {
-		kfree(client);
+	if (encoder == NULL)
 		return -ENOMEM;
-	}
 	encoder->norm = VIDEO_MODE_NTSC;
 	encoder->enable = 1;
 	i2c_set_clientdata(client, encoder);
 
-	i = i2c_attach_client(client);
-	if (i) {
-		kfree(client);
-		kfree(encoder);
-		return i;
-	}
-
 	i = saa7185_write_block(client, init_common, sizeof(init_common));
-	if (i >= 0) {
-		i = saa7185_write_block(client, init_ntsc,
-					sizeof(init_ntsc));
-	}
-	if (i < 0) {
-		dprintk(1, KERN_ERR "%s_attach: init error %d\n",
-			I2C_NAME(client), i);
-	} else {
-		dprintk(1,
-			KERN_INFO
-			"%s_attach: chip version %d at address 0x%x\n",
-			I2C_NAME(client), saa7185_read(client) >> 5,
-			client->addr << 1);
-	}
-
+	if (i >= 0)
+		i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc));
+	if (i < 0)
+		v4l_dbg(1, debug, client, "init error %d\n", i);
+	else
+		v4l_dbg(1, debug, client, "revision 0x%x\n",
+				saa7185_read(client) >> 5);
 	return 0;
 }
 
-static int
-saa7185_attach_adapter (struct i2c_adapter *adapter)
-{
-	dprintk(1,
-		KERN_INFO
-		"saa7185.c: starting probe for adapter %s (0x%x)\n",
-		I2C_NAME(adapter), adapter->id);
-	return i2c_probe(adapter, &addr_data, &saa7185_detect_client);
-}
-
-static int
-saa7185_detach_client (struct i2c_client *client)
+static int saa7185_remove(struct i2c_client *client)
 {
 	struct saa7185 *encoder = i2c_get_clientdata(client);
-	int err;
-
-	err = i2c_detach_client(client);
-	if (err) {
-		return err;
-	}
 
 	saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40);	/* SW: output off is active */
 	//saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
 
 	kfree(encoder);
-	kfree(client);
-
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
-static struct i2c_driver i2c_driver_saa7185 = {
-	.driver = {
-		.name = "saa7185",	/* name */
-	},
-
-	.id = I2C_DRIVERID_SAA7185B,
+static const struct i2c_device_id saa7185_id[] = {
+	{ "saa7185", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, saa7185_id);
 
-	.attach_adapter = saa7185_attach_adapter,
-	.detach_client = saa7185_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "saa7185",
+	.driverid = I2C_DRIVERID_SAA7185B,
 	.command = saa7185_command,
+	.probe = saa7185_probe,
+	.remove = saa7185_remove,
+	.id_table = saa7185_id,
 };
-
-static int __init
-saa7185_init (void)
-{
-	return i2c_add_driver(&i2c_driver_saa7185);
-}
-
-static void __exit
-saa7185_exit (void)
-{
-	i2c_del_driver(&i2c_driver_saa7185);
-}
-
-module_init(saa7185_init);
-module_exit(saa7185_exit);

+ 61 - 35
drivers/media/video/sh_mobile_ceu_camera.c

@@ -40,39 +40,39 @@
 
 /* register offsets for sh7722 / sh7723 */
 
-#define CAPSR  0x00
-#define CAPCR  0x04
-#define CAMCR  0x08
-#define CMCYR  0x0c
-#define CAMOR  0x10
-#define CAPWR  0x14
-#define CAIFR  0x18
-#define CSTCR  0x20 /* not on sh7723 */
-#define CSECR  0x24 /* not on sh7723 */
-#define CRCNTR 0x28
-#define CRCMPR 0x2c
-#define CFLCR  0x30
-#define CFSZR  0x34
-#define CDWDR  0x38
-#define CDAYR  0x3c
-#define CDACR  0x40
-#define CDBYR  0x44
-#define CDBCR  0x48
-#define CBDSR  0x4c
-#define CFWCR  0x5c
-#define CLFCR  0x60
-#define CDOCR  0x64
-#define CDDCR  0x68
-#define CDDAR  0x6c
-#define CEIER  0x70
-#define CETCR  0x74
-#define CSTSR  0x7c
-#define CSRTR  0x80
-#define CDSSR  0x84
-#define CDAYR2 0x90
-#define CDACR2 0x94
-#define CDBYR2 0x98
-#define CDBCR2 0x9c
+#define CAPSR  0x00 /* Capture start register */
+#define CAPCR  0x04 /* Capture control register */
+#define CAMCR  0x08 /* Capture interface control register */
+#define CMCYR  0x0c /* Capture interface cycle  register */
+#define CAMOR  0x10 /* Capture interface offset register */
+#define CAPWR  0x14 /* Capture interface width register */
+#define CAIFR  0x18 /* Capture interface input format register */
+#define CSTCR  0x20 /* Camera strobe control register (<= sh7722) */
+#define CSECR  0x24 /* Camera strobe emission count register (<= sh7722) */
+#define CRCNTR 0x28 /* CEU register control register */
+#define CRCMPR 0x2c /* CEU register forcible control register */
+#define CFLCR  0x30 /* Capture filter control register */
+#define CFSZR  0x34 /* Capture filter size clip register */
+#define CDWDR  0x38 /* Capture destination width register */
+#define CDAYR  0x3c /* Capture data address Y register */
+#define CDACR  0x40 /* Capture data address C register */
+#define CDBYR  0x44 /* Capture data bottom-field address Y register */
+#define CDBCR  0x48 /* Capture data bottom-field address C register */
+#define CBDSR  0x4c /* Capture bundle destination size register */
+#define CFWCR  0x5c /* Firewall operation control register */
+#define CLFCR  0x60 /* Capture low-pass filter control register */
+#define CDOCR  0x64 /* Capture data output control register */
+#define CDDCR  0x68 /* Capture data complexity level register */
+#define CDDAR  0x6c /* Capture data complexity level address register */
+#define CEIER  0x70 /* Capture event interrupt enable register */
+#define CETCR  0x74 /* Capture event flag clear register */
+#define CSTSR  0x7c /* Capture status register */
+#define CSRTR  0x80 /* Capture software reset register */
+#define CDSSR  0x84 /* Capture data size register */
+#define CDAYR2 0x90 /* Capture data address Y register 2 */
+#define CDACR2 0x94 /* Capture data address C register 2 */
+#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
+#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
 
 static DEFINE_MUTEX(camera_lock);
 
@@ -165,6 +165,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 	ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10);
 
 	if (pcdev->active) {
+		pcdev->active->state = VIDEOBUF_ACTIVE;
 		ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active));
 		ceu_write(pcdev, CAPSR, 0x1); /* start capture */
 	}
@@ -236,7 +237,7 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
 	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
-	vb->state = VIDEOBUF_ACTIVE;
+	vb->state = VIDEOBUF_QUEUED;
 	spin_lock_irqsave(&pcdev->lock, flags);
 	list_add_tail(&vb->queue, &pcdev->capture);
 
@@ -323,12 +324,24 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	unsigned long flags;
 
 	BUG_ON(icd != pcdev->icd);
 
 	/* disable capture, disable interrupts */
 	ceu_write(pcdev, CEIER, 0);
 	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
+
+	/* make sure active buffer is canceled */
+	spin_lock_irqsave(&pcdev->lock, flags);
+	if (pcdev->active) {
+		list_del(&pcdev->active->queue);
+		pcdev->active->state = VIDEOBUF_ERROR;
+		wake_up_all(&pcdev->active->done);
+		pcdev->active = NULL;
+	}
+	spin_unlock_irqrestore(&pcdev->lock, flags);
+
 	icd->ops->release(icd);
 
 	dev_info(&icd->dev,
@@ -391,7 +404,20 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
 	ceu_write(pcdev, CFLCR, 0); /* data fetch mode - no scaling */
 	ceu_write(pcdev, CFSZR, (icd->height << 16) | cfszr_width);
 	ceu_write(pcdev, CLFCR, 0); /* data fetch mode - no lowpass filter */
-	ceu_write(pcdev, CDOCR, 0x00000016);
+
+	/* A few words about byte order (observed in Big Endian mode)
+	 *
+	 * In data fetch mode bytes are received in chunks of 8 bytes.
+	 * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first)
+	 *
+	 * The data is however by default written to memory in reverse order:
+	 * D7, D6, D5, D4, D3, D2, D1, D0 (D7 written to lowest byte)
+	 *
+	 * The lowest three bits of CDOCR allows us to do swapping,
+	 * using 7 we swap the data bytes to match the incoming order:
+	 * D0, D1, D2, D3, D4, D5, D6, D7
+	 */
+	ceu_write(pcdev, CDOCR, 0x00000017);
 
 	ceu_write(pcdev, CDWDR, cdwdr_width);
 	ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */

+ 11 - 9
drivers/media/video/soc_camera_platform.c

@@ -18,15 +18,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/soc_camera.h>
-
-struct soc_camera_platform_info {
-	int iface;
-	char *format_name;
-	unsigned long format_depth;
-	struct v4l2_pix_format format;
-	unsigned long bus_param;
-	int (*set_capture)(struct soc_camera_platform_info *info, int enable);
-};
+#include <media/soc_camera_platform.h>
 
 struct soc_camera_platform_priv {
 	struct soc_camera_platform_info *info;
@@ -44,11 +36,21 @@ soc_camera_platform_get_info(struct soc_camera_device *icd)
 
 static int soc_camera_platform_init(struct soc_camera_device *icd)
 {
+	struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+
+	if (p->power)
+		p->power(1);
+
 	return 0;
 }
 
 static int soc_camera_platform_release(struct soc_camera_device *icd)
 {
+	struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+
+	if (p->power)
+		p->power(0);
+
 	return 0;
 }
 

+ 8 - 19
drivers/media/video/stk-webcam.c

@@ -27,7 +27,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <linux/kref.h>
 
 #include <linux/usb.h>
 #include <linux/mm.h>
@@ -560,7 +559,7 @@ static void stk_clean_iso(struct stk_camera *dev)
 
 		urb = dev->isobufs[i].urb;
 		if (urb) {
-			if (atomic_read(&dev->urbs_used))
+			if (atomic_read(&dev->urbs_used) && is_present(dev))
 				usb_kill_urb(urb);
 			usb_free_urb(urb);
 		}
@@ -689,18 +688,14 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
 {
 	struct stk_camera *dev = fp->private_data;
 
-	if (dev->owner != fp) {
-		usb_autopm_put_interface(dev->interface);
-		return 0;
+	if (dev->owner == fp) {
+		stk_stop_stream(dev);
+		stk_free_buffers(dev);
+		dev->owner = NULL;
 	}
 
-	stk_stop_stream(dev);
-
-	stk_free_buffers(dev);
-
-	dev->owner = NULL;
-
-	usb_autopm_put_interface(dev->interface);
+	if(is_present(dev))
+		usb_autopm_put_interface(dev->interface);
 
 	return 0;
 }
@@ -714,9 +709,6 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
 	struct stk_sio_buffer *sbuf;
 	struct stk_camera *dev = fp->private_data;
 
-	if (dev == NULL)
-		return -EIO;
-
 	if (!is_present(dev))
 		return -EIO;
 	if (dev->owner && dev->owner != fp)
@@ -773,9 +765,6 @@ static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait)
 {
 	struct stk_camera *dev = fp->private_data;
 
-	if (dev == NULL)
-		return -ENODEV;
-
 	poll_wait(fp, &dev->wait_frame, wait);
 
 	if (!is_present(dev))
@@ -1436,7 +1425,7 @@ static void stk_camera_disconnect(struct usb_interface *interface)
 	wake_up_interruptible(&dev->wait_frame);
 	stk_remove_sysfs_files(&dev->vdev);
 
-	STK_INFO("Syntek USB2.0 Camera release resources"
+	STK_INFO("Syntek USB2.0 Camera release resources "
 		"video device /dev/video%d\n", dev->vdev.minor);
 
 	video_unregister_device(&dev->vdev);

+ 0 - 1
drivers/media/video/stk-webcam.h

@@ -122,7 +122,6 @@ struct stk_camera {
 
 #define vdev_to_camera(d) container_of(d, struct stk_camera, vdev)
 
-void stk_camera_delete(struct kref *);
 int stk_camera_write_reg(struct stk_camera *, u16, u8);
 int stk_camera_read_reg(struct stk_camera *, u16, int *);
 

+ 1 - 1
drivers/media/video/tveeprom.c

@@ -242,7 +242,7 @@ hauppauge_tuner[] =
 	{ TUNER_ABSENT,        		"TCL M2523_3DBH_E"},
 	{ TUNER_ABSENT,        		"TCL M2523_3DIH_E"},
 	{ TUNER_ABSENT,        		"TCL MFPE05_2_U"},
-	{ TUNER_PHILIPS_FMD1216ME_MK3,	"Philips FMD1216MEX"},
+	{ TUNER_PHILIPS_FMD1216MEX_MK3,	"Philips FMD1216MEX"},
 	{ TUNER_ABSENT,        		"Philips FRH2036B"},
 	{ TUNER_ABSENT,        		"Panasonic ENGF75_01GF"},
 	{ TUNER_ABSENT,        		"MaxLinear MXL5005"},

+ 167 - 34
drivers/media/video/videobuf-dvb.c

@@ -126,7 +126,6 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
 	mutex_lock(&dvb->lock);
 	dvb->nfeeds--;
 	if (0 == dvb->nfeeds  &&  NULL != dvb->thread) {
-		// FIXME: cx8802_cancel_buffers(dev);
 		err = kthread_stop(dvb->thread);
 		dvb->thread = NULL;
 	}
@@ -134,30 +133,38 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
 	return err;
 }
 
-/* ------------------------------------------------------------------ */
-
-int videobuf_dvb_register(struct videobuf_dvb *dvb,
+static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
 			  struct module *module,
 			  void *adapter_priv,
 			  struct device *device,
-			  short *adapter_nr)
+			  char *adapter_name,
+			  short *adapter_nr,
+			  int mfe_shared)
 {
 	int result;
 
-	mutex_init(&dvb->lock);
+	mutex_init(&fe->lock);
 
 	/* register adapter */
-	result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device,
-				      adapter_nr);
+	result = dvb_register_adapter(&fe->adapter, adapter_name, module,
+		device, adapter_nr);
 	if (result < 0) {
 		printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
-		       dvb->name, result);
-		goto fail_adapter;
+		       adapter_name, result);
 	}
-	dvb->adapter.priv = adapter_priv;
+	fe->adapter.priv = adapter_priv;
+	fe->adapter.mfe_shared = mfe_shared;
+
+	return result;
+}
+
+static int videobuf_dvb_register_frontend(struct dvb_adapter *adapter,
+	struct videobuf_dvb *dvb)
+{
+	int result;
 
 	/* register frontend */
-	result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+	result = dvb_register_frontend(adapter, dvb->frontend);
 	if (result < 0) {
 		printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
 		       dvb->name, result);
@@ -183,7 +190,8 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
 	dvb->dmxdev.filternum    = 256;
 	dvb->dmxdev.demux        = &dvb->demux.dmx;
 	dvb->dmxdev.capabilities = 0;
-	result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
+	result = dvb_dmxdev_init(&dvb->dmxdev, adapter);
+
 	if (result < 0) {
 		printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
 		       dvb->name, result);
@@ -214,7 +222,11 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
 	}
 
 	/* register network adapter */
-	dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
+	dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx);
+	if (dvb->net.dvbdev == NULL) {
+		result = -ENOMEM;
+		goto fail_fe_conn;
+	}
 	return 0;
 
 fail_fe_conn:
@@ -229,30 +241,151 @@ fail_dmx:
 	dvb_unregister_frontend(dvb->frontend);
 fail_frontend:
 	dvb_frontend_detach(dvb->frontend);
-	dvb_unregister_adapter(&dvb->adapter);
-fail_adapter:
+	dvb->frontend = NULL;
+
 	return result;
 }
 
-void videobuf_dvb_unregister(struct videobuf_dvb *dvb)
+/* ------------------------------------------------------------------ */
+/* Register a single adapter and one or more frontends */
+int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
+			  struct module *module,
+			  void *adapter_priv,
+			  struct device *device,
+			  short *adapter_nr,
+			  int mfe_shared)
 {
-	dvb_net_release(&dvb->net);
-	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
-	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
-	dvb_dmxdev_release(&dvb->dmxdev);
-	dvb_dmx_release(&dvb->demux);
-	dvb_unregister_frontend(dvb->frontend);
-	dvb_frontend_detach(dvb->frontend);
-	dvb_unregister_adapter(&dvb->adapter);
+	struct list_head *list, *q;
+	struct videobuf_dvb_frontend *fe;
+	int res;
+
+	fe = videobuf_dvb_get_frontend(f, 1);
+	if (!fe) {
+		printk(KERN_WARNING "Unable to register the adapter which has no frontends\n");
+		return -EINVAL;
+	}
+
+	/* Bring up the adapter */
+	res = videobuf_dvb_register_adapter(f, module, adapter_priv, device,
+		fe->dvb.name, adapter_nr, mfe_shared);
+	if (res < 0) {
+		printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
+		return res;
+	}
+
+	/* Attach all of the frontends to the adapter */
+	mutex_lock(&f->lock);
+	list_for_each_safe(list, q, &f->felist) {
+		fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+		res = videobuf_dvb_register_frontend(&f->adapter, &fe->dvb);
+		if (res < 0) {
+			printk(KERN_WARNING "%s: videobuf_dvb_register_frontend failed (errno = %d)\n",
+				fe->dvb.name, res);
+			goto err;
+		}
+	}
+	mutex_unlock(&f->lock);
+	return 0;
+
+err:
+	mutex_unlock(&f->lock);
+	videobuf_dvb_unregister_bus(f);
+	return res;
 }
+EXPORT_SYMBOL(videobuf_dvb_register_bus);
 
-EXPORT_SYMBOL(videobuf_dvb_register);
-EXPORT_SYMBOL(videobuf_dvb_unregister);
+void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f)
+{
+	struct list_head *list, *q;
+	struct videobuf_dvb_frontend *fe;
+
+	mutex_lock(&f->lock);
+	list_for_each_safe(list, q, &f->felist) {
+		fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+		if (fe->dvb.net.dvbdev) {
+			dvb_net_release(&fe->dvb.net);
+			fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
+				&fe->dvb.fe_mem);
+			fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
+				&fe->dvb.fe_hw);
+			dvb_dmxdev_release(&fe->dvb.dmxdev);
+			dvb_dmx_release(&fe->dvb.demux);
+			dvb_unregister_frontend(fe->dvb.frontend);
+		}
+		if (fe->dvb.frontend)
+			/* always allocated, may have been reset */
+			dvb_frontend_detach(fe->dvb.frontend);
+		list_del(list);
+		kfree(fe);
+	}
+	mutex_unlock(&f->lock);
 
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * compile-command: "make DVB=1"
- * End:
- */
+	dvb_unregister_adapter(&f->adapter);
+}
+EXPORT_SYMBOL(videobuf_dvb_unregister_bus);
+
+struct videobuf_dvb_frontend *videobuf_dvb_get_frontend(
+	struct videobuf_dvb_frontends *f, int id)
+{
+	struct list_head *list, *q;
+	struct videobuf_dvb_frontend *fe, *ret = NULL;
+
+	mutex_lock(&f->lock);
+
+	list_for_each_safe(list, q, &f->felist) {
+		fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+		if (fe->id == id) {
+			ret = fe;
+			break;
+		}
+	}
+
+	mutex_unlock(&f->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(videobuf_dvb_get_frontend);
+
+int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f,
+	struct dvb_frontend *p)
+{
+	struct list_head *list, *q;
+	struct videobuf_dvb_frontend *fe = NULL;
+	int ret = 0;
+
+	mutex_lock(&f->lock);
+
+	list_for_each_safe(list, q, &f->felist) {
+		fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+		if (fe->dvb.frontend == p) {
+			ret = fe->id;
+			break;
+		}
+	}
+
+	mutex_unlock(&f->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(videobuf_dvb_find_frontend);
+
+struct videobuf_dvb_frontend *videobuf_dvb_alloc_frontend(
+	struct videobuf_dvb_frontends *f, int id)
+{
+	struct videobuf_dvb_frontend *fe;
+
+	fe = kzalloc(sizeof(struct videobuf_dvb_frontend), GFP_KERNEL);
+	if (fe == NULL)
+		goto fail_alloc;
+
+	fe->id = id;
+	mutex_init(&fe->dvb.lock);
+
+	mutex_lock(&f->lock);
+	list_add_tail(&fe->felist, &f->felist);
+	mutex_unlock(&f->lock);
+
+fail_alloc:
+	return fe;
+}
+EXPORT_SYMBOL(videobuf_dvb_alloc_frontend);

+ 207 - 71
drivers/media/video/vivi.c

@@ -128,12 +128,56 @@ struct vivi_fmt {
 	int   depth;
 };
 
-static struct vivi_fmt format = {
-	.name     = "4:2:2, packed, YUYV",
-	.fourcc   = V4L2_PIX_FMT_YUYV,
-	.depth    = 16,
+static struct vivi_fmt formats[] = {
+	{
+		.name     = "4:2:2, packed, YUYV",
+		.fourcc   = V4L2_PIX_FMT_YUYV,
+		.depth    = 16,
+	},
+	{
+		.name     = "4:2:2, packed, UYVY",
+		.fourcc   = V4L2_PIX_FMT_UYVY,
+		.depth    = 16,
+	},
+	{
+		.name     = "RGB565 (LE)",
+		.fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
+		.depth    = 16,
+	},
+	{
+		.name     = "RGB565 (BE)",
+		.fourcc   = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
+		.depth    = 16,
+	},
+	{
+		.name     = "RGB555 (LE)",
+		.fourcc   = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
+		.depth    = 16,
+	},
+	{
+		.name     = "RGB555 (BE)",
+		.fourcc   = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
+		.depth    = 16,
+	},
 };
 
+static struct vivi_fmt *get_format(struct v4l2_format *f)
+{
+	struct vivi_fmt *fmt;
+	unsigned int k;
+
+	for (k = 0; k < ARRAY_SIZE(formats); k++) {
+		fmt = &formats[k];
+		if (fmt->fourcc == f->fmt.pix.pixelformat)
+			break;
+	}
+
+	if (k == ARRAY_SIZE(formats))
+		return NULL;
+
+	return &formats[k];
+}
+
 struct sg_to_addr {
 	int pos;
 	struct scatterlist *sg;
@@ -190,6 +234,7 @@ struct vivi_fh {
 	struct videobuf_queue      vb_vidq;
 
 	enum v4l2_buf_type         type;
+	unsigned char              bars[8][3];
 };
 
 /* ------------------------------------------------------------------
@@ -234,42 +279,118 @@ static u8 bars[8][3] = {
 #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
 #define TSTAMP_MIN_X 64
 
-static void gen_line(char *basep, int inipos, int wmax,
-		int hmax, int line, int count, char *timestr)
+static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
 {
-	int  w, i, j, y;
-	int pos = inipos;
-	char *p, *s;
-	u8   chr, r, g, b, color;
+	unsigned char r_y, g_u, b_v;
+	unsigned char *p;
+	int color;
 
-	/* We will just duplicate the second pixel at the packet */
-	wmax /= 2;
+	r_y = fh->bars[colorpos][0]; /* R or precalculated Y */
+	g_u = fh->bars[colorpos][1]; /* G or precalculated U */
+	b_v = fh->bars[colorpos][2]; /* B or precalculated V */
 
-	/* Generate a standard color bar pattern */
-	for (w = 0; w < wmax; w++) {
-		int colorpos = ((w + count) * 8/(wmax + 1)) % 8;
-		r = bars[colorpos][0];
-		g = bars[colorpos][1];
-		b = bars[colorpos][2];
-
-		for (color = 0; color < 4; color++) {
-			p = basep + pos;
+	for (color = 0; color < 4; color++) {
+		p = buf + color;
 
+		switch (fh->fmt->fourcc) {
+		case V4L2_PIX_FMT_YUYV:
 			switch (color) {
 			case 0:
 			case 2:
-				*p = TO_Y(r, g, b);	/* Luma */
+				*p = r_y;
 				break;
 			case 1:
-				*p = TO_U(r, g, b);	/* Cb */
+				*p = g_u;
 				break;
 			case 3:
-				*p = TO_V(r, g, b);	/* Cr */
+				*p = b_v;
+				break;
+			}
+			break;
+		case V4L2_PIX_FMT_UYVY:
+			switch (color) {
+			case 1:
+			case 3:
+				*p = r_y;
+				break;
+			case 0:
+				*p = g_u;
+				break;
+			case 2:
+				*p = b_v;
+				break;
+			}
+			break;
+		case V4L2_PIX_FMT_RGB565:
+			switch (color) {
+			case 0:
+			case 2:
+				*p = (g_u << 5) | b_v;
+				break;
+			case 1:
+			case 3:
+				*p = (r_y << 3) | (g_u >> 3);
+				break;
+			}
+			break;
+		case V4L2_PIX_FMT_RGB565X:
+			switch (color) {
+			case 0:
+			case 2:
+				*p = (r_y << 3) | (g_u >> 3);
+				break;
+			case 1:
+			case 3:
+				*p = (g_u << 5) | b_v;
 				break;
 			}
-			pos++;
+			break;
+		case V4L2_PIX_FMT_RGB555:
+			switch (color) {
+			case 0:
+			case 2:
+				*p = (g_u << 5) | b_v;
+				break;
+			case 1:
+			case 3:
+				*p = (r_y << 2) | (g_u >> 3);
+				break;
+			}
+			break;
+		case V4L2_PIX_FMT_RGB555X:
+			switch (color) {
+			case 0:
+			case 2:
+				*p = (r_y << 2) | (g_u >> 3);
+				break;
+			case 1:
+			case 3:
+				*p = (g_u << 5) | b_v;
+				break;
+			}
+			break;
 		}
 	}
+}
+
+static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax,
+		int hmax, int line, int count, char *timestr)
+{
+	int  w, i, j;
+	int pos = inipos;
+	char *s;
+	u8 chr;
+
+	/* We will just duplicate the second pixel at the packet */
+	wmax /= 2;
+
+	/* Generate a standard color bar pattern */
+	for (w = 0; w < wmax; w++) {
+		int colorpos = ((w + count) * 8/(wmax + 1)) % 8;
+
+		gen_twopix(fh, basep + pos, colorpos);
+		pos += 4; /* only 16 bpp supported for now */
+	}
 
 	/* Checks if it is possible to show timestamp */
 	if (TSTAMP_MAX_Y >= hmax)
@@ -283,38 +404,12 @@ static void gen_line(char *basep, int inipos, int wmax,
 		for (s = timestr; *s; s++) {
 			chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y];
 			for (i = 0; i < 7; i++) {
-				if (chr & 1 << (7 - i)) {
-					/* Font color*/
-					r = 0;
-					g = 198;
-					b = 0;
-				} else {
-					/* Background color */
-					r = bars[BLACK][0];
-					g = bars[BLACK][1];
-					b = bars[BLACK][2];
-				}
-
 				pos = inipos + j * 2;
-				for (color = 0; color < 4; color++) {
-					p = basep + pos;
-
-					y = TO_Y(r, g, b);
-
-					switch (color) {
-					case 0:
-					case 2:
-						*p = TO_Y(r, g, b); /* Luma */
-						break;
-					case 1:
-						*p = TO_U(r, g, b); /* Cb */
-						break;
-					case 3:
-						*p = TO_V(r, g, b); /* Cr */
-						break;
-					}
-					pos++;
-				}
+				/* Draw white font on black background */
+				if (chr & 1 << (7 - i))
+					gen_twopix(fh, basep + pos, WHITE);
+				else
+					gen_twopix(fh, basep + pos, BLACK);
 				j++;
 			}
 		}
@@ -324,8 +419,9 @@ end:
 	return;
 }
 
-static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
+static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf)
 {
+	struct vivi_dev *dev = fh->dev;
 	int h , pos = 0;
 	int hmax  = buf->vb.height;
 	int wmax  = buf->vb.width;
@@ -341,7 +437,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
 		return;
 
 	for (h = 0; h < hmax; h++) {
-		gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count,
+		gen_line(fh, tmpbuf, 0, wmax, hmax, h, dev->mv_count,
 			 dev->timestr);
 		memcpy(vbuf + pos, tmpbuf, wmax * 2);
 		pos += wmax*2;
@@ -410,7 +506,7 @@ static void vivi_thread_tick(struct vivi_fh *fh)
 	do_gettimeofday(&buf->vb.ts);
 
 	/* Fill buffer */
-	vivi_fillbuff(dev, buf);
+	vivi_fillbuff(fh, buf);
 	dprintk(dev, 1, "filled buffer %p\n", buf);
 
 	wake_up(&buf->vb.done);
@@ -636,11 +732,15 @@ static int vidioc_querycap(struct file *file, void  *priv,
 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 					struct v4l2_fmtdesc *f)
 {
-	if (f->index > 0)
+	struct vivi_fmt *fmt;
+
+	if (f->index >= ARRAY_SIZE(formats))
 		return -EINVAL;
 
-	strlcpy(f->description, format.name, sizeof(f->description));
-	f->pixelformat = format.fourcc;
+	fmt = &formats[f->index];
+
+	strlcpy(f->description, fmt->name, sizeof(f->description));
+	f->pixelformat = fmt->fourcc;
 	return 0;
 }
 
@@ -670,13 +770,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	enum v4l2_field field;
 	unsigned int maxw, maxh;
 
-	if (format.fourcc != f->fmt.pix.pixelformat) {
-		dprintk(dev, 1, "Fourcc format (0x%08x) invalid. "
-			"Driver accepts only 0x%08x\n",
-			f->fmt.pix.pixelformat, format.fourcc);
+	fmt = get_format(f);
+	if (!fmt) {
+		dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n",
+			f->fmt.pix.pixelformat);
 		return -EINVAL;
 	}
-	fmt = &format;
 
 	field = f->fmt.pix.field;
 
@@ -714,6 +813,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 {
 	struct vivi_fh  *fh = priv;
 	struct videobuf_queue *q = &fh->vb_vidq;
+	unsigned char r, g, b;
+	int k, is_yuv;
 
 	int ret = vidioc_try_fmt_vid_cap(file, fh, f);
 	if (ret < 0)
@@ -727,12 +828,49 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 		goto out;
 	}
 
-	fh->fmt           = &format;
+	fh->fmt           = get_format(f);
 	fh->width         = f->fmt.pix.width;
 	fh->height        = f->fmt.pix.height;
 	fh->vb_vidq.field = f->fmt.pix.field;
 	fh->type          = f->type;
 
+	/* precalculate color bar values to speed up rendering */
+	for (k = 0; k < 8; k++) {
+		r = bars[k][0];
+		g = bars[k][1];
+		b = bars[k][2];
+		is_yuv = 0;
+
+		switch (fh->fmt->fourcc) {
+		case V4L2_PIX_FMT_YUYV:
+		case V4L2_PIX_FMT_UYVY:
+			is_yuv = 1;
+			break;
+		case V4L2_PIX_FMT_RGB565:
+		case V4L2_PIX_FMT_RGB565X:
+			r >>= 3;
+			g >>= 2;
+			b >>= 3;
+			break;
+		case V4L2_PIX_FMT_RGB555:
+		case V4L2_PIX_FMT_RGB555X:
+			r >>= 3;
+			g >>= 3;
+			b >>= 3;
+			break;
+		}
+
+		if (is_yuv) {
+			fh->bars[k][0] = TO_Y(r, g, b);	/* Luma */
+			fh->bars[k][1] = TO_U(r, g, b);	/* Cb */
+			fh->bars[k][2] = TO_V(r, g, b);	/* Cr */
+		} else {
+			fh->bars[k][0] = r;
+			fh->bars[k][1] = g;
+			fh->bars[k][2] = b;
+		}
+	}
+
 	ret = 0;
 out:
 	mutex_unlock(&q->vb_lock);
@@ -886,8 +1024,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 	File operations for the device
    ------------------------------------------------------------------*/
 
-#define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8)
-
 static int vivi_open(struct inode *inode, struct file *file)
 {
 	int minor = iminor(inode);
@@ -936,7 +1072,7 @@ unlock:
 	fh->dev      = dev;
 
 	fh->type     = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	fh->fmt      = &format;
+	fh->fmt      = &formats[0];
 	fh->width    = 640;
 	fh->height   = 480;
 

+ 91 - 237
drivers/media/video/vpx3220.c

@@ -22,32 +22,21 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/types.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
 #include <asm/uaccess.h>
-
 #include <linux/i2c.h>
-
-#define I2C_NAME(x) (x)->name
-
-#include <linux/videodev.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev.h>
 #include <linux/video_decoder.h>
 
-#define I2C_VPX3220        0x86
-#define VPX3220_DEBUG	KERN_DEBUG "vpx3220: "
+MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
+MODULE_AUTHOR("Laurent Pinchart");
+MODULE_LICENSE("GPL");
 
 static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
-	do { \
-		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
-
 #define VPX_TIMEOUT_COUNT  10
 
 /* ----------------------------------------------------------------------- */
@@ -67,10 +56,8 @@ struct vpx3220 {
 static char *inputs[] = { "internal", "composite", "svideo" };
 
 /* ----------------------------------------------------------------------- */
-static inline int
-vpx3220_write (struct i2c_client *client,
-	       u8                 reg,
-	       u8                 value)
+
+static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value)
 {
 	struct vpx3220 *decoder = i2c_get_clientdata(client);
 
@@ -78,15 +65,12 @@ vpx3220_write (struct i2c_client *client,
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-static inline int
-vpx3220_read (struct i2c_client *client,
-	      u8                 reg)
+static inline int vpx3220_read(struct i2c_client *client, u8 reg)
 {
 	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int
-vpx3220_fp_status (struct i2c_client *client)
+static int vpx3220_fp_status(struct i2c_client *client)
 {
 	unsigned char status;
 	unsigned int i;
@@ -106,14 +90,11 @@ vpx3220_fp_status (struct i2c_client *client)
 	return -1;
 }
 
-static int
-vpx3220_fp_write (struct i2c_client *client,
-		  u8                 fpaddr,
-		  u16                data)
+static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data)
 {
 	/* Write the 16-bit address to the FPWR register */
 	if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
-		dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+		v4l_dbg(1, debug, client, "%s: failed\n", __func__);
 		return -1;
 	}
 
@@ -122,22 +103,20 @@ vpx3220_fp_write (struct i2c_client *client,
 
 	/* Write the 16-bit data to the FPDAT register */
 	if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
-		dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+		v4l_dbg(1, debug, client, "%s: failed\n", __func__);
 		return -1;
 	}
 
 	return 0;
 }
 
-static u16
-vpx3220_fp_read (struct i2c_client *client,
-		 u16                fpaddr)
+static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr)
 {
 	s16 data;
 
 	/* Write the 16-bit address to the FPRD register */
 	if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
-		dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+		v4l_dbg(1, debug, client, "%s: failed\n", __func__);
 		return -1;
 	}
 
@@ -147,25 +126,22 @@ vpx3220_fp_read (struct i2c_client *client,
 	/* Read the 16-bit data from the FPDAT register */
 	data = i2c_smbus_read_word_data(client, 0x28);
 	if (data == -1) {
-		dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+		v4l_dbg(1, debug, client, "%s: failed\n", __func__);
 		return -1;
 	}
 
 	return swab16(data);
 }
 
-static int
-vpx3220_write_block (struct i2c_client *client,
-		     const u8          *data,
-		     unsigned int       len)
+static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
 {
 	u8 reg;
 	int ret = -1;
 
 	while (len >= 2) {
 		reg = *data++;
-		if ((ret =
-		     vpx3220_write(client, reg, *data++)) < 0)
+		ret = vpx3220_write(client, reg, *data++);
+		if (ret < 0)
 			break;
 		len -= 2;
 	}
@@ -173,10 +149,8 @@ vpx3220_write_block (struct i2c_client *client,
 	return ret;
 }
 
-static int
-vpx3220_write_fp_block (struct i2c_client *client,
-			const u16         *data,
-			unsigned int       len)
+static int vpx3220_write_fp_block(struct i2c_client *client,
+		const u16 *data, unsigned int len)
 {
 	u8 reg;
 	int ret = 0;
@@ -285,25 +259,20 @@ static const unsigned short init_fp[] = {
 	0x4b, 0x298,		/* PLL gain */
 };
 
-static void
-vpx3220_dump_i2c (struct i2c_client *client)
+static void vpx3220_dump_i2c(struct i2c_client *client)
 {
 	int len = sizeof(init_common);
 	const unsigned char *data = init_common;
 
 	while (len > 1) {
-		dprintk(1,
-			KERN_DEBUG "vpx3216b i2c reg 0x%02x data 0x%02x\n",
+		v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n",
 			*data, vpx3220_read(client, *data));
 		data += 2;
 		len -= 2;
 	}
 }
 
-static int
-vpx3220_command (struct i2c_client *client,
-		 unsigned int       cmd,
-		 void              *arg)
+static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
 {
 	struct vpx3220 *decoder = i2c_get_clientdata(client);
 
@@ -315,7 +284,6 @@ vpx3220_command (struct i2c_client *client,
 		vpx3220_write_fp_block(client, init_fp,
 				       sizeof(init_fp) >> 1);
 		switch (decoder->norm) {
-
 		case VIDEO_MODE_NTSC:
 			vpx3220_write_fp_block(client, init_ntsc,
 					       sizeof(init_ntsc) >> 1);
@@ -334,21 +302,20 @@ vpx3220_command (struct i2c_client *client,
 					       sizeof(init_pal) >> 1);
 			break;
 		}
-	}
 		break;
+	}
 
 	case DECODER_DUMP:
 	{
 		vpx3220_dump_i2c(client);
-	}
 		break;
+	}
 
 	case DECODER_GET_CAPABILITIES:
 	{
 		struct video_decoder_capability *cap = arg;
 
-		dprintk(1, KERN_DEBUG "%s: DECODER_GET_CAPABILITIES\n",
-			I2C_NAME(client));
+		v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n");
 
 		cap->flags = VIDEO_DECODER_PAL |
 			     VIDEO_DECODER_NTSC |
@@ -357,20 +324,18 @@ vpx3220_command (struct i2c_client *client,
 			     VIDEO_DECODER_CCIR;
 		cap->inputs = 3;
 		cap->outputs = 1;
-	}
 		break;
+	}
 
 	case DECODER_GET_STATUS:
 	{
 		int res = 0, status;
 
-		dprintk(1, KERN_INFO "%s: DECODER_GET_STATUS\n",
-			I2C_NAME(client));
+		v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n");
 
 		status = vpx3220_fp_read(client, 0x0f3);
 
-		dprintk(1, KERN_INFO "%s: status: 0x%04x\n", I2C_NAME(client),
-			status);
+		v4l_dbg(1, debug, client, "status: 0x%04x\n", status);
 
 		if (status < 0)
 			return status;
@@ -379,7 +344,6 @@ vpx3220_command (struct i2c_client *client,
 			res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;
 
 			switch (status & 0x18) {
-
 			case 0x00:
 			case 0x10:
 			case 0x14:
@@ -400,8 +364,8 @@ vpx3220_command (struct i2c_client *client,
 		}
 
 		*(int *) arg = res;
-	}
 		break;
+	}
 
 	case DECODER_SET_NORM:
 	{
@@ -413,50 +377,43 @@ vpx3220_command (struct i2c_client *client,
 		   choosen video norm */
 		temp_input = vpx3220_fp_read(client, 0xf2);
 
-		dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n",
-			I2C_NAME(client), *iarg);
+		v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg);
 		switch (*iarg) {
-
 		case VIDEO_MODE_NTSC:
 			vpx3220_write_fp_block(client, init_ntsc,
 					       sizeof(init_ntsc) >> 1);
-			dprintk(1, KERN_INFO "%s: norm switched to NTSC\n",
-				I2C_NAME(client));
+			v4l_dbg(1, debug, client, "norm switched to NTSC\n");
 			break;
 
 		case VIDEO_MODE_PAL:
 			vpx3220_write_fp_block(client, init_pal,
 					       sizeof(init_pal) >> 1);
-			dprintk(1, KERN_INFO "%s: norm switched to PAL\n",
-				I2C_NAME(client));
+			v4l_dbg(1, debug, client, "norm switched to PAL\n");
 			break;
 
 		case VIDEO_MODE_SECAM:
 			vpx3220_write_fp_block(client, init_secam,
 					       sizeof(init_secam) >> 1);
-			dprintk(1, KERN_INFO "%s: norm switched to SECAM\n",
-				I2C_NAME(client));
+			v4l_dbg(1, debug, client, "norm switched to SECAM\n");
 			break;
 
 		case VIDEO_MODE_AUTO:
 			/* FIXME This is only preliminary support */
 			data = vpx3220_fp_read(client, 0xf2) & 0x20;
 			vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
-			dprintk(1, KERN_INFO "%s: norm switched to Auto\n",
-				I2C_NAME(client));
+			v4l_dbg(1, debug, client, "norm switched to AUTO\n");
 			break;
 
 		default:
 			return -EINVAL;
-
 		}
 		decoder->norm = *iarg;
 
 		/* And here we set the backed up video input again */
 		vpx3220_fp_write(client, 0xf2, temp_input | 0x0010);
 		udelay(10);
-	}
 		break;
+	}
 
 	case DECODER_SET_INPUT:
 	{
@@ -475,8 +432,7 @@ vpx3220_command (struct i2c_client *client,
 		if (*iarg < 0 || *iarg > 2)
 			return -EINVAL;
 
-		dprintk(1, KERN_INFO "%s: input switched to %s\n",
-			I2C_NAME(client), inputs[*iarg]);
+		v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]);
 
 		vpx3220_write(client, 0x33, input[*iarg][0]);
 
@@ -488,8 +444,8 @@ vpx3220_command (struct i2c_client *client,
 				 data | (input[*iarg][1] << 5) | 0x0010);
 
 		udelay(10);
-	}
 		break;
+	}
 
 	case DECODER_SET_OUTPUT:
 	{
@@ -499,19 +455,18 @@ vpx3220_command (struct i2c_client *client,
 		if (*iarg != 0) {
 			return -EINVAL;
 		}
-	}
 		break;
+	}
 
 	case DECODER_ENABLE_OUTPUT:
 	{
 		int *iarg = arg;
 
-		dprintk(1, KERN_DEBUG "%s: DECODER_ENABLE_OUTPUT %d\n",
-			I2C_NAME(client), *iarg);
+		v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg);
 
 		vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
-	}
 		break;
+	}
 
 	case DECODER_SET_PICTURE:
 	{
@@ -542,8 +497,8 @@ vpx3220_command (struct i2c_client *client,
 			vpx3220_fp_write(client, 0x1c,
 					 ((decoder->hue - 32768) >> 6) & 0xFFF);
 		}
-	}
 		break;
+	}
 
 	default:
 		return -EINVAL;
@@ -552,8 +507,7 @@ vpx3220_command (struct i2c_client *client,
 	return 0;
 }
 
-static int
-vpx3220_init_client (struct i2c_client *client)
+static int vpx3220_init_client(struct i2c_client *client)
 {
 	vpx3220_write_block(client, init_common, sizeof(init_common));
 	vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1);
@@ -567,115 +521,26 @@ vpx3220_init_client (struct i2c_client *client)
  * Client management code
  */
 
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] =
-    { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4,
-	I2C_CLIENT_END
-};
-
-static unsigned short ignore = I2C_CLIENT_END;
+static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 1, I2C_CLIENT_END };
 
-static struct i2c_client_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.probe			= &ignore,
-	.ignore			= &ignore,
-};
-
-static struct i2c_driver vpx3220_i2c_driver;
-
-static int
-vpx3220_detach_client (struct i2c_client *client)
-{
-	struct vpx3220 *decoder = i2c_get_clientdata(client);
-	int err;
-
-	err = i2c_detach_client(client);
-	if (err) {
-		return err;
-	}
-
-	kfree(decoder);
-	kfree(client);
-
-	return 0;
-}
+I2C_CLIENT_INSMOD;
 
-static int
-vpx3220_detect_client (struct i2c_adapter *adapter,
-		       int                 address,
-		       int                 kind)
+static int vpx3220_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
-	int err;
-	struct i2c_client *client;
 	struct vpx3220 *decoder;
-
-	dprintk(1, VPX3220_DEBUG "%s\n", __func__);
+	const char *name = NULL;
+	u8 ver;
+	u16 pn;
 
 	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality
-	    (adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
-		return 0;
-
-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == NULL) {
-		return -ENOMEM;
-	}
-
-	client->addr = address;
-	client->adapter = adapter;
-	client->driver = &vpx3220_i2c_driver;
-
-	/* Check for manufacture ID and part number */
-	if (kind < 0) {
-		u8 id;
-		u16 pn;
-
-		id = vpx3220_read(client, 0x00);
-		if (id != 0xec) {
-			dprintk(1,
-				KERN_INFO
-				"vpx3220_attach: Wrong manufacturer ID (0x%02x)\n",
-				id);
-			kfree(client);
-			return 0;
-		}
-
-		pn = (vpx3220_read(client, 0x02) << 8) +
-		    vpx3220_read(client, 0x01);
-		switch (pn) {
-		case 0x4680:
-			strlcpy(I2C_NAME(client), "vpx3220a",
-				sizeof(I2C_NAME(client)));
-			break;
-		case 0x4260:
-			strlcpy(I2C_NAME(client), "vpx3216b",
-				sizeof(I2C_NAME(client)));
-			break;
-		case 0x4280:
-			strlcpy(I2C_NAME(client), "vpx3214c",
-				sizeof(I2C_NAME(client)));
-			break;
-		default:
-			dprintk(1,
-				KERN_INFO
-				"%s: Wrong part number (0x%04x)\n",
-				__func__, pn);
-			kfree(client);
-			return 0;
-		}
-	} else {
-		strlcpy(I2C_NAME(client), "forced vpx32xx",
-			sizeof(I2C_NAME(client)));
-	}
+	if (!i2c_check_functionality(client->adapter,
+		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
+		return -ENODEV;
 
 	decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
-	if (decoder == NULL) {
-		kfree(client);
+	if (decoder == NULL)
 		return -ENOMEM;
-	}
 	decoder->norm = VIDEO_MODE_PAL;
 	decoder->input = 0;
 	decoder->enable = 1;
@@ -685,63 +550,52 @@ vpx3220_detect_client (struct i2c_adapter *adapter,
 	decoder->sat = 32768;
 	i2c_set_clientdata(client, decoder);
 
-	err = i2c_attach_client(client);
-	if (err) {
-		kfree(client);
-		kfree(decoder);
-		return err;
+	ver = i2c_smbus_read_byte_data(client, 0x00);
+	pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
+		i2c_smbus_read_byte_data(client, 0x01);
+	if (ver == 0xec) {
+		switch (pn) {
+		case 0x4680:
+			name = "vpx3220a";
+			break;
+		case 0x4260:
+			name = "vpx3216b";
+			break;
+		case 0x4280:
+			name = "vpx3214c";
+			break;
+		}
 	}
-
-	dprintk(1, KERN_INFO "%s: vpx32xx client found at address 0x%02x\n",
-		I2C_NAME(client), client->addr << 1);
+	if (name)
+		v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+			client->addr << 1, client->adapter->name);
+	else
+		v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n",
+			ver, pn, client->addr << 1, client->adapter->name);
 
 	vpx3220_init_client(client);
-
 	return 0;
 }
 
-static int
-vpx3220_attach_adapter (struct i2c_adapter *adapter)
+static int vpx3220_remove(struct i2c_client *client)
 {
-	int ret;
-
-	ret = i2c_probe(adapter, &addr_data, &vpx3220_detect_client);
-	dprintk(1, VPX3220_DEBUG "%s: i2c_probe returned %d\n",
-		__func__, ret);
-	return ret;
+	kfree(i2c_get_clientdata(client));
+	return 0;
 }
 
-/* -----------------------------------------------------------------------
- * Driver initialization and cleanup code
- */
-
-static struct i2c_driver vpx3220_i2c_driver = {
-	.driver = {
-		.name = "vpx3220",
-	},
-
-	.id = I2C_DRIVERID_VPX3220,
+static const struct i2c_device_id vpx3220_id[] = {
+	{ "vpx3220a", 0 },
+	{ "vpx3216b", 0 },
+	{ "vpx3214c", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, vpx3220_id);
 
-	.attach_adapter = vpx3220_attach_adapter,
-	.detach_client = vpx3220_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+	.name = "vpx3220",
+	.driverid = I2C_DRIVERID_VPX3220,
 	.command = vpx3220_command,
+	.probe = vpx3220_probe,
+	.remove = vpx3220_remove,
+	.id_table = vpx3220_id,
 };
-
-static int __init
-vpx3220_init (void)
-{
-	return i2c_add_driver(&vpx3220_i2c_driver);
-}
-
-static void __exit
-vpx3220_cleanup (void)
-{
-	i2c_del_driver(&vpx3220_i2c_driver);
-}
-
-module_init(vpx3220_init);
-module_exit(vpx3220_cleanup);
-
-MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
-MODULE_AUTHOR("Laurent Pinchart");
-MODULE_LICENSE("GPL");

+ 1 - 0
drivers/media/video/zoran/zoran_card.c

@@ -817,6 +817,7 @@ zoran_register_i2c (struct zoran *zr)
 	memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
 	       sizeof(struct i2c_algo_bit_data));
 	zr->i2c_algo.data = zr;
+	zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG;
 	zr->i2c_adapter.id = I2C_HW_B_ZR36067;
 	zr->i2c_adapter.client_register = zoran_i2c_client_register;
 	zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister;

+ 0 - 1
drivers/media/video/zoran/zoran_driver.c

@@ -2996,7 +2996,6 @@ zoran_do_ioctl (struct inode *inode,
 			break;
 
 		default:
-			dprintk(3, "unsupported\n");
 			dprintk(1,
 				KERN_ERR
 				"%s: VIDIOC_S_FMT - unsupported type %d\n",

+ 2 - 0
include/linux/dvb/frontend.h

@@ -166,6 +166,7 @@ typedef enum fe_modulation {
 	VSB_16,
 	PSK_8,
 	APSK_16,
+	APSK_32,
 	DQPSK,
 } fe_modulation_t;
 
@@ -295,6 +296,7 @@ typedef enum fe_delivery_system {
 	SYS_DVBC_ANNEX_AC,
 	SYS_DVBC_ANNEX_B,
 	SYS_DVBT,
+	SYS_DSS,
 	SYS_DVBS,
 	SYS_DVBS2,
 	SYS_DVBH,

+ 1 - 1
include/linux/i2c-id.h

@@ -60,7 +60,7 @@
 #define I2C_DRIVERID_WM8775	69	/* wm8775 audio processor	*/
 #define I2C_DRIVERID_CS53L32A	70	/* cs53l32a audio processor	*/
 #define I2C_DRIVERID_CX25840	71	/* cx2584x video encoder	*/
-#define I2C_DRIVERID_SAA7127	72	/* saa7124 video encoder	*/
+#define I2C_DRIVERID_SAA7127	72	/* saa7127 video encoder	*/
 #define I2C_DRIVERID_SAA711X	73	/* saa711x video encoders	*/
 #define I2C_DRIVERID_AKITAIOEXP	74	/* IO Expander on Sharp SL-C1000 */
 #define I2C_DRIVERID_INFRARED	75	/* I2C InfraRed on Video boards */

+ 11 - 0
include/media/soc_camera_platform.h

@@ -1,3 +1,13 @@
+/*
+ * Generic Platform Camera Driver Header
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #ifndef __SOC_CAMERA_H__
 #define __SOC_CAMERA_H__
 
@@ -9,6 +19,7 @@ struct soc_camera_platform_info {
 	unsigned long format_depth;
 	struct v4l2_pix_format format;
 	unsigned long bus_param;
+	void (*power)(int);
 	int (*set_capture)(struct soc_camera_platform_info *info, int enable);
 };
 

+ 1 - 0
include/media/tuner.h

@@ -123,6 +123,7 @@
 #define TUNER_TEA5761			75	/* Only FM Radio Tuner */
 #define TUNER_XC5000			76	/* Xceive Silicon Tuner */
 #define TUNER_TCL_MF02GIP_5N		77	/* TCL MF02GIP_5N */
+#define TUNER_PHILIPS_FMD1216MEX_MK3	78
 
 /* tv card specific */
 #define TDA9887_PRESENT 		(1<<0)

+ 11 - 0
include/media/v4l2-i2c-drv-legacy.h

@@ -21,6 +21,17 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+/* NOTE: the full version of this header is in the v4l-dvb repository
+ * and allows v4l i2c drivers to be compiled on older kernels as well.
+ * The version of this header as it appears in the kernel is a stripped
+ * version (without all the backwards compatibility stuff) and so it
+ * looks a bit odd.
+ *
+ * If you look at the full version then you will understand the reason
+ * for introducing this header since you really don't want to have all
+ * the tricky backwards compatibility code in each and every i2c driver.
+ */
+
 struct v4l2_i2c_driver_data {
 	const char * const name;
 	int driverid;

+ 11 - 0
include/media/v4l2-i2c-drv.h

@@ -21,6 +21,17 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+/* NOTE: the full version of this header is in the v4l-dvb repository
+ * and allows v4l i2c drivers to be compiled on older kernels as well.
+ * The version of this header as it appears in the kernel is a stripped
+ * version (without all the backwards compatibility stuff) and so it
+ * looks a bit odd.
+ *
+ * If you look at the full version then you will understand the reason
+ * for introducing this header since you really don't want to have all
+ * the tricky backwards compatibility code in each and every i2c driver.
+ */
+
 #ifndef __V4L2_I2C_DRV_H__
 #define __V4L2_I2C_DRV_H__
 

+ 25 - 4
include/media/videobuf-dvb.h

@@ -16,7 +16,6 @@ struct videobuf_dvb {
 	int                        nfeeds;
 
 	/* videobuf_dvb_(un)register manges this */
-	struct dvb_adapter         adapter;
 	struct dvb_demux           demux;
 	struct dmxdev              dmxdev;
 	struct dmx_frontend        fe_hw;
@@ -24,12 +23,34 @@ struct videobuf_dvb {
 	struct dvb_net             net;
 };
 
-int videobuf_dvb_register(struct videobuf_dvb *dvb,
+struct videobuf_dvb_frontend {
+	struct list_head felist;
+	int id;
+	struct videobuf_dvb dvb;
+};
+
+struct videobuf_dvb_frontends {
+	struct list_head felist;
+	struct mutex lock;
+	struct dvb_adapter adapter;
+	int active_fe_id; /* Indicates which frontend in the felist is in use */
+	int gate; /* Frontend with gate control 0=!MFE,1=fe0,2=fe1 etc */
+};
+
+int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
 			  struct module *module,
 			  void *adapter_priv,
 			  struct device *device,
-			  short *adapter_nr);
-void videobuf_dvb_unregister(struct videobuf_dvb *dvb);
+			  short *adapter_nr,
+			  int mfe_shared);
+
+void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
+
+struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(struct videobuf_dvb_frontends *f, int id);
+
+struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id);
+int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p);
+
 
 /*
  * Local variables:

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.