diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-17 22:08:47 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-17 22:08:47 (GMT) |
commit | 5564da7e9d12ea80745f66c8d2ec7bd00f3f94eb (patch) | |
tree | 30e5327e7fac3dad5e8f74e777d1f621f0693791 | |
parent | 58617d5e59663d2edea03bd03cb74279827611bb (diff) | |
parent | d4305c68cc30b66a71ea05297e6c0663feccad65 (diff) | |
download | linux-fsl-qoriq-5564da7e9d12ea80745f66c8d2ec7bd00f3f94eb.tar.xz |
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.
...
92 files changed, 4080 insertions, 4182 deletions
diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828 index aa05e5b..d5cb4ea 100644 --- a/Documentation/video4linux/CARDLIST.au0828 +++ b/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] diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index 30bbdda..691d2f3 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/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 diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c index 227642b..a887824 100644 --- a/drivers/media/common/tuners/mxl5005s.c +++ b/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); diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index 2a1aac1..fb3f3b3 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/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; diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c index 04961a1..7c0bc06 100644 --- a/drivers/media/common/tuners/tuner-types.c +++ b/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); diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index f9c2bb9..e12d13e 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/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", diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h index cf1a558..f4c1466 100644 --- a/drivers/media/common/tuners/xc5000.h +++ b/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 diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index f732144..14e627e 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/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, diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index f170e82..5689d1f 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/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, diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 3055301..db4a63b 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/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, diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 665776d..a113744 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/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); diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 89d12dc..574e336 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/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 */ }; diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index ca53df6..6286fbb 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/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, diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 9430e03..5d1abe3 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/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); diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h index b1e465c..f154e1f 100644 --- a/drivers/media/dvb/frontends/cx22702.h +++ b/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 diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index deb36f4..b144b30 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c @@ -41,10 +41,14 @@ #include "dvb_frontend.h" #include "cx24116.h" -static int debug = 0; +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); + #define dprintk(args...) \ do { \ - if (debug) printk ("cx24116: " args); \ + if (debug) \ + printk(KERN_INFO "cx24116: " args); \ } while (0) #define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw" @@ -68,13 +72,20 @@ static int debug = 0; #define CX24116_REG_UCB8 (0xca) #define CX24116_REG_CLKDIV (0xf3) #define CX24116_REG_RATEDIV (0xf9) -#define CX24116_REG_FECSTATUS (0x9c) /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */ + +/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */ +#define CX24116_REG_FECSTATUS (0x9c) /* FECSTATUS bits */ -#define CX24116_FEC_FECMASK (0x1f) /* mask to determine configured fec (not tuned) or actual fec (tuned) */ -#define CX24116_FEC_DVBS (0x20) /* Select DVB-S demodulator, else DVB-S2 */ +/* mask to determine configured fec (not tuned) or actual fec (tuned) */ +#define CX24116_FEC_FECMASK (0x1f) + +/* Select DVB-S demodulator, else DVB-S2 */ +#define CX24116_FEC_DVBS (0x20) #define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */ -#define CX24116_FEC_PILOT (0x80) /* Pilot mode requested when tuning else always reset when tuned */ + +/* Pilot mode requested when tuning else always reset when tuned */ +#define CX24116_FEC_PILOT (0x80) /* arg buffer size */ #define CX24116_ARGLEN (0x1e) @@ -116,12 +127,17 @@ static int debug = 0; /* DiSEqC tone burst */ static int toneburst = 1; +module_param(toneburst, int, 0644); +MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\ + "2=MESSAGE CACHE (default:1)"); /* SNR measurements */ -static int esno_snr = 0; +static int esno_snr; +module_param(esno_snr, int, 0644); +MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\ + "1=ESNO(db * 10) (default:0)"); -enum cmds -{ +enum cmds { CMD_SET_VCO = 0x10, CMD_TUNEREQUEST = 0x11, CMD_MPEGCONFIG = 0x13, @@ -138,8 +154,7 @@ enum cmds }; /* The Demod/Tuner can't easily provide these, we cache them */ -struct cx24116_tuning -{ +struct cx24116_tuning { u32 frequency; u32 symbol_rate; fe_spectral_inversion_t inversion; @@ -158,16 +173,14 @@ struct cx24116_tuning }; /* Basic commands that are sent to the firmware */ -struct cx24116_cmd -{ +struct cx24116_cmd { u8 len; u8 args[CX24116_ARGLEN]; }; -struct cx24116_state -{ - struct i2c_adapter* i2c; - const struct cx24116_config* config; +struct cx24116_state { + struct i2c_adapter *i2c; + const struct cx24116_config *config; struct dvb_frontend frontend; @@ -179,19 +192,20 @@ struct cx24116_state struct cx24116_cmd dsec_cmd; }; -static int cx24116_writereg(struct cx24116_state* state, int reg, int data) +static int cx24116_writereg(struct cx24116_state *state, int reg, int data) { u8 buf[] = { reg, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; int err; - if (debug>1) + if (debug > 1) printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n", - __func__,reg, data); + __func__, reg, data); - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk("%s: writereg error(err == %i, reg == 0x%02x," + err = i2c_transfer(state->i2c, &msg, 1); + if (err != 1) { + printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," " value == 0x%02x)\n", __func__, err, reg, data); return -EREMOTEIO; } @@ -200,7 +214,8 @@ static int cx24116_writereg(struct cx24116_state* state, int reg, int data) } /* Bulk byte writes to a single I2C address, for 32k firmware load */ -static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16 len) +static int cx24116_writeregN(struct cx24116_state *state, int reg, + const u8 *data, u16 len) { int ret = -EREMOTEIO; struct i2c_msg msg; @@ -221,12 +236,13 @@ static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16 msg.buf = buf; msg.len = len + 1; - if (debug>1) - printk("cx24116: %s: write regN 0x%02x, len = %d\n", - __func__,reg, len); + if (debug > 1) + printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n", + __func__, reg, len); - if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk("%s: writereg error(err == %i, reg == 0x%02x\n", + ret = i2c_transfer(state->i2c, &msg, 1); + if (ret != 1) { + printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n", __func__, ret, reg); ret = -EREMOTEIO; } @@ -237,30 +253,35 @@ error: return ret; } -static int cx24116_readreg(struct cx24116_state* state, u8 reg) +static int cx24116_readreg(struct cx24116_state *state, u8 reg) { int ret; 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 } + { .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: reg=0x%x (error=%d)\n", __func__, reg, ret); + printk(KERN_ERR "%s: reg=0x%x (error=%d)\n", + __func__, reg, ret); return ret; } - if (debug>1) - printk("cx24116: read reg 0x%02x, value 0x%02x\n",reg, b1[0]); + if (debug > 1) + printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n", + reg, b1[0]); return b1[0]; } -static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_inversion_t inversion) +static int cx24116_set_inversion(struct cx24116_state *state, + fe_spectral_inversion_t inversion) { dprintk("%s(%d)\n", __func__, inversion); @@ -308,10 +329,10 @@ static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_invers * Eg.(2/3) szap "Zone Horror" * * mask/val = 0x04, 0x20 - * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 00000000 | FE_HAS_LOCK + * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK * * mask/val = 0x04, 0x30 - * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 00000000 | FE_HAS_LOCK + * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK * * After tuning FECSTATUS contains actual FEC * in use numbered 1 through to 8 for 1/2 .. 2/3 etc @@ -389,18 +410,16 @@ struct cx24116_modfec { */ }; -static int cx24116_lookup_fecmod(struct cx24116_state* state, +static int cx24116_lookup_fecmod(struct cx24116_state *state, fe_modulation_t m, fe_code_rate_t f) { int i, ret = -EOPNOTSUPP; dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f); - for(i=0 ; i < sizeof(CX24116_MODFEC_MODES) / sizeof(struct cx24116_modfec) ; i++) - { - if( (m == CX24116_MODFEC_MODES[i].modulation) && - (f == CX24116_MODFEC_MODES[i].fec) ) - { + for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) { + if ((m == CX24116_MODFEC_MODES[i].modulation) && + (f == CX24116_MODFEC_MODES[i].fec)) { ret = i; break; } @@ -409,7 +428,8 @@ static int cx24116_lookup_fecmod(struct cx24116_state* state, return ret; } -static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_code_rate_t fec) +static int cx24116_set_fec(struct cx24116_state *state, + fe_modulation_t mod, fe_code_rate_t fec) { int ret = 0; @@ -417,7 +437,7 @@ static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_ ret = cx24116_lookup_fecmod(state, mod, fec); - if(ret < 0) + if (ret < 0) return ret; state->dnxt.fec = fec; @@ -429,7 +449,7 @@ static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_ return 0; } -static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate) +static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate) { dprintk("%s(%d)\n", __func__, rate); @@ -446,42 +466,49 @@ static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate) return 0; } -static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw); +static int cx24116_load_firmware(struct dvb_frontend *fe, + const struct firmware *fw); -static int cx24116_firmware_ondemand(struct dvb_frontend* fe) +static int cx24116_firmware_ondemand(struct dvb_frontend *fe) { struct cx24116_state *state = fe->demodulator_priv; const struct firmware *fw; int ret = 0; - dprintk("%s()\n",__func__); + dprintk("%s()\n", __func__); - if (cx24116_readreg(state, 0x20) > 0) - { + if (cx24116_readreg(state, 0x20) > 0) { if (state->skip_fw_load) return 0; /* Load firmware */ - /* request the firmware, this will block until someone uploads it */ - printk("%s: Waiting for firmware upload (%s)...\n", __func__, CX24116_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, &state->i2c->dev); - printk("%s: Waiting for firmware upload(2)...\n", __func__); + /* request the firmware, this will block until loaded */ + printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", + __func__, CX24116_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, + &state->i2c->dev); + printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", + __func__); if (ret) { - printk("%s: No firmware uploaded (timeout or file not found?)\n", __func__); + printk(KERN_ERR "%s: No firmware uploaded " + "(timeout or file not found?)\n", __func__); return ret; } - /* Make sure we don't recurse back through here during loading */ + /* Make sure we don't recurse back through here + * during loading */ state->skip_fw_load = 1; ret = cx24116_load_firmware(fe, fw); if (ret) - printk("%s: Writing firmware to device failed\n", __func__); + printk(KERN_ERR "%s: Writing firmware to device failed\n", + __func__); release_firmware(fw); - printk("%s: Firmware upload %s\n", __func__, ret == 0 ? "complete" : "failed"); + printk(KERN_INFO "%s: Firmware upload %s\n", __func__, + ret == 0 ? "complete" : "failed"); /* Ensure firmware is always loaded if required */ state->skip_fw_load = 0; @@ -490,8 +517,10 @@ static int cx24116_firmware_ondemand(struct dvb_frontend* fe) return ret; } -/* Take a basic firmware command structure, format it and forward it for processing */ -static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd) +/* Take a basic firmware command structure, format it + * and forward it for processing + */ +static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd) { struct cx24116_state *state = fe->demodulator_priv; int i, ret; @@ -499,49 +528,49 @@ static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd) dprintk("%s()\n", __func__); /* Load the firmware if required */ - if ( (ret = cx24116_firmware_ondemand(fe)) != 0) - { - printk("%s(): Unable initialise the firmware\n", __func__); + ret = cx24116_firmware_ondemand(fe); + if (ret != 0) { + printk(KERN_ERR "%s(): Unable initialise the firmware\n", + __func__); return ret; } /* Write the command */ - for(i = 0; i < cmd->len ; i++) - { + for (i = 0; i < cmd->len ; i++) { dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]); cx24116_writereg(state, i, cmd->args[i]); } /* Start execution and wait for cmd to terminate */ cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01); - while( cx24116_readreg(state, CX24116_REG_EXECUTE) ) - { + while (cx24116_readreg(state, CX24116_REG_EXECUTE)) { msleep(10); - if(i++ > 64) - { - /* Avoid looping forever if the firmware does no respond */ - printk("%s() Firmware not responding\n", __func__); + if (i++ > 64) { + /* Avoid looping forever if the firmware does + not respond */ + printk(KERN_WARNING "%s() Firmware not responding\n", + __func__); return -EREMOTEIO; } } return 0; } -static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) +static int cx24116_load_firmware(struct dvb_frontend *fe, + const struct firmware *fw) { - struct cx24116_state* state = fe->demodulator_priv; + struct cx24116_state *state = fe->demodulator_priv; struct cx24116_cmd cmd; int i, ret; unsigned char vers[4]; dprintk("%s\n", __func__); - dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n" - ,fw->size - ,fw->data[0] - ,fw->data[1] - ,fw->data[ fw->size-2 ] - ,fw->data[ fw->size-1 ] - ); + dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n", + fw->size, + fw->data[0], + fw->data[1], + fw->data[fw->size-2], + fw->data[fw->size-1]); /* Toggle 88x SRST pin to reset demod */ if (state->config->reset_device) @@ -587,7 +616,7 @@ static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware cmd.args[0x07] = 0x9d; cmd.args[0x08] = 0xfc; cmd.args[0x09] = 0x06; - cmd.len= 0x0a; + cmd.len = 0x0a; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -598,7 +627,7 @@ static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware cmd.args[0x00] = CMD_TUNERINIT; cmd.args[0x01] = 0x00; cmd.args[0x02] = 0x00; - cmd.len= 0x03; + cmd.len = 0x03; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -615,36 +644,38 @@ static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware else cmd.args[0x04] = 0x02; cmd.args[0x05] = 0x00; - cmd.len= 0x06; + cmd.len = 0x06; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; /* Firmware CMD 35: Get firmware version */ cmd.args[0x00] = CMD_UPDFWVERS; - cmd.len= 0x02; - for(i=0; i<4; i++) { + cmd.len = 0x02; + for (i = 0; i < 4; i++) { cmd.args[0x01] = i; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; - vers[i]= cx24116_readreg(state, CX24116_REG_MAILBOX); + vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX); } - printk("%s: FW version %i.%i.%i.%i\n", __func__, + printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__, vers[0], vers[1], vers[2], vers[3]); return 0; } -static int cx24116_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) +static int cx24116_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) { /* The isl6421 module will override this function in the fops. */ - dprintk("%s() This should never appear if the isl6421 module is loaded correctly\n",__func__); + dprintk("%s() This should never appear if the isl6421 module " + "is loaded correctly\n", __func__); return -EOPNOTSUPP; } -static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status) +static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct cx24116_state *state = fe->demodulator_priv; @@ -666,22 +697,23 @@ static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status) return 0; } -static int cx24116_read_ber(struct dvb_frontend* fe, u32* ber) +static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber) { struct cx24116_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); - *ber = ( cx24116_readreg(state, CX24116_REG_BER24) << 24 ) | - ( cx24116_readreg(state, CX24116_REG_BER16) << 16 ) | - ( cx24116_readreg(state, CX24116_REG_BER8 ) << 8 ) | - cx24116_readreg(state, CX24116_REG_BER0 ); + *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) | + (cx24116_readreg(state, CX24116_REG_BER16) << 16) | + (cx24116_readreg(state, CX24116_REG_BER8) << 8) | + cx24116_readreg(state, CX24116_REG_BER0); return 0; } /* TODO Determine function and scale appropriately */ -static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) +static int cx24116_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) { struct cx24116_state *state = fe->demodulator_priv; struct cx24116_cmd cmd; @@ -692,39 +724,43 @@ static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_str /* Firmware CMD 19: Get AGC */ cmd.args[0x00] = CMD_GETAGC; - cmd.len= 0x01; + cmd.len = 0x01; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; - sig_reading = ( cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK ) | - ( cx24116_readreg(state, CX24116_REG_SIGNAL) << 6 ); - *signal_strength= 0 - sig_reading; + sig_reading = + (cx24116_readreg(state, + CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) | + (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6); + *signal_strength = 0 - sig_reading; - dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__, sig_reading, *signal_strength); + dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", + __func__, sig_reading, *signal_strength); return 0; } /* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */ -static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr) +static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr) { struct cx24116_state *state = fe->demodulator_priv; u8 snr_reading; static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ - 0x00000,0x0199A,0x03333,0x04ccD,0x06667, - 0x08000,0x0999A,0x0b333,0x0cccD,0x0e667, - 0x10000,0x1199A,0x13333,0x14ccD,0x16667,0x18000 }; + 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667, + 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667, + 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667, + 0x18000 }; dprintk("%s()\n", __func__); snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); - if(snr_reading >= 0xa0 /* 100% */) + if (snr_reading >= 0xa0 /* 100% */) *snr = 0xffff; else - *snr = snr_tab [ ( snr_reading & 0xf0 ) >> 4 ] + - ( snr_tab [ ( snr_reading & 0x0f ) ] >> 4 ); + *snr = snr_tab[(snr_reading & 0xf0) >> 4] + + (snr_tab[(snr_reading & 0x0f)] >> 4); dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__, snr_reading, *snr); @@ -736,7 +772,7 @@ static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr) * ESNO, from 0->30db (values 0->300). We provide this value by * default. */ -static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr) +static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr) { struct cx24116_state *state = fe->demodulator_priv; @@ -750,7 +786,7 @@ static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr) return 0; } -static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) +static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr) { if (esno_snr == 1) return cx24116_read_snr_esno(fe, snr); @@ -758,27 +794,27 @@ static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr) return cx24116_read_snr_pct(fe, snr); } -static int cx24116_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) +static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct cx24116_state *state = fe->demodulator_priv; dprintk("%s()\n", __func__); - *ucblocks = ( cx24116_readreg(state, CX24116_REG_UCB8) << 8 ) | + *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) | cx24116_readreg(state, CX24116_REG_UCB0); return 0; } /* Overwrite the current tuning params, we are about to tune */ -static void cx24116_clone_params(struct dvb_frontend* fe) +static void cx24116_clone_params(struct dvb_frontend *fe) { struct cx24116_state *state = fe->demodulator_priv; memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur)); } /* Wait for LNB */ -static int cx24116_wait_for_lnb(struct dvb_frontend* fe) +static int cx24116_wait_for_lnb(struct dvb_frontend *fe) { struct cx24116_state *state = fe->demodulator_priv; int i; @@ -787,7 +823,7 @@ static int cx24116_wait_for_lnb(struct dvb_frontend* fe) cx24116_readreg(state, CX24116_REG_QSTATUS)); /* Wait for up to 300 ms */ - for(i = 0; i < 30 ; i++) { + for (i = 0; i < 30 ; i++) { if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20) return 0; msleep(10); @@ -798,20 +834,21 @@ static int cx24116_wait_for_lnb(struct dvb_frontend* fe) return -ETIMEDOUT; /* -EBUSY ? */ } -static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +static int cx24116_set_tone(struct dvb_frontend *fe, + fe_sec_tone_mode_t tone) { struct cx24116_cmd cmd; int ret; dprintk("%s(%d)\n", __func__, tone); - if ( (tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF) ) { - printk("%s: Invalid, tone=%d\n", __func__, tone); + if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { + printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone); return -EINVAL; } /* Wait for LNB ready */ ret = cx24116_wait_for_lnb(fe); - if(ret != 0) + if (ret != 0) return ret; /* Min delay time after DiSEqC send */ @@ -820,7 +857,7 @@ static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) /* This is always done before the tone is set */ cmd.args[0x00] = CMD_SET_TONEPRE; cmd.args[0x01] = 0x00; - cmd.len= 0x02; + cmd.len = 0x02; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -836,11 +873,11 @@ static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) cmd.args[0x03] = 0x01; break; case SEC_TONE_OFF: - dprintk("%s: setting tone off\n",__func__); + dprintk("%s: setting tone off\n", __func__); cmd.args[0x03] = 0x00; break; } - cmd.len= 0x04; + cmd.len = 0x04; /* Min delay time before DiSEqC send */ msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ @@ -849,7 +886,7 @@ static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) } /* Initialise DiSEqC */ -static int cx24116_diseqc_init(struct dvb_frontend* fe) +static int cx24116_diseqc_init(struct dvb_frontend *fe) { struct cx24116_state *state = fe->demodulator_priv; struct cx24116_cmd cmd; @@ -864,7 +901,7 @@ static int cx24116_diseqc_init(struct dvb_frontend* fe) cmd.args[0x05] = 0x28; cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01; cmd.args[0x07] = 0x01; - cmd.len= 0x08; + cmd.len = 0x08; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -878,36 +915,38 @@ static int cx24116_diseqc_init(struct dvb_frontend* fe) /* Unknown */ state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02; state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00; - state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; /* Continuation flag? */ + /* Continuation flag? */ + state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; /* DiSEqC message length */ state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00; /* Command length */ - state->dsec_cmd.len= CX24116_DISEQC_MSGOFS; + state->dsec_cmd.len = CX24116_DISEQC_MSGOFS; return 0; } /* Send DiSEqC message with derived burst (hack) || previous burst */ -static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *d) +static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *d) { struct cx24116_state *state = fe->demodulator_priv; int i, ret; /* Dump DiSEqC message */ if (debug) { - printk("cx24116: %s(", __func__); - for(i = 0 ; i < d->msg_len ;) { - printk("0x%02x", d->msg[i]); - if(++i < d->msg_len) - printk(", "); - } + printk(KERN_INFO "cx24116: %s(", __func__); + for (i = 0 ; i < d->msg_len ;) { + printk(KERN_INFO "0x%02x", d->msg[i]); + if (++i < d->msg_len) + printk(KERN_INFO ", "); + } printk(") toneburst=%d\n", toneburst); } /* Validate length */ - if(d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) + if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) return -EINVAL; /* DiSEqC message */ @@ -918,18 +957,19 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len; /* Command length */ - state->dsec_cmd.len= CX24116_DISEQC_MSGOFS + state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; + state->dsec_cmd.len = CX24116_DISEQC_MSGOFS + + state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; /* DiSEqC toneburst */ - if(toneburst == CX24116_DISEQC_MESGCACHE) + if (toneburst == CX24116_DISEQC_MESGCACHE) /* Message is cached */ return 0; - else if(toneburst == CX24116_DISEQC_TONEOFF) + else if (toneburst == CX24116_DISEQC_TONEOFF) /* Message is sent without burst */ state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0; - else if(toneburst == CX24116_DISEQC_TONECACHE) { + else if (toneburst == CX24116_DISEQC_TONECACHE) { /* * Message is sent with derived else cached burst * @@ -948,15 +988,17 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma * Y = VOLTAGE (0=13V, 1=18V) * Z = BAND (0=LOW, 1=HIGH(22K)) */ - if(d->msg_len >= 4 && d->msg[2] == 0x38) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = ((d->msg[3] & 4) >> 2); - if(debug) - dprintk("%s burst=%d\n", __func__, state->dsec_cmd.args[CX24116_DISEQC_BURST]); + if (d->msg_len >= 4 && d->msg[2] == 0x38) + state->dsec_cmd.args[CX24116_DISEQC_BURST] = + ((d->msg[3] & 4) >> 2); + if (debug) + dprintk("%s burst=%d\n", __func__, + state->dsec_cmd.args[CX24116_DISEQC_BURST]); } /* Wait for LNB ready */ ret = cx24116_wait_for_lnb(fe); - if(ret != 0) + if (ret != 0) return ret; /* Wait for voltage/min repeat delay */ @@ -964,7 +1006,7 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma /* Command */ ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if(ret != 0) + if (ret != 0) return ret; /* * Wait for send @@ -976,29 +1018,33 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma * 12.5ms burst + * >15ms delay (XXX determine if FW does this, see set_tone) */ - msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60) ); + msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + + ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60)); return 0; } /* Send DiSEqC burst */ -static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) +static int cx24116_diseqc_send_burst(struct dvb_frontend *fe, + fe_sec_mini_cmd_t burst) { struct cx24116_state *state = fe->demodulator_priv; int ret; - dprintk("%s(%d) toneburst=%d\n",__func__, burst, toneburst); + dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst); /* DiSEqC burst */ if (burst == SEC_MINI_A) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A; - else if(burst == SEC_MINI_B) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_B; + state->dsec_cmd.args[CX24116_DISEQC_BURST] = + CX24116_DISEQC_MINI_A; + else if (burst == SEC_MINI_B) + state->dsec_cmd.args[CX24116_DISEQC_BURST] = + CX24116_DISEQC_MINI_B; else return -EINVAL; /* DiSEqC toneburst */ - if(toneburst != CX24116_DISEQC_MESGCACHE) + if (toneburst != CX24116_DISEQC_MESGCACHE) /* Burst is cached */ return 0; @@ -1006,7 +1052,7 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t /* Wait for LNB ready */ ret = cx24116_wait_for_lnb(fe); - if(ret != 0) + if (ret != 0) return ret; /* Wait for voltage/min repeat delay */ @@ -1014,7 +1060,7 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t /* Command */ ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if(ret != 0) + if (ret != 0) return ret; /* @@ -1027,34 +1073,32 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t * 12.5ms burst + * >15ms delay (XXX determine if FW does this, see set_tone) */ - msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60 ); + msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60); return 0; } -static void cx24116_release(struct dvb_frontend* fe) +static void cx24116_release(struct dvb_frontend *fe) { - struct cx24116_state* state = fe->demodulator_priv; - dprintk("%s\n",__func__); + struct cx24116_state *state = fe->demodulator_priv; + dprintk("%s\n", __func__); kfree(state); } static struct dvb_frontend_ops cx24116_ops; -struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, - struct i2c_adapter* i2c) +struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, + struct i2c_adapter *i2c) { - struct cx24116_state* state = NULL; + struct cx24116_state *state = NULL; int ret; - dprintk("%s\n",__func__); + dprintk("%s\n", __func__); /* allocate memory for the internal state */ state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL); - if (state == NULL) { - printk("Unable to kmalloc\n"); + if (state == NULL) goto error1; - } /* setup the state */ memset(state, 0, sizeof(struct cx24116_state)); @@ -1063,32 +1107,36 @@ struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, state->i2c = i2c; /* check if the demod is present */ - ret = (cx24116_readreg(state, 0xFF) << 8) | cx24116_readreg(state, 0xFE); + ret = (cx24116_readreg(state, 0xFF) << 8) | + cx24116_readreg(state, 0xFE); if (ret != 0x0501) { - printk("Invalid probe, probably not a CX24116 device\n"); + printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n"); goto error2; } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24116_ops, sizeof(struct dvb_frontend_ops)); + memcpy(&state->frontend.ops, &cx24116_ops, + sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; return &state->frontend; error2: kfree(state); error1: return NULL; } +EXPORT_SYMBOL(cx24116_attach); + /* * Initialise or wake up device * * Power config will reset and load initial firmware if required */ -static int cx24116_initfe(struct dvb_frontend* fe) +static int cx24116_initfe(struct dvb_frontend *fe) { - struct cx24116_state* state = fe->demodulator_priv; + struct cx24116_state *state = fe->demodulator_priv; struct cx24116_cmd cmd; int ret; - dprintk("%s()\n",__func__); + dprintk("%s()\n", __func__); /* Power on */ cx24116_writereg(state, 0xe0, 0); @@ -1098,9 +1146,9 @@ static int cx24116_initfe(struct dvb_frontend* fe) /* Firmware CMD 36: Power config */ cmd.args[0x00] = CMD_TUNERSLEEP; cmd.args[0x01] = 0; - cmd.len= 0x02; + cmd.len = 0x02; ret = cx24116_cmd_execute(fe, &cmd); - if(ret != 0) + if (ret != 0) return ret; return cx24116_diseqc_init(fe); @@ -1109,20 +1157,20 @@ static int cx24116_initfe(struct dvb_frontend* fe) /* * Put device to sleep */ -static int cx24116_sleep(struct dvb_frontend* fe) +static int cx24116_sleep(struct dvb_frontend *fe) { - struct cx24116_state* state = fe->demodulator_priv; + struct cx24116_state *state = fe->demodulator_priv; struct cx24116_cmd cmd; int ret; - dprintk("%s()\n",__func__); + dprintk("%s()\n", __func__); /* Firmware CMD 36: Power config */ cmd.args[0x00] = CMD_TUNERSLEEP; cmd.args[0x01] = 1; - cmd.len= 0x02; + cmd.len = 0x02; ret = cx24116_cmd_execute(fe, &cmd); - if(ret != 0) + if (ret != 0) return ret; /* Power off (Shutdown clocks) */ @@ -1133,13 +1181,15 @@ static int cx24116_sleep(struct dvb_frontend* fe) return 0; } -static int cx24116_set_property(struct dvb_frontend *fe, struct dtv_property* tvp) +static int cx24116_set_property(struct dvb_frontend *fe, + struct dtv_property *tvp) { dprintk("%s(..)\n", __func__); return 0; } -static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tvp) +static int cx24116_get_property(struct dvb_frontend *fe, + struct dtv_property *tvp) { dprintk("%s(..)\n", __func__); return 0; @@ -1148,7 +1198,8 @@ static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tv /* dvb-core told us to tune, the tv property cache will be complete, * it's safe for is to pull values and use them for tuning purposes. */ -static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) +static int cx24116_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) { struct cx24116_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; @@ -1156,96 +1207,102 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par fe_status_t tunerstat; int i, status, ret, retune; - dprintk("%s()\n",__func__); + dprintk("%s()\n", __func__); - switch(c->delivery_system) { - case SYS_DVBS: - dprintk("%s: DVB-S delivery system selected\n",__func__); + switch (c->delivery_system) { + case SYS_DVBS: + dprintk("%s: DVB-S delivery system selected\n", __func__); - /* Only QPSK is supported for DVB-S */ - if(c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } + /* Only QPSK is supported for DVB-S */ + if (c->modulation != QPSK) { + dprintk("%s: unsupported modulation selected (%d)\n", + __func__, c->modulation); + return -EOPNOTSUPP; + } - /* Pilot doesn't exist in DVB-S, turn bit off */ - state->dnxt.pilot_val = CX24116_PILOT_OFF; - retune = 1; + /* Pilot doesn't exist in DVB-S, turn bit off */ + state->dnxt.pilot_val = CX24116_PILOT_OFF; + retune = 1; - /* DVB-S only supports 0.35 */ - if(c->rolloff != ROLLOFF_35) { - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); - return -EOPNOTSUPP; - } - state->dnxt.rolloff_val = CX24116_ROLLOFF_035; - break; + /* DVB-S only supports 0.35 */ + if (c->rolloff != ROLLOFF_35) { + dprintk("%s: unsupported rolloff selected (%d)\n", + __func__, c->rolloff); + return -EOPNOTSUPP; + } + state->dnxt.rolloff_val = CX24116_ROLLOFF_035; + break; - case SYS_DVBS2: - dprintk("%s: DVB-S2 delivery system selected\n",__func__); - - /* - * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, - * but not hardware auto detection - */ - if(c->modulation != PSK_8 && c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } + case SYS_DVBS2: + dprintk("%s: DVB-S2 delivery system selected\n", __func__); - switch(c->pilot) { - case PILOT_AUTO: /* Not supported but emulated */ - retune = 2; /* Fall-through */ - case PILOT_OFF: - state->dnxt.pilot_val = CX24116_PILOT_OFF; - break; - case PILOT_ON: - state->dnxt.pilot_val = CX24116_PILOT_ON; - break; - default: - dprintk("%s: unsupported pilot mode selected (%d)\n", - __func__, c->pilot); - return -EOPNOTSUPP; - } + /* + * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, + * but not hardware auto detection + */ + if (c->modulation != PSK_8 && c->modulation != QPSK) { + dprintk("%s: unsupported modulation selected (%d)\n", + __func__, c->modulation); + return -EOPNOTSUPP; + } - switch(c->rolloff) { - case ROLLOFF_20: - state->dnxt.rolloff_val= CX24116_ROLLOFF_020; - break; - case ROLLOFF_25: - state->dnxt.rolloff_val= CX24116_ROLLOFF_025; - break; - case ROLLOFF_35: - state->dnxt.rolloff_val= CX24116_ROLLOFF_035; - break; - case ROLLOFF_AUTO: /* Rolloff must be explicit */ - default: - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); - return -EOPNOTSUPP; - } + switch (c->pilot) { + case PILOT_AUTO: /* Not supported but emulated */ + state->dnxt.pilot_val = (c->modulation == QPSK) + ? CX24116_PILOT_OFF : CX24116_PILOT_ON; + retune = 2; + break; + case PILOT_OFF: + state->dnxt.pilot_val = CX24116_PILOT_OFF; + break; + case PILOT_ON: + state->dnxt.pilot_val = CX24116_PILOT_ON; break; + default: + dprintk("%s: unsupported pilot mode selected (%d)\n", + __func__, c->pilot); + return -EOPNOTSUPP; + } + switch (c->rolloff) { + case ROLLOFF_20: + state->dnxt.rolloff_val = CX24116_ROLLOFF_020; + break; + case ROLLOFF_25: + state->dnxt.rolloff_val = CX24116_ROLLOFF_025; + break; + case ROLLOFF_35: + state->dnxt.rolloff_val = CX24116_ROLLOFF_035; + break; + case ROLLOFF_AUTO: /* Rolloff must be explicit */ default: - dprintk("%s: unsupported delivery system selected (%d)\n", - __func__, c->delivery_system); + dprintk("%s: unsupported rolloff selected (%d)\n", + __func__, c->rolloff); return -EOPNOTSUPP; + } + break; + + default: + dprintk("%s: unsupported delivery system selected (%d)\n", + __func__, c->delivery_system); + return -EOPNOTSUPP; } state->dnxt.modulation = c->modulation; state->dnxt.frequency = c->frequency; state->dnxt.pilot = c->pilot; state->dnxt.rolloff = c->rolloff; - if ((ret = cx24116_set_inversion(state, c->inversion)) != 0) + ret = cx24116_set_inversion(state, c->inversion); + if (ret != 0) return ret; /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ - if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0) + ret = cx24116_set_fec(state, c->modulation, c->fec_inner); + if (ret != 0) return ret; - if ((ret = cx24116_set_symbolrate(state, c->symbol_rate)) != 0) + ret = cx24116_set_symbolrate(state, c->symbol_rate); + if (ret != 0) return ret; /* discard the 'current' tuning parameters and prepare to tune */ @@ -1271,7 +1328,7 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par /* Set/Reset B/W */ cmd.args[0x00] = CMD_BANDWIDTH; cmd.args[0x01] = 0x01; - cmd.len= 0x02; + cmd.len = 0x02; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -1319,7 +1376,7 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); } - cmd.len= 0x13; + cmd.len = 0x13; /* We need to support pilot and non-pilot tuning in the * driver automatically. This is a workaround for because @@ -1327,12 +1384,13 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par */ do { /* Reset status register */ - status = cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK; + status = cx24116_readreg(state, CX24116_REG_SSTATUS) + & CX24116_SIGNAL_MASK; cx24116_writereg(state, CX24116_REG_SSTATUS, status); /* Tune */ ret = cx24116_cmd_execute(fe, &cmd); - if( ret != 0 ) + if (ret != 0) break; /* @@ -1341,28 +1399,27 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par * If we are able to tune then generally it occurs within 100ms. * If it takes longer, try a different toneburst setting. */ - for(i = 0; i < 50 ; i++) { + for (i = 0; i < 50 ; i++) { cx24116_read_status(fe, &tunerstat); status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC); - if(status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { - dprintk("%s: Tuned\n",__func__); + if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { + dprintk("%s: Tuned\n", __func__); goto tuned; } msleep(10); } - dprintk("%s: Not tuned\n",__func__); + dprintk("%s: Not tuned\n", __func__); /* Toggle pilot bit when in auto-pilot */ - if(state->dcur.pilot == PILOT_AUTO) + if (state->dcur.pilot == PILOT_AUTO) cmd.args[0x07] ^= CX24116_PILOT_ON; - } - while(--retune); + } while (--retune); tuned: /* Set/Reset B/W */ cmd.args[0x00] = CMD_BANDWIDTH; cmd.args[0x01] = 0x00; - cmd.len= 0x02; + cmd.len = 0x02; ret = cx24116_cmd_execute(fe, &cmd); if (ret != 0) return ret; @@ -1407,17 +1464,7 @@ static struct dvb_frontend_ops cx24116_ops = { .set_frontend = cx24116_set_frontend, }; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -module_param(toneburst, int, 0644); -MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, 2=MESSAGE CACHE (default:1)"); - -module_param(esno_snr, int, 0644); -MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, 1=ESNO(db * 10) (default:0)"); - MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware"); MODULE_AUTHOR("Steven Toth"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(cx24116_attach); diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h index 8dbcec2..4cb3ddd 100644 --- a/drivers/media/dvb/frontends/cx24116.h +++ b/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 */ diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index 7156157..1a8c36f 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/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); diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h index cc6b411..51ae866 100644 --- a/drivers/media/dvb/frontends/cx24123.h +++ b/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 */ diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index 7500a1c..cf4d893 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/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: diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h index d1a1d2e..070d974 100644 --- a/drivers/media/dvb/frontends/s5h1409.h +++ b/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; diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c index 2da1a37..2febfb5 100644 --- a/drivers/media/dvb/frontends/s5h1411.c +++ b/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 } }; diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 04e7f1c..2a8bbcd 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/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; diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h index d2876d2..07f3fc0 100644 --- a/drivers/media/dvb/frontends/z0194a.h +++ b/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 diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 9da260f..6f9b773 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/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), diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index e51d707..04cd7c0 100644 --- a/drivers/media/radio/Kconfig +++ b/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" diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index f6cedcd..5920cd30 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/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, @@ -1175,18 +1187,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { .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, .name = "Mute", @@ -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, - }, }; @@ -1220,56 +1216,34 @@ 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, }; diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index f794f2d..e0eb4f3 100644 --- a/drivers/media/video/adv7170.c +++ b/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); diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index 8ee07a6..6008e84 100644 --- a/drivers/media/video/adv7175.c +++ b/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); diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 5f07a8a..d60123b 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/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), diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c index d856de9..5765e86 100644 --- a/drivers/media/video/au0828/au0828-core.c +++ b/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); diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c index f0fcdb4..a882cf5 100644 --- a/drivers/media/video/au0828/au0828-dvb.c +++ b/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, diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index ddd2a79..a07b7b8 100644 --- a/drivers/media/video/bt819.c +++ b/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); diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index ab2ce4d..4213867 100644 --- a/drivers/media/video/bt856.c +++ b/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); diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c index 96b4155..596f9e2 100644 --- a/drivers/media/video/bt866.c +++ b/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, +}; diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 2cda15f..dac5ccc 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/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 - */ diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index beb3e61..8f6fb2a 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/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 - */ diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 24bd183..e1aac07 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/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 -*/ diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index f98e476..bb7f71a 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/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; } diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index f75ed1c..ab3110d 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/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, diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index ba4e0aa..1d53f54 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/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 - */ diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 5da04e8..fbc224f 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/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]; diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index d656fec..60705b0 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/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) diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 344ed26..6968ab0 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/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); diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 8e74d64..01de230 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/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); diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a6b061c..6df5cf3 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/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; diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 3a1977f..7dd506b 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/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) { diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index be45955..3904b73 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/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(); diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index dbf01b8..76207c2 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/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); diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index c21af31..e48fbfc 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/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; diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 4779dd0..1d9dc90 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/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> diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h index c786d7d..1a37ae4 100644 --- a/drivers/media/video/gspca/m5602/m5602_bridge.h +++ b/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 diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 19d5e35..fd6ce38 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/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, " diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 566d492..fb700c2 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/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]); } diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h index 79a5d88..315209d5 100644 --- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h +++ b/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 } }, diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index 31c5896..837c7e47 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/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; diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h index 2f29cb0..065632f 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/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); diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c index 08c015b..d17ac52 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.c +++ b/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); diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h index 68f34c9..a0b75ff 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.h +++ b/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}, diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 6820256..14b1eac 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/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; diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h index bb7f7e3..eaef676 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ b/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); diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c index b4b33c2..8988a72 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c +++ b/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]); } diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h index 833708e..ee3ee9c 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h +++ b/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); diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h index 930fcaa..60c9a48 100644 --- a/drivers/media/video/gspca/m5602/m5602_sensor.h +++ b/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> * diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index b561f7c..eac245d 100644 --- a/drivers/media/video/gspca/t613.c +++ b/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, }; diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index b7457fc..1c404e4 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/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); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 8696527..208fb54 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/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; diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c index 2fd4b4a..bae2d2b 100644 --- a/drivers/media/video/ks0127.c +++ b/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), ®}, - {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}}; + { c->addr, 0, sizeof(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, +}; diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 4aa82b3..adf2ba7 100644 --- a/drivers/media/video/saa7110.c +++ b/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); diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index 96c3d43..a4738a2 100644 --- a/drivers/media/video/saa7111.c +++ b/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); diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index e790755..7ca709f 100644 --- a/drivers/media/video/saa7114.c +++ b/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); diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index d0e83fe..cc02fb1 100644 --- a/drivers/media/video/saa7127.c +++ b/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 diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 87c1098..8c46115 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/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; } diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 491ab1f..24096d6 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/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); diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 02fda4e..6debb65 100644 --- a/drivers/media/video/saa7185.c +++ b/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); diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 7683809..2407607 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/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 */ diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index 1adc257..bb7a9d4 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/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; } diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index db69bc5..edaea49 100644 --- a/drivers/media/video/stk-webcam.c +++ b/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); diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h index 084a85b..9f67366 100644 --- a/drivers/media/video/stk-webcam.h +++ b/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 *); diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index bcc32fa..3b0b84c 100644 --- a/drivers/media/video/tveeprom.c +++ b/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"}, diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c index b56cffc..917277d 100644 --- a/drivers/media/video/videobuf-dvb.c +++ b/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); diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 65c8af1..7d7e51d 100644 --- a/drivers/media/video/vivi.c +++ b/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; diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 45be9ec..67aa0db 100644 --- a/drivers/media/video/vpx3220.c +++ b/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"); diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 3282be7..fa5f2f8 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/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; diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 25de763..db11ab9 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/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", diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 6e4ace2..79a8ed8 100644 --- a/include/linux/dvb/frontend.h +++ b/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, diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 493435b..01d67ba 100644 --- a/include/linux/i2c-id.h +++ b/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 */ diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h index 851f182..1d092b4 100644 --- a/include/media/soc_camera_platform.h +++ b/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); }; diff --git a/include/media/tuner.h b/include/media/tuner.h index 67c1f51..7d4e2db 100644 --- a/include/media/tuner.h +++ b/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) diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h index 975ffbf..e65dd9d 100644 --- a/include/media/v4l2-i2c-drv-legacy.h +++ b/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; diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h index 40ecef2..efdc8bf 100644 --- a/include/media/v4l2-i2c-drv.h +++ b/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__ diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h index b777486..80471c2 100644 --- a/include/media/videobuf-dvb.h +++ b/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: |