mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
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. ...
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
@@ -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:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user