提交 5564da7e 编写于 作者: L Linus Torvalds

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.
  ...
0 -> Unknown board (au0828) 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] 2 -> Hauppauge HVR850 (au0828) [2040:7240]
3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281] 4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281]
......
...@@ -75,3 +75,4 @@ tuner=73 - Samsung TCPG 6121P30A ...@@ -75,3 +75,4 @@ tuner=73 - Samsung TCPG 6121P30A
tuner=75 - Philips TEA5761 FM Radio tuner=75 - Philips TEA5761 FM Radio
tuner=76 - Xceive 5000 tuner tuner=76 - Xceive 5000 tuner
tuner=77 - TCL tuner MF02GIP-5N-E 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, ...@@ -3481,7 +3481,9 @@ static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
} }
ctrlVal = 0; ctrlVal = 0;
for (k = 0; k < state->MXL_Ctrl[i].size; k++) 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 } else
return -1; return -1;
} }
...@@ -3581,7 +3583,7 @@ static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit, ...@@ -3581,7 +3583,7 @@ static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
static u32 MXL_Ceiling(u32 value, u32 resolution) 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 */ /* Retrieve the Initialzation Registers */
...@@ -3910,7 +3912,10 @@ static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable, ...@@ -3910,7 +3912,10 @@ static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
static int mxl5005s_init(struct dvb_frontend *fe) static int mxl5005s_init(struct dvb_frontend *fe)
{ {
struct mxl5005s_state *state = fe->tuner_priv;
dprintk(1, "%s()\n", __func__); dprintk(1, "%s()\n", __func__);
state->current_mode = MXL_QAM;
return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ); return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ);
} }
...@@ -4092,7 +4097,6 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, ...@@ -4092,7 +4097,6 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
state->frontend = fe; state->frontend = fe;
state->config = config; state->config = config;
state->i2c = i2c; state->i2c = i2c;
state->current_mode = MXL_QAM;
printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n", printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n",
config->i2c_address); config->i2c_address);
......
...@@ -493,6 +493,7 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) ...@@ -493,6 +493,7 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FM1236_MK3:
case TUNER_PHILIPS_FMD1216ME_MK3: case TUNER_PHILIPS_FMD1216ME_MK3:
case TUNER_PHILIPS_FMD1216MEX_MK3:
case TUNER_LG_NTSC_TAPE: case TUNER_LG_NTSC_TAPE:
case TUNER_PHILIPS_FM1256_IH3: case TUNER_PHILIPS_FM1256_IH3:
case TUNER_TCL_MF02GIP_5N: case TUNER_TCL_MF02GIP_5N:
...@@ -767,6 +768,7 @@ static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf, ...@@ -767,6 +768,7 @@ static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf,
switch (priv->type) { switch (priv->type) {
case TUNER_PHILIPS_FMD1216ME_MK3: case TUNER_PHILIPS_FMD1216ME_MK3:
case TUNER_PHILIPS_FMD1216MEX_MK3:
if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ &&
params->frequency >= 158870000) params->frequency >= 158870000)
buf[3] |= 0x08; buf[3] |= 0x08;
......
...@@ -946,7 +946,7 @@ static struct tuner_params tuner_tena_9533_di_params[] = { ...@@ -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[] = { static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
{ 16 * 160.00 /*MHz*/, 0x86, 0x51, }, { 16 * 160.00 /*MHz*/, 0x86, 0x51, },
...@@ -984,6 +984,27 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = { ...@@ -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 ----- */ /* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */
...@@ -1663,6 +1684,16 @@ struct tunertype tuners[] = { ...@@ -1663,6 +1684,16 @@ struct tunertype tuners[] = {
.params = tuner_tcl_mf02gip_5n_params, .params = tuner_tcl_mf02gip_5n_params,
.count = ARRAY_SIZE(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); EXPORT_SYMBOL(tuners);
......
...@@ -43,7 +43,7 @@ MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization."); ...@@ -43,7 +43,7 @@ MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization.");
static DEFINE_MUTEX(xc5000_list_mutex); static DEFINE_MUTEX(xc5000_list_mutex);
static LIST_HEAD(hybrid_tuner_instance_list); 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) printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw"
...@@ -138,11 +138,11 @@ struct xc5000_priv { ...@@ -138,11 +138,11 @@ struct xc5000_priv {
immediately the length of the following transaction. immediately the length of the following transaction.
*/ */
typedef struct { struct XC_TV_STANDARD {
char *Name; char *Name;
u16 AudioMode; u16 AudioMode;
u16 VideoMode; u16 VideoMode;
} XC_TV_STANDARD; };
/* Tuner standards */ /* Tuner standards */
#define MN_NTSC_PAL_BTSC 0 #define MN_NTSC_PAL_BTSC 0
...@@ -169,7 +169,7 @@ typedef struct { ...@@ -169,7 +169,7 @@ typedef struct {
#define FM_Radio_INPUT2 21 #define FM_Radio_INPUT2 21
#define FM_Radio_INPUT1 22 #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-BTSC", 0x0400, 0x8020},
{"M/N-NTSC/PAL-A2", 0x0600, 0x8020}, {"M/N-NTSC/PAL-A2", 0x0600, 0x8020},
{"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020}, {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
...@@ -183,7 +183,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { ...@@ -183,7 +183,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
{"D/K-PAL-NICAM", 0x0E80, 0x8009}, {"D/K-PAL-NICAM", 0x0E80, 0x8009},
{"D/K-PAL-MONO", 0x1478, 0x8009}, {"D/K-PAL-MONO", 0x1478, 0x8009},
{"D/K-SECAM-A2 DK1", 0x1200, 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}, {"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
{"L-SECAM-NICAM", 0x8E82, 0x0009}, {"L-SECAM-NICAM", 0x8E82, 0x0009},
{"L'-SECAM-NICAM", 0x8E82, 0x4009}, {"L'-SECAM-NICAM", 0x8E82, 0x4009},
...@@ -307,9 +307,10 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) ...@@ -307,9 +307,10 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
unsigned int len, pos, index; unsigned int len, pos, index;
u8 buf[XC_MAX_I2C_WRITE_LENGTH]; u8 buf[XC_MAX_I2C_WRITE_LENGTH];
index=0; index = 0;
while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) { while ((i2c_sequence[index] != 0xFF) ||
len = i2c_sequence[index]* 256 + i2c_sequence[index+1]; (i2c_sequence[index + 1] != 0xFF)) {
len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
if (len == 0x0000) { if (len == 0x0000) {
/* RESET command */ /* RESET command */
result = xc_reset(fe); result = xc_reset(fe);
...@@ -329,15 +330,17 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) ...@@ -329,15 +330,17 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
buf[1] = i2c_sequence[index + 1]; buf[1] = i2c_sequence[index + 1];
pos = 2; pos = 2;
while (pos < len) { while (pos < len) {
if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2) { if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
nbytes_to_send = XC_MAX_I2C_WRITE_LENGTH; nbytes_to_send =
} else { XC_MAX_I2C_WRITE_LENGTH;
else
nbytes_to_send = (len - pos + 2); 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++) { result = xc_send_i2c_data(priv, buf,
buf[i] = i2c_sequence[index + pos + i - 2]; nbytes_to_send);
}
result = xc_send_i2c_data(priv, buf, nbytes_to_send);
if (result != XC_RESULT_SUCCESS) if (result != XC_RESULT_SUCCESS)
return result; return result;
...@@ -386,8 +389,7 @@ static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) ...@@ -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, dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE"); 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; rf_mode = XC_RF_MODE_CABLE;
printk(KERN_ERR printk(KERN_ERR
"%s(), Invalid mode, defaulting to CABLE", "%s(), Invalid mode, defaulting to CABLE",
...@@ -560,13 +562,13 @@ static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len) ...@@ -560,13 +562,13 @@ static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len)
.flags = I2C_M_RD, .buf = buf, .len = len }; .flags = I2C_M_RD, .buf = buf, .len = len };
if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { 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 -EREMOTEIO;
} }
return 0; 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; struct xc5000_priv *priv = fe->tuner_priv;
const struct firmware *fw; const struct firmware *fw;
...@@ -576,7 +578,8 @@ static int xc5000_fwupload(struct dvb_frontend* fe) ...@@ -576,7 +578,8 @@ static int xc5000_fwupload(struct dvb_frontend* fe)
printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
XC5000_DEFAULT_FIRMWARE); 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) { if (ret) {
printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
ret = XC_RESULT_RESET_FAILURE; ret = XC_RESULT_RESET_FAILURE;
...@@ -592,7 +595,7 @@ static int xc5000_fwupload(struct dvb_frontend* fe) ...@@ -592,7 +595,7 @@ static int xc5000_fwupload(struct dvb_frontend* fe)
ret = XC_RESULT_RESET_FAILURE; ret = XC_RESULT_RESET_FAILURE;
} else { } else {
printk(KERN_INFO "xc5000: firmware upload\n"); printk(KERN_INFO "xc5000: firmware upload\n");
ret = xc_load_i2c_sequence(fe, fw->data ); ret = xc_load_i2c_sequence(fe, fw->data);
} }
out: out:
...@@ -651,7 +654,7 @@ static int xc5000_set_params(struct dvb_frontend *fe, ...@@ -651,7 +654,7 @@ static int xc5000_set_params(struct dvb_frontend *fe,
dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); 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_8:
case VSB_16: case VSB_16:
dprintk(1, "%s() VSB modulation\n", __func__); dprintk(1, "%s() VSB modulation\n", __func__);
...@@ -748,42 +751,42 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, ...@@ -748,42 +751,42 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
/* FIX ME: Some video standards may have several possible audio /* FIX ME: Some video standards may have several possible audio
standards. We simply default to one of them here. 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 */ /* default to BTSC audio standard */
priv->video_standard = MN_NTSC_PAL_BTSC; priv->video_standard = MN_NTSC_PAL_BTSC;
goto tune_channel; goto tune_channel;
} }
if(params->std & V4L2_STD_PAL_BG) { if (params->std & V4L2_STD_PAL_BG) {
/* default to NICAM audio standard */ /* default to NICAM audio standard */
priv->video_standard = BG_PAL_NICAM; priv->video_standard = BG_PAL_NICAM;
goto tune_channel; goto tune_channel;
} }
if(params->std & V4L2_STD_PAL_I) { if (params->std & V4L2_STD_PAL_I) {
/* default to NICAM audio standard */ /* default to NICAM audio standard */
priv->video_standard = I_PAL_NICAM; priv->video_standard = I_PAL_NICAM;
goto tune_channel; goto tune_channel;
} }
if(params->std & V4L2_STD_PAL_DK) { if (params->std & V4L2_STD_PAL_DK) {
/* default to NICAM audio standard */ /* default to NICAM audio standard */
priv->video_standard = DK_PAL_NICAM; priv->video_standard = DK_PAL_NICAM;
goto tune_channel; goto tune_channel;
} }
if(params->std & V4L2_STD_SECAM_DK) { if (params->std & V4L2_STD_SECAM_DK) {
/* default to A2 DK1 audio standard */ /* default to A2 DK1 audio standard */
priv->video_standard = DK_SECAM_A2DK1; priv->video_standard = DK_SECAM_A2DK1;
goto tune_channel; goto tune_channel;
} }
if(params->std & V4L2_STD_SECAM_L) { if (params->std & V4L2_STD_SECAM_L) {
priv->video_standard = L_SECAM_NICAM; priv->video_standard = L_SECAM_NICAM;
goto tune_channel; goto tune_channel;
} }
if(params->std & V4L2_STD_SECAM_LC) { if (params->std & V4L2_STD_SECAM_LC) {
priv->video_standard = LC_SECAM_NICAM; priv->video_standard = LC_SECAM_NICAM;
goto tune_channel; goto tune_channel;
} }
...@@ -863,7 +866,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) ...@@ -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 * I2C transactions until calibration is complete. This way we
* don't have to rely on clock stretching working. * don't have to rely on clock stretching working.
*/ */
xc_wait( 100 ); xc_wait(100);
/* Default to "CABLE" mode */ /* Default to "CABLE" mode */
ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
...@@ -885,15 +888,13 @@ static int xc5000_sleep(struct dvb_frontend *fe) ...@@ -885,15 +888,13 @@ static int xc5000_sleep(struct dvb_frontend *fe)
*/ */
ret = xc_shutdown(priv); ret = xc_shutdown(priv);
if(ret != XC_RESULT_SUCCESS) { if (ret != XC_RESULT_SUCCESS) {
printk(KERN_ERR printk(KERN_ERR
"xc5000: %s() unable to shutdown tuner\n", "xc5000: %s() unable to shutdown tuner\n",
__func__); __func__);
return -EREMOTEIO; return -EREMOTEIO;
} } else
else {
return XC_RESULT_SUCCESS; return XC_RESULT_SUCCESS;
}
} }
static int xc5000_init(struct dvb_frontend *fe) static int xc5000_init(struct dvb_frontend *fe)
...@@ -989,7 +990,7 @@ struct dvb_frontend *xc5000_attach(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) if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0)
goto fail; goto fail;
switch(id) { switch (id) {
case XC_PRODUCT_ID_FW_LOADED: case XC_PRODUCT_ID_FW_LOADED:
printk(KERN_INFO printk(KERN_INFO
"xc5000: Successfully identified at address 0x%02x\n", "xc5000: Successfully identified at address 0x%02x\n",
......
...@@ -45,17 +45,17 @@ struct xc5000_config { ...@@ -45,17 +45,17 @@ struct xc5000_config {
#if defined(CONFIG_MEDIA_TUNER_XC5000) || \ #if defined(CONFIG_MEDIA_TUNER_XC5000) || \
(defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE)) (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 i2c_adapter *i2c,
struct xc5000_config *cfg); struct xc5000_config *cfg);
#else #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 i2c_adapter *i2c,
struct xc5000_config *cfg) struct xc5000_config *cfg)
{ {
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL; return NULL;
} }
#endif // CONFIG_MEDIA_TUNER_XC5000 #endif
#endif // __XC5000_H__ #endif
...@@ -595,6 +595,18 @@ static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb) ...@@ -595,6 +595,18 @@ static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb)
dm1105dvb_dma_unmap(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 = { static struct stv0288_config earda_config = {
.demod_address = 0x68, .demod_address = 0x68,
.min_delay_ms = 100, .min_delay_ms = 100,
......
...@@ -47,6 +47,7 @@ static int dvb_shutdown_timeout; ...@@ -47,6 +47,7 @@ static int dvb_shutdown_timeout;
static int dvb_force_auto_inversion; static int dvb_force_auto_inversion;
static int dvb_override_tune_delay; static int dvb_override_tune_delay;
static int dvb_powerdown_on_sleep = 1; 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_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); 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); ...@@ -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_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_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_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 #define dprintk if (dvb_frontend_debug) printk
...@@ -212,8 +215,9 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, ...@@ -212,8 +215,9 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
static void dvb_frontend_init(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->dvb->num,
fe->id,
fe->ops.info.name); fe->ops.info.name);
if (fe->ops.init) if (fe->ops.init)
...@@ -686,7 +690,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe) ...@@ -686,7 +690,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
mb(); mb();
fe_thread = kthread_run(dvb_frontend_thread, fe, 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)) { if (IS_ERR(fe_thread)) {
ret = PTR_ERR(fe_thread); ret = PTR_ERR(fe_thread);
printk("dvb_frontend_start: failed to start kthread (%d)\n", ret); 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, ...@@ -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); *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);
if (*freq_min == 0 || *freq_max == 0) if (*freq_min == 0 || *freq_max == 0)
printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n", printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
fe->dvb->num); fe->dvb->num,fe->id);
} }
static int dvb_frontend_check_parameters(struct dvb_frontend *fe, static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
...@@ -724,8 +728,8 @@ 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); dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max);
if ((freq_min && parms->frequency < freq_min) || if ((freq_min && parms->frequency < freq_min) ||
(freq_max && parms->frequency > freq_max)) { (freq_max && parms->frequency > freq_max)) {
printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n", printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
fe->dvb->num, parms->frequency, freq_min, freq_max); fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max);
return -EINVAL; return -EINVAL;
} }
...@@ -735,8 +739,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, ...@@ -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) || parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
(fe->ops.info.symbol_rate_max && (fe->ops.info.symbol_rate_max &&
parms->u.qpsk.symbol_rate > 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", printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
fe->dvb->num, parms->u.qpsk.symbol_rate, fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate,
fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
return -EINVAL; return -EINVAL;
} }
...@@ -746,8 +750,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, ...@@ -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) || parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) ||
(fe->ops.info.symbol_rate_max && (fe->ops.info.symbol_rate_max &&
parms->u.qam.symbol_rate > 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", printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
fe->dvb->num, parms->u.qam.symbol_rate, fe->dvb->num, fe->id, parms->u.qam.symbol_rate,
fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
return -EINVAL; return -EINVAL;
} }
...@@ -899,30 +903,30 @@ void dtv_property_dump(struct dtv_property *tvp) ...@@ -899,30 +903,30 @@ void dtv_property_dump(struct dtv_property *tvp)
int i; int i;
if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) { 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); __func__, tvp->cmd);
return; return;
} }
printk("%s() tvp.cmd = 0x%08x (%s)\n" dprintk("%s() tvp.cmd = 0x%08x (%s)\n"
,__FUNCTION__ ,__func__
,tvp->cmd ,tvp->cmd
,dtv_cmds[ tvp->cmd ].name); ,dtv_cmds[ tvp->cmd ].name);
if(dtv_cmds[ tvp->cmd ].buffer) { if(dtv_cmds[ tvp->cmd ].buffer) {
printk("%s() tvp.u.buffer.len = 0x%02x\n" dprintk("%s() tvp.u.buffer.len = 0x%02x\n"
,__FUNCTION__ ,__func__
,tvp->u.buffer.len); ,tvp->u.buffer.len);
for(i = 0; i < tvp->u.buffer.len; i++) for(i = 0; i < tvp->u.buffer.len; i++)
printk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n" dprintk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n"
,__FUNCTION__ ,__func__
,i ,i
,tvp->u.buffer.data[i]); ,tvp->u.buffer.data[i]);
} else } 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) 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 ...@@ -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; struct dtv_frontend_properties *c = &fe->dtv_property_cache;
printk("%s()\n", __FUNCTION__);
c->frequency = p->frequency; c->frequency = p->frequency;
c->inversion = p->inversion; c->inversion = p->inversion;
...@@ -998,27 +1000,25 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe) ...@@ -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_private *fepriv = fe->frontend_priv;
struct dvb_frontend_parameters *p = &fepriv->parameters; struct dvb_frontend_parameters *p = &fepriv->parameters;
printk("%s()\n", __FUNCTION__);
p->frequency = c->frequency; p->frequency = c->frequency;
p->inversion = c->inversion; p->inversion = c->inversion;
switch (fe->ops.info.type) { switch (fe->ops.info.type) {
case FE_QPSK: 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.symbol_rate = c->symbol_rate;
p->u.qpsk.fec_inner = c->fec_inner; p->u.qpsk.fec_inner = c->fec_inner;
c->delivery_system = SYS_DVBS; c->delivery_system = SYS_DVBS;
break; break;
case FE_QAM: 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.symbol_rate = c->symbol_rate;
p->u.qam.fec_inner = c->fec_inner; p->u.qam.fec_inner = c->fec_inner;
p->u.qam.modulation = c->modulation; p->u.qam.modulation = c->modulation;
c->delivery_system = SYS_DVBC_ANNEX_AC; c->delivery_system = SYS_DVBC_ANNEX_AC;
break; break;
case FE_OFDM: case FE_OFDM:
printk("%s() Preparing OFDM req\n", __FUNCTION__); dprintk("%s() Preparing OFDM req\n", __func__);
if (c->bandwidth_hz == 6000000) if (c->bandwidth_hz == 6000000)
p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
else if (c->bandwidth_hz == 7000000) else if (c->bandwidth_hz == 7000000)
...@@ -1036,7 +1036,7 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe) ...@@ -1036,7 +1036,7 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
c->delivery_system = SYS_DVBT; c->delivery_system = SYS_DVBT;
break; break;
case FE_ATSC: case FE_ATSC:
printk("%s() Preparing VSB req\n", __FUNCTION__); dprintk("%s() Preparing VSB req\n", __func__);
p->u.vsb.modulation = c->modulation; p->u.vsb.modulation = c->modulation;
if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
c->delivery_system = SYS_ATSC; c->delivery_system = SYS_ATSC;
...@@ -1055,14 +1055,13 @@ void dtv_property_adv_params_sync(struct dvb_frontend *fe) ...@@ -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_private *fepriv = fe->frontend_priv;
struct dvb_frontend_parameters *p = &fepriv->parameters; struct dvb_frontend_parameters *p = &fepriv->parameters;
printk("%s()\n", __FUNCTION__);
p->frequency = c->frequency; p->frequency = c->frequency;
p->inversion = c->inversion; p->inversion = c->inversion;
switch(c->modulation) { switch(c->modulation) {
case PSK_8: case PSK_8:
case APSK_16: case APSK_16:
case APSK_32:
case QPSK: case QPSK:
p->u.qpsk.symbol_rate = c->symbol_rate; p->u.qpsk.symbol_rate = c->symbol_rate;
p->u.qpsk.fec_inner = c->fec_inner; p->u.qpsk.fec_inner = c->fec_inner;
...@@ -1089,19 +1088,17 @@ void dtv_property_cache_submit(struct dvb_frontend *fe) ...@@ -1089,19 +1088,17 @@ void dtv_property_cache_submit(struct dvb_frontend *fe)
{ {
struct dtv_frontend_properties *c = &fe->dtv_property_cache; 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 /* For legacy delivery systems we don't need the delivery_system to
* be specified, but we populate the older structures from the cache * be specified, but we populate the older structures from the cache
* so we can call set_frontend on older drivers. * so we can call set_frontend on older drivers.
*/ */
if(is_legacy_delivery_system(c->delivery_system)) { 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); dtv_property_legacy_params_sync(fe);
} else { } 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 ... /* For advanced delivery systems / modulation types ...
* we seed the lecacy dvb_frontend_parameters structure * 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, ...@@ -1123,8 +1120,6 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp,
{ {
int r = 0; int r = 0;
printk("%s()\n", __FUNCTION__);
dtv_property_dump(tvp); dtv_property_dump(tvp);
/* Allow the frontend to validate incoming properties */ /* Allow the frontend to validate incoming properties */
...@@ -1198,7 +1193,6 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, ...@@ -1198,7 +1193,6 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
{ {
int r = 0; int r = 0;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
printk("%s()\n", __FUNCTION__);
dtv_property_dump(tvp); dtv_property_dump(tvp);
/* Allow the frontend to validate incoming properties */ /* Allow the frontend to validate incoming properties */
...@@ -1213,7 +1207,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, ...@@ -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 /* Reset a cache of data specific to the frontend here. This does
* not effect hardware. * 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)); memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
fe->dtv_property_cache.state = tvp->cmd; fe->dtv_property_cache.state = tvp->cmd;
fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; 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, ...@@ -1224,7 +1218,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
* ioctl. * ioctl.
*/ */
fe->dtv_property_cache.state = tvp->cmd; 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); dtv_property_cache_submit(fe);
r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, 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, ...@@ -1335,12 +1329,10 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
dprintk("%s\n", __func__); dprintk("%s\n", __func__);
if(cmd == FE_SET_PROPERTY) { if(cmd == FE_SET_PROPERTY) {
printk("%s() FE_SET_PROPERTY\n", __FUNCTION__);
tvps = (struct dtv_properties __user *)parg; tvps = (struct dtv_properties __user *)parg;
printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); dprintk("%s() properties.num = %d\n", __func__, tvps->num);
printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); dprintk("%s() properties.props = %p\n", __func__, tvps->props);
/* Put an arbitrary limit on the number of messages that can /* Put an arbitrary limit on the number of messages that can
* be sent at once */ * be sent at once */
...@@ -1364,18 +1356,16 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, ...@@ -1364,18 +1356,16 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
err |= (tvp + i)->result; err |= (tvp + i)->result;
} }
if(fe->dtv_property_cache.state == DTV_TUNE) { if(fe->dtv_property_cache.state == DTV_TUNE)
printk("%s() Property cache is full, tuning\n", __FUNCTION__); dprintk("%s() Property cache is full, tuning\n", __func__);
}
} else } else
if(cmd == FE_GET_PROPERTY) { if(cmd == FE_GET_PROPERTY) {
printk("%s() FE_GET_PROPERTY\n", __FUNCTION__);
tvps = (struct dtv_properties __user *)parg; tvps = (struct dtv_properties __user *)parg;
printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); dprintk("%s() properties.num = %d\n", __func__, tvps->num);
printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); dprintk("%s() properties.props = %p\n", __func__, tvps->props);
/* Put an arbitrary limit on the number of messages that can /* Put an arbitrary limit on the number of messages that can
* be sent at once */ * be sent at once */
...@@ -1704,13 +1694,53 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) ...@@ -1704,13 +1694,53 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data; struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dvb_adapter *adapter = fe->dvb;
int ret; int ret;
dprintk ("%s\n", __func__); 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 (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
return ret; goto err0;
} }
if ((ret = dvb_generic_open (inode, file)) < 0) if ((ret = dvb_generic_open (inode, file)) < 0)
...@@ -1730,6 +1760,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) ...@@ -1730,6 +1760,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
fepriv->events.eventr = fepriv->events.eventw = 0; fepriv->events.eventr = fepriv->events.eventw = 0;
} }
if (adapter->mfe_shared)
mutex_unlock (&adapter->mfe_lock);
return ret; return ret;
err2: err2:
...@@ -1737,6 +1769,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) ...@@ -1737,6 +1769,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
err1: err1:
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0); fe->ops.ts_bus_ctrl(fe, 0);
err0:
if (adapter->mfe_shared)
mutex_unlock (&adapter->mfe_lock);
return ret; return ret;
} }
...@@ -1806,8 +1841,9 @@ int dvb_register_frontend(struct dvb_adapter* dvb, ...@@ -1806,8 +1841,9 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
fe->dvb = dvb; fe->dvb = dvb;
fepriv->inversion = INVERSION_OFF; fepriv->inversion = INVERSION_OFF;
printk ("DVB: registering frontend %i (%s)...\n", printk ("DVB: registering adapter %i frontend %i (%s)...\n",
fe->dvb->num, fe->dvb->num,
fe->id,
fe->ops.info.name); fe->ops.info.name);
dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
......
...@@ -222,6 +222,7 @@ struct dvb_frontend { ...@@ -222,6 +222,7 @@ struct dvb_frontend {
struct dtv_frontend_properties dtv_property_cache; struct dtv_frontend_properties dtv_property_cache;
#define DVB_FRONTEND_COMPONENT_TUNER 0 #define DVB_FRONTEND_COMPONENT_TUNER 0
int (*callback)(void *adapter_priv, int component, int cmd, int arg); int (*callback)(void *adapter_priv, int component, int cmd, int arg);
int id;
}; };
extern int dvb_register_frontend(struct dvb_adapter *dvb, extern int dvb_register_frontend(struct dvb_adapter *dvb,
......
...@@ -326,6 +326,9 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, ...@@ -326,6 +326,9 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
adap->name = name; adap->name = name;
adap->module = module; adap->module = module;
adap->device = device; 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); list_add_tail (&adap->list_head, &dvb_adapter_list);
......
...@@ -62,6 +62,10 @@ struct dvb_adapter { ...@@ -62,6 +62,10 @@ struct dvb_adapter {
struct device *device; struct device *device;
struct module *module; 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) ...@@ -422,6 +422,18 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
return 0; 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 = { static struct cx24116_config dw2104_config = {
.demod_address = 0x55, .demod_address = 0x55,
.mpg_clk_pos_pol = 0x01, .mpg_clk_pos_pol = 0x01,
......
...@@ -30,8 +30,7 @@ ...@@ -30,8 +30,7 @@
#include <linux/dvb/frontend.h> #include <linux/dvb/frontend.h>
struct cx22702_config struct cx22702_config {
{
/* the demodulator's i2c address */ /* the demodulator's i2c address */
u8 demod_address; u8 demod_address;
...@@ -41,16 +40,19 @@ struct cx22702_config ...@@ -41,16 +40,19 @@ struct cx22702_config
u8 output_mode; u8 output_mode;
}; };
#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE)) #if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \
extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, && defined(MODULE))
struct i2c_adapter* i2c); extern struct dvb_frontend *cx22702_attach(
const struct cx22702_config *config,
struct i2c_adapter *i2c);
#else #else
static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, static inline struct dvb_frontend *cx22702_attach(
struct i2c_adapter* i2c) const struct cx22702_config *config,
struct i2c_adapter *i2c)
{ {
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL; return NULL;
} }
#endif // CONFIG_DVB_CX22702 #endif
#endif // CX22702_H #endif
...@@ -23,31 +23,32 @@ ...@@ -23,31 +23,32 @@
#include <linux/dvb/frontend.h> #include <linux/dvb/frontend.h>
struct cx24116_config struct cx24116_config {
{
/* the demodulator's i2c address */ /* the demodulator's i2c address */
u8 demod_address; u8 demod_address;
/* Need to set device param for start_dma */ /* 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 */ /* 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 */ /* Need to set MPEG parameters */
u8 mpg_clk_pos_pol:0x02; u8 mpg_clk_pos_pol:0x02;
}; };
#if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE) #if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE)
extern struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, extern struct dvb_frontend *cx24116_attach(
struct i2c_adapter* i2c); const struct cx24116_config *config,
struct i2c_adapter *i2c);
#else #else
static inline struct dvb_frontend* cx24116_attach(const struct cx24116_config* config, static inline struct dvb_frontend *cx24116_attach(
struct i2c_adapter* i2c) 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; return NULL;
} }
#endif // CONFIG_DVB_CX24116 #endif
#endif /* CX24116_H */ #endif /* CX24116_H */
...@@ -33,7 +33,13 @@ ...@@ -33,7 +33,13 @@
#define XTAL 10111000 #define XTAL 10111000
static int force_band; 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; 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 info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0)
#define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0) #define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0)
...@@ -46,10 +52,9 @@ static int debug; ...@@ -46,10 +52,9 @@ static int debug;
} \ } \
} while (0) } while (0)
struct cx24123_state struct cx24123_state {
{ struct i2c_adapter *i2c;
struct i2c_adapter* i2c; const struct cx24123_config *config;
const struct cx24123_config* config;
struct dvb_frontend frontend; struct dvb_frontend frontend;
...@@ -70,8 +75,7 @@ struct cx24123_state ...@@ -70,8 +75,7 @@ struct cx24123_state
}; };
/* Various tuner defaults need to be established for a given symbol rate Sps */ /* 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_low;
u32 symbolrate_high; u32 symbolrate_high;
u32 VCAprogdata; u32 VCAprogdata;
...@@ -109,8 +113,7 @@ static struct ...@@ -109,8 +113,7 @@ static struct
* fixme: The bounds on the bands do not match the doc in real life. * 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. * fixme: Some of them have been moved, other might need adjustment.
*/ */
static struct static struct cx24123_bandselect_val {
{
u32 freq_low; u32 freq_low;
u32 freq_high; u32 freq_high;
u32 VCOdivider; u32 VCOdivider;
...@@ -249,7 +252,8 @@ static int cx24123_i2c_writereg(struct cx24123_state *state, ...@@ -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); */ /* 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," printk("%s: writereg error(err == %i, reg == 0x%02x,"
" data == 0x%02x)\n", __func__, err, reg, data); " data == 0x%02x)\n", __func__, err, reg, data);
return err; return err;
...@@ -284,7 +288,8 @@ static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg) ...@@ -284,7 +288,8 @@ static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg)
#define cx24123_writereg(state, reg, val) \ #define cx24123_writereg(state, reg, val) \
cx24123_i2c_writereg(state, state->config->demod_address, 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 nom_reg = cx24123_readreg(state, 0x0e);
u8 auto_reg = cx24123_readreg(state, 0x10); u8 auto_reg = cx24123_readreg(state, 0x10);
...@@ -311,7 +316,8 @@ static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_invers ...@@ -311,7 +316,8 @@ static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_invers
return 0; 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; u8 val;
...@@ -328,18 +334,20 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers ...@@ -328,18 +334,20 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers
return 0; 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; 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; fec = FEC_AUTO;
/* Set the soft decision threshold */ /* Set the soft decision threshold */
if(fec == FEC_1_2) if (fec == FEC_1_2)
cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) | 0x01); cx24123_writereg(state, 0x43,
cx24123_readreg(state, 0x43) | 0x01);
else else
cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) & ~0x01); cx24123_writereg(state, 0x43,
cx24123_readreg(state, 0x43) & ~0x01);
switch (fec) { switch (fec) {
case FEC_1_2: case FEC_1_2:
...@@ -388,11 +396,11 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) ...@@ -388,11 +396,11 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
return 0; 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; int ret;
ret = cx24123_readreg (state, 0x1b); ret = cx24123_readreg(state, 0x1b);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = ret & 0x07; ret = ret & 0x07;
...@@ -433,16 +441,16 @@ static u32 cx24123_int_log2(u32 a, u32 b) ...@@ -433,16 +441,16 @@ static u32 cx24123_int_log2(u32 a, u32 b)
{ {
u32 exp, nearest = 0; u32 exp, nearest = 0;
u32 div = a / b; u32 div = a / b;
if(a % b >= b / 2) ++div; if (a % b >= b / 2)
if(div < (1 << 31)) ++div;
{ if (div < (1 << 31)) {
for(exp = 1; div > exp; nearest++) for (exp = 1; div > exp; nearest++)
exp += exp; exp += exp;
} }
return nearest; 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; u32 tmp, sample_rate, ratio, sample_gain;
u8 pll_mult; u8 pll_mult;
...@@ -498,9 +506,9 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) ...@@ -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, 0x01, pll_mult * 6);
cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f ); cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f);
cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff ); cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff);
cx24123_writereg(state, 0x0a, (ratio ) & 0xff ); cx24123_writereg(state, 0x0a, ratio & 0xff);
/* also set the demodulator sample gain */ /* also set the demodulator sample gain */
sample_gain = cx24123_int_log2(sample_rate, srate); sample_gain = cx24123_int_log2(sample_rate, srate);
...@@ -514,10 +522,12 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 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 * Based on the required frequency and symbolrate, the tuner AGC has
* and the correct band selected. Calculate those values * 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; struct cx24123_state *state = fe->demodulator_priv;
u32 ndiv = 0, adiv = 0, vco_div = 0; 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 ...@@ -525,6 +535,8 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
int pump = 2; int pump = 2;
int band = 0; int band = 0;
int num_bands = ARRAY_SIZE(cx24123_bandselect_vals); 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 */ /* Defaults for low freq, low rate */
state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
...@@ -532,58 +544,65 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa ...@@ -532,58 +544,65 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
state->bandselectarg = cx24123_bandselect_vals[0].progdata; state->bandselectarg = cx24123_bandselect_vals[0].progdata;
vco_div = cx24123_bandselect_vals[0].VCOdivider; vco_div = cx24123_bandselect_vals[0].VCOdivider;
/* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */ /* For the given symbol rate, determine the VCA, VGA and
for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) * 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) && agcv = &cx24123_AGC_vals[i];
(cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { if ((agcv->symbolrate_low <= p->u.qpsk.symbol_rate) &&
state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; (agcv->symbolrate_high >= p->u.qpsk.symbol_rate)) {
state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; state->VCAarg = agcv->VCAprogdata;
state->FILTune = cx24123_AGC_vals[i].FILTune; state->VGAarg = agcv->VGAprogdata;
state->FILTune = agcv->FILTune;
} }
} }
/* determine the band to use */ /* determine the band to use */
if(force_band < 1 || force_band > num_bands) if (force_band < 1 || force_band > num_bands) {
{ for (i = 0; i < num_bands; i++) {
for (i = 0; i < num_bands; i++) bsv = &cx24123_bandselect_vals[i];
{ if ((bsv->freq_low <= p->frequency) &&
if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && (bsv->freq_high >= p->frequency))
(cx24123_bandselect_vals[i].freq_high >= p->frequency) )
band = i; band = i;
} }
} } else
else
band = force_band - 1; band = force_band - 1;
state->bandselectarg = cx24123_bandselect_vals[band].progdata; state->bandselectarg = cx24123_bandselect_vals[band].progdata;
vco_div = cx24123_bandselect_vals[band].VCOdivider; vco_div = cx24123_bandselect_vals[band].VCOdivider;
/* determine the charge pump current */ /* 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; pump = 0x01;
else else
pump = 0x02; pump = 0x02;
/* Determine the N/A dividers for the requested lband freq (in kHz). */ /* 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 */ /* Note: the reference divider R=10, frequency is in KHz,
ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff; * XTAL is in Hz */
adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f; 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) if (adiv == 0 && ndiv > 0)
ndiv--; ndiv--;
/* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */ /* control bits 11, refdiv 11, charge pump polarity 1,
state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv; * charge pump current, ndiv, adiv */
state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) |
(pump << 14) | (ndiv << 5) | adiv;
return 0; return 0;
} }
/* /*
* Tuner data is 21 bits long, must be left-aligned in data. * 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; struct cx24123_state *state = fe->demodulator_priv;
unsigned long timeout; unsigned long timeout;
...@@ -610,7 +629,7 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par ...@@ -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 */ /* send another 8 bytes, wait for the send to be completed */
timeout = jiffies + msecs_to_jiffies(40); 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) { while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
if (time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
err("%s: demodulator is not responding, "\ err("%s: demodulator is not responding, "\
...@@ -620,9 +639,10 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par ...@@ -620,9 +639,10 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
msleep(10); 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); timeout = jiffies + msecs_to_jiffies(40);
cx24123_writereg(state, 0x22, (data) & 0xff ); cx24123_writereg(state, 0x22, (data) & 0xff);
while ((cx24123_readreg(state, 0x20) & 0x80)) { while ((cx24123_readreg(state, 0x20) & 0x80)) {
if (time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
err("%s: demodulator is not responding," \ err("%s: demodulator is not responding," \
...@@ -639,7 +659,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par ...@@ -639,7 +659,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
return 0; 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; struct cx24123_state *state = fe->demodulator_priv;
u8 val; u8 val;
...@@ -690,7 +711,7 @@ static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start) ...@@ -690,7 +711,7 @@ static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start)
return cx24123_writereg(state, 0x23, r); 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; struct cx24123_state *state = fe->demodulator_priv;
int i; int i;
...@@ -699,11 +720,13 @@ static int cx24123_initfe(struct dvb_frontend* fe) ...@@ -699,11 +720,13 @@ static int cx24123_initfe(struct dvb_frontend* fe)
/* Configure the demod to a good set of defaults */ /* Configure the demod to a good set of defaults */
for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++) 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 */ /* Set the LNB polarity */
if(state->config->lnb_polarity) if (state->config->lnb_polarity)
cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02); cx24123_writereg(state, 0x32,
cx24123_readreg(state, 0x32) | 0x02);
if (state->config->dont_use_pll) if (state->config->dont_use_pll)
cx24123_repeater_mode(state, 1, 0); cx24123_repeater_mode(state, 1, 0);
...@@ -711,7 +734,8 @@ static int cx24123_initfe(struct dvb_frontend* fe) ...@@ -711,7 +734,8 @@ static int cx24123_initfe(struct dvb_frontend* fe)
return 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; struct cx24123_state *state = fe->demodulator_priv;
u8 val; u8 val;
...@@ -740,7 +764,7 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state) ...@@ -740,7 +764,7 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
{ {
unsigned long timeout = jiffies + msecs_to_jiffies(200); unsigned long timeout = jiffies + msecs_to_jiffies(200);
while (!(cx24123_readreg(state, 0x29) & 0x40)) { while (!(cx24123_readreg(state, 0x29) & 0x40)) {
if(time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
err("%s: diseqc queue not ready, " \ err("%s: diseqc queue not ready, " \
"command may be lost.\n", __func__); "command may be lost.\n", __func__);
break; break;
...@@ -749,7 +773,8 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state) ...@@ -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; struct cx24123_state *state = fe->demodulator_priv;
int i, val, tone; int i, val, tone;
...@@ -771,20 +796,21 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma ...@@ -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]); cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
val = cx24123_readreg(state, 0x29); 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 */ /* wait for diseqc message to finish sending */
cx24123_wait_for_diseqc(state); cx24123_wait_for_diseqc(state);
/* restart continuous tone if enabled */ /* restart continuous tone if enabled */
if (tone & 0x10) { if (tone & 0x10)
cx24123_writereg(state, 0x29, tone & ~0x40); cx24123_writereg(state, 0x29, tone & ~0x40);
}
return 0; 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; struct cx24123_state *state = fe->demodulator_priv;
int val, tone; int val, tone;
...@@ -814,13 +840,13 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t ...@@ -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); cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
/* restart continuous tone if enabled */ /* restart continuous tone if enabled */
if (tone & 0x10) { if (tone & 0x10)
cx24123_writereg(state, 0x29, tone & ~0x40); cx24123_writereg(state, 0x29, tone & ~0x40);
}
return 0; 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; struct cx24123_state *state = fe->demodulator_priv;
int sync = cx24123_readreg(state, 0x14); int sync = cx24123_readreg(state, 0x14);
...@@ -853,8 +879,9 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) ...@@ -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 * Configured to return the measurement of errors in blocks,
* is available, so this value doubles up to satisfy both measurements * 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) 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, ...@@ -876,7 +903,8 @@ static int cx24123_read_signal_strength(struct dvb_frontend *fe,
{ {
struct cx24123_state *state = fe->demodulator_priv; 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); dprintk("Signal strength = %d\n", *signal_strength);
...@@ -907,7 +935,7 @@ static int cx24123_set_frontend(struct dvb_frontend *fe, ...@@ -907,7 +935,7 @@ static int cx24123_set_frontend(struct dvb_frontend *fe,
if (state->config->set_ts_params) if (state->config->set_ts_params)
state->config->set_ts_params(fe, 0); state->config->set_ts_params(fe, 0);
state->currentfreq=p->frequency; state->currentfreq = p->frequency;
state->currentsymbolrate = p->u.qpsk.symbol_rate; state->currentsymbolrate = p->u.qpsk.symbol_rate;
cx24123_set_inversion(state, p->inversion); cx24123_set_inversion(state, p->inversion);
...@@ -932,7 +960,8 @@ static int cx24123_set_frontend(struct dvb_frontend *fe, ...@@ -932,7 +960,8 @@ static int cx24123_set_frontend(struct dvb_frontend *fe,
return 0; 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; struct cx24123_state *state = fe->demodulator_priv;
...@@ -952,7 +981,7 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par ...@@ -952,7 +981,7 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
return 0; 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; struct cx24123_state *state = fe->demodulator_priv;
u8 val; u8 val;
...@@ -977,8 +1006,8 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) ...@@ -977,8 +1006,8 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
return 0; return 0;
} }
static int cx24123_tune(struct dvb_frontend* fe, static int cx24123_tune(struct dvb_frontend *fe,
struct dvb_frontend_parameters* params, struct dvb_frontend_parameters *params,
unsigned int mode_flags, unsigned int mode_flags,
unsigned int *delay, unsigned int *delay,
fe_status_t *status) fe_status_t *status)
...@@ -997,12 +1026,12 @@ static int cx24123_tune(struct dvb_frontend* fe, ...@@ -997,12 +1026,12 @@ static int cx24123_tune(struct dvb_frontend* fe,
static int cx24123_get_algo(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"); dprintk("\n");
i2c_del_adapter(&state->tuner_i2c_adapter); i2c_del_adapter(&state->tuner_i2c_adapter);
kfree(state); kfree(state);
...@@ -1037,8 +1066,8 @@ EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter); ...@@ -1037,8 +1066,8 @@ EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
static struct dvb_frontend_ops cx24123_ops; static struct dvb_frontend_ops cx24123_ops;
struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
struct i2c_adapter* i2c) struct i2c_adapter *i2c)
{ {
struct cx24123_state *state = struct cx24123_state *state =
kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
...@@ -1057,15 +1086,20 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, ...@@ -1057,15 +1086,20 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
/* check if the demod is there */ /* check if the demod is there */
state->demod_rev = cx24123_readreg(state, 0x00); state->demod_rev = cx24123_readreg(state, 0x00);
switch (state->demod_rev) { switch (state->demod_rev) {
case 0xe1: info("detected CX24123C\n"); break; case 0xe1:
case 0xd1: info("detected CX24123\n"); break; info("detected CX24123C\n");
break;
case 0xd1:
info("detected CX24123\n");
break;
default: default:
err("wrong demod revision: %x\n", state->demod_rev); err("wrong demod revision: %x\n", state->demod_rev);
goto error; goto error;
} }
/* create dvb_frontend */ /* 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; state->frontend.demodulator_priv = state;
/* create tuner i2c adapter */ /* create tuner i2c adapter */
...@@ -1090,6 +1124,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, ...@@ -1090,6 +1124,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
return NULL; return NULL;
} }
EXPORT_SYMBOL(cx24123_attach);
static struct dvb_frontend_ops cx24123_ops = { static struct dvb_frontend_ops cx24123_ops = {
...@@ -1126,15 +1161,8 @@ static struct dvb_frontend_ops cx24123_ops = { ...@@ -1126,15 +1161,8 @@ static struct dvb_frontend_ops cx24123_ops = {
.get_frontend_algo = cx24123_get_algo, .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 " \ MODULE_DESCRIPTION("DVB Frontend module for Conexant " \
"CX24123/CX24109/CX24113 hardware"); "CX24123/CX24109/CX24113 hardware");
MODULE_AUTHOR("Steven Toth"); MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
EXPORT_SYMBOL(cx24123_attach);
...@@ -23,13 +23,12 @@ ...@@ -23,13 +23,12 @@
#include <linux/dvb/frontend.h> #include <linux/dvb/frontend.h>
struct cx24123_config struct cx24123_config {
{
/* the demodulator's i2c address */ /* the demodulator's i2c address */
u8 demod_address; u8 demod_address;
/* Need to set device param for start_dma */ /* 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 */ /* 0 = LNB voltage normal, 1 = LNB voltage inverted */
int lnb_polarity; int lnb_polarity;
...@@ -39,7 +38,8 @@ struct cx24123_config ...@@ -39,7 +38,8 @@ struct cx24123_config
void (*agc_callback) (struct dvb_frontend *); 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, extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
struct i2c_adapter *i2c); struct i2c_adapter *i2c);
extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *); extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);
...@@ -56,6 +56,6 @@ static struct i2c_adapter * ...@@ -56,6 +56,6 @@ static struct i2c_adapter *
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL; return NULL;
} }
#endif // CONFIG_DVB_CX24123 #endif
#endif /* CX24123_H */ #endif /* CX24123_H */
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
struct s5h1409_state { struct s5h1409_state {
struct i2c_adapter* i2c; struct i2c_adapter *i2c;
/* configuration settings */ /* configuration settings */
const struct s5h1409_config* config; const struct s5h1409_config *config;
struct dvb_frontend frontend; struct dvb_frontend frontend;
...@@ -48,6 +48,9 @@ struct s5h1409_state { ...@@ -48,6 +48,9 @@ struct s5h1409_state {
}; };
static int debug; static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Enable verbose debug messages");
#define dprintk if (debug) printk #define dprintk if (debug) printk
/* Register values to initialise the demod, this will set VSB by default */ /* Register values to initialise the demod, this will set VSB by default */
...@@ -299,10 +302,10 @@ static struct qam256_snr_tab { ...@@ -299,10 +302,10 @@ static struct qam256_snr_tab {
}; };
/* 8 bit registers, 16 bit values */ /* 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; 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, struct i2c_msg msg = { .addr = state->config->demod_address,
.flags = 0, .buf = buf, .len = 3 }; .flags = 0, .buf = buf, .len = 3 };
...@@ -310,19 +313,19 @@ static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data) ...@@ -310,19 +313,19 @@ static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data)
ret = i2c_transfer(state->i2c, &msg, 1); ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 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); "ret == %i)\n", __func__, reg, data, ret);
return (ret != 1) ? -1 : 0; 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; int ret;
u8 b0 [] = { reg }; u8 b0[] = { reg };
u8 b1 [] = { 0, 0 }; u8 b1[] = { 0, 0 };
struct i2c_msg msg [] = { struct i2c_msg msg[] = {
{ .addr = state->config->demod_address, .flags = 0, { .addr = state->config->demod_address, .flags = 0,
.buf = b0, .len = 1 }, .buf = b0, .len = 1 },
{ .addr = state->config->demod_address, .flags = I2C_M_RD, { .addr = state->config->demod_address, .flags = I2C_M_RD,
...@@ -335,9 +338,9 @@ static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg) ...@@ -335,9 +338,9 @@ static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg)
return (b1[0] << 8) | b1[1]; 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__); dprintk("%s()\n", __func__);
...@@ -349,11 +352,11 @@ static int s5h1409_softreset(struct dvb_frontend* fe) ...@@ -349,11 +352,11 @@ static int s5h1409_softreset(struct dvb_frontend* fe)
} }
#define S5H1409_VSB_IF_FREQ 5380 #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); dprintk("%s(%d KHz)\n", __func__, KHz);
...@@ -376,26 +379,26 @@ static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz) ...@@ -376,26 +379,26 @@ static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
return 0; 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); dprintk("%s(%d)\n", __func__, inverted);
if(inverted == 1) if (inverted == 1)
return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */ return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
else else
return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */ 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) 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); dprintk("%s(0x%08x)\n", __func__, m);
switch(m) { switch (m) {
case VSB_8: case VSB_8:
dprintk("%s() VSB_8\n", __func__); dprintk("%s() VSB_8\n", __func__);
if (state->if_freq != S5H1409_VSB_IF_FREQ) if (state->if_freq != S5H1409_VSB_IF_FREQ)
...@@ -422,9 +425,9 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe, ...@@ -422,9 +425,9 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe,
return 0; 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); dprintk("%s(%d)\n", __func__, enable);
...@@ -434,9 +437,9 @@ static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) ...@@ -434,9 +437,9 @@ static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
return s5h1409_writereg(state, 0xf3, 0); 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); dprintk("%s(%d)\n", __func__, enable);
...@@ -448,18 +451,18 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable) ...@@ -448,18 +451,18 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
s5h1409_readreg(state, 0xe3) & 0xfeff); 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); dprintk("%s(%d)\n", __func__, enable);
return s5h1409_writereg(state, 0xf2, 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__); dprintk("%s()\n", __func__);
...@@ -483,7 +486,7 @@ static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe) ...@@ -483,7 +486,7 @@ static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe)
reg &= 0xff; reg &= 0xff;
s5h1409_writereg(state, 0x96, 0x00c); s5h1409_writereg(state, 0x96, 0x00c);
if ((reg < 0x38) || (reg > 0x68) ) { if ((reg < 0x38) || (reg > 0x68)) {
s5h1409_writereg(state, 0x93, 0x3332); s5h1409_writereg(state, 0x93, 0x3332);
s5h1409_writereg(state, 0x9e, 0x2c37); s5h1409_writereg(state, 0x9e, 0x2c37);
} else { } else {
...@@ -514,7 +517,7 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) ...@@ -514,7 +517,7 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
s5h1409_writereg(state, 0x96, 0x20); s5h1409_writereg(state, 0x96, 0x20);
s5h1409_writereg(state, 0xad, s5h1409_writereg(state, 0xad,
( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) ); (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
s5h1409_writereg(state, 0xab, s5h1409_writereg(state, 0xab,
s5h1409_readreg(state, 0xab) & 0xeffe); s5h1409_readreg(state, 0xab) & 0xeffe);
} }
...@@ -529,10 +532,10 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) ...@@ -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 */ /* 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 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); dprintk("%s(frequency=%d)\n", __func__, p->frequency);
...@@ -546,9 +549,11 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe, ...@@ -546,9 +549,11 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe,
msleep(100); msleep(100);
if (fe->ops.tuner_ops.set_params) { 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); 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 */ /* Optimize the demod for QAM */
...@@ -592,17 +597,17 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode) ...@@ -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 /* Reset the demod hardware and reset all of the configuration registers
to a default state. */ to a default state. */
static int s5h1409_init (struct dvb_frontend* fe) static int s5h1409_init(struct dvb_frontend *fe)
{ {
int i; int i;
struct s5h1409_state* state = fe->demodulator_priv; struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__); dprintk("%s()\n", __func__);
s5h1409_sleep(fe, 0); s5h1409_sleep(fe, 0);
s5h1409_register_reset(fe); 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); s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data);
/* The datasheet says that after initialisation, VSB is default */ /* The datasheet says that after initialisation, VSB is default */
...@@ -627,9 +632,9 @@ static int s5h1409_init (struct dvb_frontend* fe) ...@@ -627,9 +632,9 @@ static int s5h1409_init (struct dvb_frontend* fe)
return 0; 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; u16 reg;
u32 tuner_status = 0; u32 tuner_status = 0;
...@@ -637,12 +642,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status) ...@@ -637,12 +642,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
/* Get the demodulator status */ /* Get the demodulator status */
reg = s5h1409_readreg(state, 0xf1); reg = s5h1409_readreg(state, 0xf1);
if(reg & 0x1000) if (reg & 0x1000)
*status |= FE_HAS_VITERBI; *status |= FE_HAS_VITERBI;
if(reg & 0x8000) if (reg & 0x8000)
*status |= FE_HAS_LOCK | FE_HAS_SYNC; *status |= FE_HAS_LOCK | FE_HAS_SYNC;
switch(state->config->status_mode) { switch (state->config->status_mode) {
case S5H1409_DEMODLOCKING: case S5H1409_DEMODLOCKING:
if (*status & FE_HAS_VITERBI) if (*status & FE_HAS_VITERBI)
*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
...@@ -668,12 +673,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status) ...@@ -668,12 +673,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
return 0; 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; int i, ret = -EINVAL;
dprintk("%s()\n", __func__); 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) { if (v < qam256_snr_tab[i].val) {
*snr = qam256_snr_tab[i].data; *snr = qam256_snr_tab[i].data;
ret = 0; ret = 0;
...@@ -683,12 +688,12 @@ static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) ...@@ -683,12 +688,12 @@ static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
return ret; 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; int i, ret = -EINVAL;
dprintk("%s()\n", __func__); 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) { if (v < qam64_snr_tab[i].val) {
*snr = qam64_snr_tab[i].data; *snr = qam64_snr_tab[i].data;
ret = 0; ret = 0;
...@@ -698,12 +703,12 @@ static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) ...@@ -698,12 +703,12 @@ static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
return ret; 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; int i, ret = -EINVAL;
dprintk("%s()\n", __func__); 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) { if (v > vsb_snr_tab[i].val) {
*snr = vsb_snr_tab[i].data; *snr = vsb_snr_tab[i].data;
ret = 0; ret = 0;
...@@ -714,13 +719,13 @@ static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) ...@@ -714,13 +719,13 @@ static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
return ret; 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; u16 reg;
dprintk("%s()\n", __func__); dprintk("%s()\n", __func__);
switch(state->current_modulation) { switch (state->current_modulation) {
case QAM_64: case QAM_64:
reg = s5h1409_readreg(state, 0xf0) & 0xff; reg = s5h1409_readreg(state, 0xf0) & 0xff;
return s5h1409_qam64_lookup_snr(fe, snr, reg); return s5h1409_qam64_lookup_snr(fe, snr, reg);
...@@ -737,30 +742,30 @@ static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr) ...@@ -737,30 +742,30 @@ static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr)
return -EINVAL; return -EINVAL;
} }
static int s5h1409_read_signal_strength(struct dvb_frontend* fe, static int s5h1409_read_signal_strength(struct dvb_frontend *fe,
u16* signal_strength) u16 *signal_strength)
{ {
return s5h1409_read_snr(fe, 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); *ucblocks = s5h1409_readreg(state, 0xb5);
return 0; 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); 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 dvb_frontend_parameters *p)
{ {
struct s5h1409_state* state = fe->demodulator_priv; struct s5h1409_state *state = fe->demodulator_priv;
p->frequency = state->current_frequency; p->frequency = state->current_frequency;
p->u.vsb.modulation = state->current_modulation; p->u.vsb.modulation = state->current_modulation;
...@@ -768,25 +773,25 @@ static int s5h1409_get_frontend(struct dvb_frontend* fe, ...@@ -768,25 +773,25 @@ static int s5h1409_get_frontend(struct dvb_frontend* fe,
return 0; 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) struct dvb_frontend_tune_settings *tune)
{ {
tune->min_delay_ms = 1000; tune->min_delay_ms = 1000;
return 0; 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); kfree(state);
} }
static struct dvb_frontend_ops s5h1409_ops; static struct dvb_frontend_ops s5h1409_ops;
struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
struct i2c_adapter* i2c) struct i2c_adapter *i2c)
{ {
struct s5h1409_state* state = NULL; struct s5h1409_state *state = NULL;
u16 reg; u16 reg;
/* allocate memory for the internal state */ /* allocate memory for the internal state */
...@@ -825,6 +830,7 @@ struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, ...@@ -825,6 +830,7 @@ struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
kfree(state); kfree(state);
return NULL; return NULL;
} }
EXPORT_SYMBOL(s5h1409_attach);
static struct dvb_frontend_ops s5h1409_ops = { static struct dvb_frontend_ops s5h1409_ops = {
...@@ -850,14 +856,10 @@ static struct dvb_frontend_ops s5h1409_ops = { ...@@ -850,14 +856,10 @@ static struct dvb_frontend_ops s5h1409_ops = {
.release = s5h1409_release, .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_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver");
MODULE_AUTHOR("Steven Toth"); MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
EXPORT_SYMBOL(s5h1409_attach);
/* /*
* Local variables: * Local variables:
......
...@@ -24,8 +24,7 @@ ...@@ -24,8 +24,7 @@
#include <linux/dvb/frontend.h> #include <linux/dvb/frontend.h>
struct s5h1409_config struct s5h1409_config {
{
/* the demodulator's i2c address */ /* the demodulator's i2c address */
u8 demod_address; u8 demod_address;
...@@ -60,12 +59,14 @@ struct s5h1409_config ...@@ -60,12 +59,14 @@ struct s5h1409_config
u16 mpeg_timing; u16 mpeg_timing;
}; };
#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) && defined(MODULE)) #if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
extern struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, && defined(MODULE))
struct i2c_adapter* i2c); extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
struct i2c_adapter *i2c);
#else #else
static inline struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, static inline struct dvb_frontend *s5h1409_attach(
struct i2c_adapter* i2c) const struct s5h1409_config *config,
struct i2c_adapter *i2c)
{ {
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL; return NULL;
......
...@@ -343,7 +343,7 @@ static int s5h1411_writereg(struct s5h1411_state *state, ...@@ -343,7 +343,7 @@ static int s5h1411_writereg(struct s5h1411_state *state,
u8 addr, u8 reg, u16 data) u8 addr, u8 reg, u16 data)
{ {
int ret; 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 }; struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
...@@ -359,10 +359,10 @@ static int s5h1411_writereg(struct s5h1411_state *state, ...@@ -359,10 +359,10 @@ static int s5h1411_writereg(struct s5h1411_state *state,
static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg) static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg)
{ {
int ret; int ret;
u8 b0 [] = { reg }; u8 b0[] = { reg };
u8 b1 [] = { 0, 0 }; u8 b1[] = { 0, 0 };
struct i2c_msg msg [] = { struct i2c_msg msg[] = {
{ .addr = addr, .flags = 0, .buf = b0, .len = 1 }, { .addr = addr, .flags = 0, .buf = b0, .len = 1 },
{ .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
......
...@@ -195,7 +195,7 @@ static struct init_tab { ...@@ -195,7 +195,7 @@ static struct init_tab {
static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
{ {
int ret; int ret;
u8 buf [] = { reg, data }; u8 buf[] = { reg, data };
struct i2c_msg msg = { struct i2c_msg msg = {
.addr = state->config->demod_address, .addr = state->config->demod_address,
.flags = 0, .buf = buf, .len = 2 }; .flags = 0, .buf = buf, .len = 2 };
...@@ -213,9 +213,9 @@ static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) ...@@ -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) static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
{ {
int ret; int ret;
u8 b0 [] = { reg }; u8 b0[] = { reg };
u8 b1 [] = { 0 }; u8 b1[] = { 0 };
struct i2c_msg msg [] = { struct i2c_msg msg[] = {
{ .addr = state->config->demod_address, { .addr = state->config->demod_address,
.flags = 0, .buf = b0, .len = 1 }, .flags = 0, .buf = b0, .len = 1 },
{ .addr = state->config->demod_address, { .addr = state->config->demod_address,
...@@ -393,43 +393,89 @@ static int tda10048_get_tps(struct tda10048_state *state, ...@@ -393,43 +393,89 @@ static int tda10048_get_tps(struct tda10048_state *state,
val = tda10048_readreg(state, TDA10048_OUT_CONF2); val = tda10048_readreg(state, TDA10048_OUT_CONF2);
switch ((val & 0x60) >> 5) { switch ((val & 0x60) >> 5) {
case 0: p->constellation = QPSK; break; case 0:
case 1: p->constellation = QAM_16; break; p->constellation = QPSK;
case 2: p->constellation = QAM_64; break; break;
case 1:
p->constellation = QAM_16;
break;
case 2:
p->constellation = QAM_64;
break;
} }
switch ((val & 0x18) >> 3) { switch ((val & 0x18) >> 3) {
case 0: p->hierarchy_information = HIERARCHY_NONE; break; case 0:
case 1: p->hierarchy_information = HIERARCHY_1; break; p->hierarchy_information = HIERARCHY_NONE;
case 2: p->hierarchy_information = HIERARCHY_2; break; break;
case 3: p->hierarchy_information = HIERARCHY_4; 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) { switch (val & 0x07) {
case 0: p->code_rate_HP = FEC_1_2; break; case 0:
case 1: p->code_rate_HP = FEC_2_3; break; p->code_rate_HP = FEC_1_2;
case 2: p->code_rate_HP = FEC_3_4; break; break;
case 3: p->code_rate_HP = FEC_5_6; break; case 1:
case 4: p->code_rate_HP = FEC_7_8; break; 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); val = tda10048_readreg(state, TDA10048_OUT_CONF3);
switch (val & 0x07) { switch (val & 0x07) {
case 0: p->code_rate_LP = FEC_1_2; break; case 0:
case 1: p->code_rate_LP = FEC_2_3; break; p->code_rate_LP = FEC_1_2;
case 2: p->code_rate_LP = FEC_3_4; break; break;
case 3: p->code_rate_LP = FEC_5_6; break; case 1:
case 4: p->code_rate_LP = FEC_7_8; break; 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); val = tda10048_readreg(state, TDA10048_OUT_CONF1);
switch ((val & 0x0c) >> 2) { switch ((val & 0x0c) >> 2) {
case 0: p->guard_interval = GUARD_INTERVAL_1_32; break; case 0:
case 1: p->guard_interval = GUARD_INTERVAL_1_16; break; p->guard_interval = GUARD_INTERVAL_1_32;
case 2: p->guard_interval = GUARD_INTERVAL_1_8; break; break;
case 3: p->guard_interval = GUARD_INTERVAL_1_4; 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) { switch (val & 0x02) {
case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break; case 0:
case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break; p->transmission_mode = TRANSMISSION_MODE_2K;
break;
case 1:
p->transmission_mode = TRANSMISSION_MODE_8K;
break;
} }
return 0; return 0;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#ifndef Z0194A #ifndef Z0194A
#define 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) u32 srate, u32 ratio)
{ {
u8 aclk = 0; u8 aclk = 0;
...@@ -40,7 +40,7 @@ static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe, ...@@ -40,7 +40,7 @@ static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe,
return 0; return 0;
} }
static u8 sharp_z0194a__inittab[] = { static u8 sharp_z0194a_inittab[] = {
0x01, 0x15, 0x01, 0x15,
0x02, 0x00, 0x02, 0x00,
0x03, 0x00, 0x03, 0x00,
...@@ -82,16 +82,4 @@ static u8 sharp_z0194a__inittab[] = { ...@@ -82,16 +82,4 @@ static u8 sharp_z0194a__inittab[] = {
0xff, 0xff 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 #endif
...@@ -42,6 +42,10 @@ struct usb_device_id smsusb_id_table[] = { ...@@ -42,6 +42,10 @@ struct usb_device_id smsusb_id_table[] = {
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ USB_DEVICE(0x2040, 0x5510), { USB_DEVICE(0x2040, 0x5510),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, .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), { USB_DEVICE(0x2040, 0x5580),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ USB_DEVICE(0x2040, 0x5590), { USB_DEVICE(0x2040, 0x5590),
......
...@@ -359,7 +359,7 @@ config USB_SI470X ...@@ -359,7 +359,7 @@ config USB_SI470X
computer's USB port. computer's USB port.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called radio-silabs. module will be called radio-si470x.
config USB_MR800 config USB_MR800
tristate "AverMedia MR 800 USB FM radio support" tristate "AverMedia MR 800 USB FM radio support"
......
...@@ -104,6 +104,7 @@ ...@@ -104,6 +104,7 @@
* - hardware frequency seek support * - hardware frequency seek support
* - afc indication * - afc indication
* - more safety checks, let si470x_get_freq return errno * - more safety checks, let si470x_get_freq return errno
* - vidioc behavior corrected according to v4l2 spec
* *
* ToDo: * ToDo:
* - add firmware download/update support * - add firmware download/update support
...@@ -157,7 +158,7 @@ MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table); ...@@ -157,7 +158,7 @@ MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
/* Radio Nr */ /* Radio Nr */
static int radio_nr = -1; static int radio_nr = -1;
module_param(radio_nr, int, 0); module_param(radio_nr, int, 0444);
MODULE_PARM_DESC(radio_nr, "Radio Nr"); MODULE_PARM_DESC(radio_nr, "Radio Nr");
/* Spacing (kHz) */ /* Spacing (kHz) */
...@@ -165,42 +166,42 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr"); ...@@ -165,42 +166,42 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr");
/* 1: 100 kHz (Europe, Japan) */ /* 1: 100 kHz (Europe, Japan) */
/* 2: 50 kHz */ /* 2: 50 kHz */
static unsigned short space = 2; static unsigned short space = 2;
module_param(space, ushort, 0); module_param(space, ushort, 0444);
MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*"); MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
/* Bottom of Band (MHz) */ /* Bottom of Band (MHz) */
/* 0: 87.5 - 108 MHz (USA, Europe)*/ /* 0: 87.5 - 108 MHz (USA, Europe)*/
/* 1: 76 - 108 MHz (Japan wide band) */ /* 1: 76 - 108 MHz (Japan wide band) */
/* 2: 76 - 90 MHz (Japan) */ /* 2: 76 - 90 MHz (Japan) */
static unsigned short band = 1; static unsigned short band = 1;
module_param(band, ushort, 0); module_param(band, ushort, 0444);
MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz"); MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
/* De-emphasis */ /* De-emphasis */
/* 0: 75 us (USA) */ /* 0: 75 us (USA) */
/* 1: 50 us (Europe, Australia, Japan) */ /* 1: 50 us (Europe, Australia, Japan) */
static unsigned short de = 1; static unsigned short de = 1;
module_param(de, ushort, 0); module_param(de, ushort, 0444);
MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*"); MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*");
/* USB timeout */ /* USB timeout */
static unsigned int usb_timeout = 500; 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*"); MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
/* Tune timeout */ /* Tune timeout */
static unsigned int tune_timeout = 3000; 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*"); MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
/* Seek timeout */ /* Seek timeout */
static unsigned int seek_timeout = 5000; 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*"); MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
/* RDS buffer blocks */ /* RDS buffer blocks */
static unsigned int rds_buf = 100; 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*"); MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
/* RDS maximum block errors */ /* RDS maximum block errors */
...@@ -209,7 +210,7 @@ static unsigned short max_rds_errors = 1; ...@@ -209,7 +210,7 @@ static unsigned short max_rds_errors = 1;
/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */ /* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
/* 2 means 3-5 errors requiring correction */ /* 2 means 3-5 errors requiring correction */
/* 3 means 6+ errors or errors in checkword, correction not possible */ /* 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*"); MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
/* RDS poll frequency */ /* RDS poll frequency */
...@@ -218,7 +219,7 @@ static unsigned int rds_poll_time = 40; ...@@ -218,7 +219,7 @@ static unsigned int rds_poll_time = 40;
/* 50 is used by radio-cadet */ /* 50 is used by radio-cadet */
/* 75 should be okay */ /* 75 should be okay */
/* 80 is the usual RDS receive interval */ /* 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*"); 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) ...@@ -667,23 +668,29 @@ static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
int retval; int retval;
/* Spacing (kHz) */ /* Spacing (kHz) */
switch (space) { switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
/* 0: 200 kHz (USA, Australia) */ /* 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) */ /* 1: 100 kHz (Europe, Japan) */
case 1 : spacing = 0.100 * FREQ_MUL; break; case 1:
spacing = 0.100 * FREQ_MUL; break;
/* 2: 50 kHz */ /* 2: 50 kHz */
default: spacing = 0.050 * FREQ_MUL; break; default:
spacing = 0.050 * FREQ_MUL; break;
}; };
/* Bottom of Band (MHz) */ /* Bottom of Band (MHz) */
switch (band) { switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
/* 0: 87.5 - 108 MHz (USA, Europe) */ /* 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) */ /* 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) */ /* 2: 76 - 90 MHz (Japan) */
case 2 : band_bottom = 76 * FREQ_MUL; break; case 2:
band_bottom = 76 * FREQ_MUL; break;
}; };
/* read channel */ /* read channel */
...@@ -706,23 +713,29 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq) ...@@ -706,23 +713,29 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
unsigned short chan; unsigned short chan;
/* Spacing (kHz) */ /* Spacing (kHz) */
switch (space) { switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
/* 0: 200 kHz (USA, Australia) */ /* 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) */ /* 1: 100 kHz (Europe, Japan) */
case 1 : spacing = 0.100 * FREQ_MUL; break; case 1:
spacing = 0.100 * FREQ_MUL; break;
/* 2: 50 kHz */ /* 2: 50 kHz */
default: spacing = 0.050 * FREQ_MUL; break; default:
spacing = 0.050 * FREQ_MUL; break;
}; };
/* Bottom of Band (MHz) */ /* Bottom of Band (MHz) */
switch (band) { switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
/* 0: 87.5 - 108 MHz (USA, Europe) */ /* 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) */ /* 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) */ /* 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) */ /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */
...@@ -1164,7 +1177,6 @@ static const struct file_operations si470x_fops = { ...@@ -1164,7 +1177,6 @@ static const struct file_operations si470x_fops = {
* si470x_v4l2_queryctrl - query control * si470x_v4l2_queryctrl - query control
*/ */
static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { 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, .id = V4L2_CID_AUDIO_VOLUME,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
...@@ -1174,18 +1186,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { ...@@ -1174,18 +1186,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
.step = 1, .step = 1,
.default_value = 15, .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, .id = V4L2_CID_AUDIO_MUTE,
.type = V4L2_CTRL_TYPE_BOOLEAN, .type = V4L2_CTRL_TYPE_BOOLEAN,
...@@ -1195,10 +1195,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = { ...@@ -1195,10 +1195,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
.step = 1, .step = 1,
.default_value = 1, .default_value = 1,
}, },
{
.id = V4L2_CID_AUDIO_LOUDNESS,
.flags = V4L2_CTRL_FLAG_DISABLED,
},
}; };
...@@ -1219,57 +1215,35 @@ static int si470x_vidioc_querycap(struct file *file, void *priv, ...@@ -1219,57 +1215,35 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
} }
/*
* si470x_vidioc_g_input - get input
*/
static int si470x_vidioc_g_input(struct file *file, void *priv,
unsigned int *i)
{
*i = 0;
return 0;
}
/*
* si470x_vidioc_s_input - set input
*/
static int si470x_vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
int retval = 0;
/* safety checks */
if (i != 0)
retval = -EINVAL;
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME
": set input failed with %d\n", retval);
return retval;
}
/* /*
* si470x_vidioc_queryctrl - enumerate control items * si470x_vidioc_queryctrl - enumerate control items
*/ */
static int si470x_vidioc_queryctrl(struct file *file, void *priv, static int si470x_vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc) struct v4l2_queryctrl *qc)
{ {
unsigned char i; unsigned char i = 0;
int retval = -EINVAL; int retval = -EINVAL;
/* safety checks */ /* abort if qc->id is below V4L2_CID_BASE */
if (!qc->id) if (qc->id < V4L2_CID_BASE)
goto done; goto done;
/* search video control */
for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
if (qc->id == si470x_v4l2_queryctrl[i].id) { if (qc->id == si470x_v4l2_queryctrl[i].id) {
memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
retval = 0; retval = 0; /* found */
break; 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: done:
if (retval < 0) if (retval < 0)
printk(KERN_WARNING DRIVER_NAME printk(KERN_WARNING DRIVER_NAME
...@@ -1360,44 +1334,13 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, ...@@ -1360,44 +1334,13 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
static int si470x_vidioc_g_audio(struct file *file, void *priv, static int si470x_vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *audio) struct v4l2_audio *audio)
{ {
int retval = 0; /* driver constants */
audio->index = 0;
/* safety checks */
if (audio->index != 0) {
retval = -EINVAL;
goto done;
}
strcpy(audio->name, "Radio"); strcpy(audio->name, "Radio");
audio->capability = V4L2_AUDCAP_STEREO; audio->capability = V4L2_AUDCAP_STEREO;
audio->mode = 0;
done: return 0;
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;
} }
...@@ -1415,7 +1358,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, ...@@ -1415,7 +1358,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
retval = -EIO; retval = -EIO;
goto done; goto done;
} }
if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { if (tuner->index != 0) {
retval = -EINVAL; retval = -EINVAL;
goto done; goto done;
} }
...@@ -1424,8 +1367,13 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, ...@@ -1424,8 +1367,13 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
if (retval < 0) if (retval < 0)
goto done; goto done;
/* driver constants */
strcpy(tuner->name, "FM"); 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) */ /* 0: 87.5 - 108 MHz (USA, Europe, default) */
default: default:
tuner->rangelow = 87.5 * FREQ_MUL; tuner->rangelow = 87.5 * FREQ_MUL;
...@@ -1442,14 +1390,18 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, ...@@ -1442,14 +1390,18 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
tuner->rangehigh = 90 * FREQ_MUL; tuner->rangehigh = 90 * FREQ_MUL;
break; 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) if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1)
tuner->audmode = V4L2_TUNER_MODE_STEREO; tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
else else
tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
/* mono/stereo selector */
if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1)
tuner->audmode = V4L2_TUNER_MODE_MONO; 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 */ /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI) tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI)
...@@ -1474,22 +1426,27 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, ...@@ -1474,22 +1426,27 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner) struct v4l2_tuner *tuner)
{ {
struct si470x_device *radio = video_drvdata(file); struct si470x_device *radio = video_drvdata(file);
int retval = 0; int retval = -EINVAL;
/* safety checks */ /* safety checks */
if (radio->disconnected) { if (radio->disconnected) {
retval = -EIO; retval = -EIO;
goto done; goto done;
} }
if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { if (tuner->index != 0)
retval = -EINVAL;
goto done; 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 */ radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */
else break;
case V4L2_TUNER_MODE_STEREO:
radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
break;
default:
goto done;
}
retval = si470x_set_register(radio, POWERCFG); retval = si470x_set_register(radio, POWERCFG);
...@@ -1515,11 +1472,12 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, ...@@ -1515,11 +1472,12 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv,
retval = -EIO; retval = -EIO;
goto done; goto done;
} }
if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { if (freq->tuner != 0) {
retval = -EINVAL; retval = -EINVAL;
goto done; goto done;
} }
freq->type = V4L2_TUNER_RADIO;
retval = si470x_get_freq(radio, &freq->frequency); retval = si470x_get_freq(radio, &freq->frequency);
done: done:
...@@ -1544,7 +1502,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, ...@@ -1544,7 +1502,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
retval = -EIO; retval = -EIO;
goto done; goto done;
} }
if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { if (freq->tuner != 0) {
retval = -EINVAL; retval = -EINVAL;
goto done; goto done;
} }
...@@ -1573,7 +1531,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, ...@@ -1573,7 +1531,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
retval = -EIO; retval = -EIO;
goto done; goto done;
} }
if ((seek->tuner != 0) && (seek->type != V4L2_TUNER_RADIO)) { if (seek->tuner != 0) {
retval = -EINVAL; retval = -EINVAL;
goto done; goto done;
} }
...@@ -1588,15 +1546,16 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, ...@@ -1588,15 +1546,16 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
return retval; return retval;
} }
/*
* si470x_ioctl_ops - video device ioctl operations
*/
static const struct v4l2_ioctl_ops si470x_ioctl_ops = { static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
.vidioc_querycap = si470x_vidioc_querycap, .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_queryctrl = si470x_vidioc_queryctrl,
.vidioc_g_ctrl = si470x_vidioc_g_ctrl, .vidioc_g_ctrl = si470x_vidioc_g_ctrl,
.vidioc_s_ctrl = si470x_vidioc_s_ctrl, .vidioc_s_ctrl = si470x_vidioc_s_ctrl,
.vidioc_g_audio = si470x_vidioc_g_audio, .vidioc_g_audio = si470x_vidioc_g_audio,
.vidioc_s_audio = si470x_vidioc_s_audio,
.vidioc_g_tuner = si470x_vidioc_g_tuner, .vidioc_g_tuner = si470x_vidioc_g_tuner,
.vidioc_s_tuner = si470x_vidioc_s_tuner, .vidioc_s_tuner = si470x_vidioc_s_tuner,
.vidioc_g_frequency = si470x_vidioc_g_frequency, .vidioc_g_frequency = si470x_vidioc_g_frequency,
...@@ -1604,14 +1563,15 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = { ...@@ -1604,14 +1563,15 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
.vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, .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 = { static struct video_device si470x_viddev_template = {
.fops = &si470x_fops, .fops = &si470x_fops,
.ioctl_ops = &si470x_ioctl_ops,
.name = DRIVER_NAME, .name = DRIVER_NAME,
.release = video_device_release, .release = video_device_release,
.ioctl_ops = &si470x_ioctl_ops,
}; };
......
...@@ -29,43 +29,24 @@ ...@@ -29,43 +29,24 @@
*/ */
#include <linux/module.h> #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/types.h>
#include <linux/i2c.h> #include <linux/ioctl.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/videodev.h> #include <linux/videodev.h>
#include <linux/video_encoder.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_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
MODULE_AUTHOR("Maxim Yevtyushkin"); MODULE_AUTHOR("Maxim Yevtyushkin");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#define I2C_NAME(x) (x)->name
static int debug; static int debug;
module_param(debug, int, 0); module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)"); MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define dprintk(num, format, args...) \
do { \
if (debug >= num) \
printk(format, ##args); \
} while (0)
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
struct adv7170 { struct adv7170 {
...@@ -80,21 +61,12 @@ struct adv7170 { ...@@ -80,21 +61,12 @@ struct adv7170 {
int sat; 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 *inputs[] = { "pass_through", "play_back" };
static char *norms[] = { "PAL", "NTSC" }; static char *norms[] = { "PAL", "NTSC" };
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static inline int static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value)
adv7170_write (struct i2c_client *client,
u8 reg,
u8 value)
{ {
struct adv7170 *encoder = i2c_get_clientdata(client); struct adv7170 *encoder = i2c_get_clientdata(client);
...@@ -102,17 +74,13 @@ adv7170_write (struct i2c_client *client, ...@@ -102,17 +74,13 @@ adv7170_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value); return i2c_smbus_write_byte_data(client, reg, value);
} }
static inline int static inline int adv7170_read(struct i2c_client *client, u8 reg)
adv7170_read (struct i2c_client *client,
u8 reg)
{ {
return i2c_smbus_read_byte_data(client, reg); return i2c_smbus_read_byte_data(client, reg);
} }
static int static int adv7170_write_block(struct i2c_client *client,
adv7170_write_block (struct i2c_client *client, const u8 *data, unsigned int len)
const u8 *data,
unsigned int len)
{ {
int ret = -1; int ret = -1;
u8 reg; u8 reg;
...@@ -133,33 +101,25 @@ adv7170_write_block (struct i2c_client *client, ...@@ -133,33 +101,25 @@ adv7170_write_block (struct i2c_client *client,
encoder->reg[reg++] = data[1]; encoder->reg[reg++] = data[1];
len -= 2; len -= 2;
data += 2; data += 2;
} while (len >= 2 && data[0] == reg && } while (len >= 2 && data[0] == reg && block_len < 32);
block_len < 32); ret = i2c_master_send(client, block_data, block_len);
if ((ret = i2c_master_send(client, block_data, if (ret < 0)
block_len)) < 0)
break; break;
} }
} else { } else {
/* do some slow I2C emulation kind of thing */ /* do some slow I2C emulation kind of thing */
while (len >= 2) { while (len >= 2) {
reg = *data++; reg = *data++;
if ((ret = adv7170_write(client, reg, ret = adv7170_write(client, reg, *data++);
*data++)) < 0) if (ret < 0)
break; break;
len -= 2; len -= 2;
} }
} }
return ret; return ret;
} }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
// Output filter: S-Video Composite
#define MR050 0x11 //0x09
#define MR060 0x14 //0x0c
//---------------------------------------------------------------------------
#define TR0MODE 0x4c #define TR0MODE 0x4c
#define TR0RST 0x80 #define TR0RST 0x80
...@@ -167,7 +127,6 @@ adv7170_write_block (struct i2c_client *client, ...@@ -167,7 +127,6 @@ adv7170_write_block (struct i2c_client *client,
#define TR1CAPT 0x00 #define TR1CAPT 0x00
#define TR1PLAY 0x00 #define TR1PLAY 0x00
static const unsigned char init_NTSC[] = { static const unsigned char init_NTSC[] = {
0x00, 0x10, // MR0 0x00, 0x10, // MR0
0x01, 0x20, // MR1 0x01, 0x20, // MR1
...@@ -227,15 +186,11 @@ static const unsigned char init_PAL[] = { ...@@ -227,15 +186,11 @@ static const unsigned char init_PAL[] = {
}; };
static int static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
adv7170_command (struct i2c_client *client,
unsigned int cmd,
void * arg)
{ {
struct adv7170 *encoder = i2c_get_clientdata(client); struct adv7170 *encoder = i2c_get_clientdata(client);
switch (cmd) { switch (cmd) {
case 0: case 0:
#if 0 #if 0
/* This is just for testing!!! */ /* This is just for testing!!! */
...@@ -254,18 +209,16 @@ adv7170_command (struct i2c_client *client, ...@@ -254,18 +209,16 @@ adv7170_command (struct i2c_client *client,
VIDEO_ENCODER_NTSC; VIDEO_ENCODER_NTSC;
cap->inputs = 2; cap->inputs = 2;
cap->outputs = 1; cap->outputs = 1;
}
break; break;
}
case ENCODER_SET_NORM: case ENCODER_SET_NORM:
{ {
int iarg = *(int *) arg; int iarg = *(int *) arg;
dprintk(1, KERN_DEBUG "%s_command: set norm %d", v4l_dbg(1, debug, client, "set norm %d\n", iarg);
I2C_NAME(client), iarg);
switch (iarg) { switch (iarg) {
case VIDEO_MODE_NTSC: case VIDEO_MODE_NTSC:
adv7170_write_block(client, init_NTSC, adv7170_write_block(client, init_NTSC,
sizeof(init_NTSC)); sizeof(init_NTSC));
...@@ -285,16 +238,13 @@ adv7170_command (struct i2c_client *client, ...@@ -285,16 +238,13 @@ adv7170_command (struct i2c_client *client,
break; break;
default: default:
dprintk(1, KERN_ERR "%s: illegal norm: %d\n", v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
I2C_NAME(client), iarg);
return -EINVAL; return -EINVAL;
} }
dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client), v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
norms[iarg]);
encoder->norm = iarg; encoder->norm = iarg;
}
break; break;
}
case ENCODER_SET_INPUT: case ENCODER_SET_INPUT:
{ {
...@@ -304,19 +254,17 @@ adv7170_command (struct i2c_client *client, ...@@ -304,19 +254,17 @@ adv7170_command (struct i2c_client *client,
*iarg = 1: input is from ZR36060 *iarg = 1: input is from ZR36060
*iarg = 2: color bar */ *iarg = 2: color bar */
dprintk(1, KERN_DEBUG "%s_command: set input from %s\n", v4l_dbg(1, debug, client, "set input from %s\n",
I2C_NAME(client),
iarg == 0 ? "decoder" : "ZR36060"); iarg == 0 ? "decoder" : "ZR36060");
switch (iarg) { switch (iarg) {
case 0: case 0:
adv7170_write(client, 0x01, 0x20); adv7170_write(client, 0x01, 0x20);
adv7170_write(client, 0x08, TR1CAPT); /* TR1 */ adv7170_write(client, 0x08, TR1CAPT); /* TR1 */
adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x02, 0x0e); // Enable genlock
adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE | TR0RST);
adv7170_write(client, 0x07, TR0MODE); adv7170_write(client, 0x07, TR0MODE);
//udelay(10); /* udelay(10); */
break; break;
case 1: case 1:
...@@ -325,20 +273,17 @@ adv7170_command (struct i2c_client *client, ...@@ -325,20 +273,17 @@ adv7170_command (struct i2c_client *client,
adv7170_write(client, 0x02, 0x08); adv7170_write(client, 0x02, 0x08);
adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE | TR0RST);
adv7170_write(client, 0x07, TR0MODE); adv7170_write(client, 0x07, TR0MODE);
//udelay(10); /* udelay(10); */
break; break;
default: default:
dprintk(1, KERN_ERR "%s: illegal input: %d\n", v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
I2C_NAME(client), iarg);
return -EINVAL; return -EINVAL;
} }
dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client), v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
inputs[iarg]);
encoder->input = iarg; encoder->input = iarg;
}
break; break;
}
case ENCODER_SET_OUTPUT: case ENCODER_SET_OUTPUT:
{ {
...@@ -348,16 +293,16 @@ adv7170_command (struct i2c_client *client, ...@@ -348,16 +293,16 @@ adv7170_command (struct i2c_client *client,
if (*iarg != 0) { if (*iarg != 0) {
return -EINVAL; return -EINVAL;
} }
}
break; break;
}
case ENCODER_ENABLE_OUTPUT: case ENCODER_ENABLE_OUTPUT:
{ {
int *iarg = arg; int *iarg = arg;
encoder->enable = !!*iarg; encoder->enable = !!*iarg;
}
break; break;
}
default: default:
return -EINVAL; return -EINVAL;
...@@ -368,149 +313,67 @@ adv7170_command (struct i2c_client *client, ...@@ -368,149 +313,67 @@ adv7170_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* static unsigned short normal_i2c[] = {
* Generic i2c probe 0xd4 >> 1, 0xd6 >> 1, /* adv7170 IDs */
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 0x54 >> 1, 0x56 >> 1, /* adv7171 IDs */
*/
static unsigned short normal_i2c[] =
{ I2C_ADV7170 >> 1, (I2C_ADV7170 >> 1) + 1,
I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1,
I2C_CLIENT_END 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_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int
adv7170_detect_client (struct i2c_adapter *adapter,
int address,
int kind)
{ {
int i;
struct i2c_client *client;
struct adv7170 *encoder; struct adv7170 *encoder;
char *dname; int i;
dprintk(1,
KERN_INFO
"adv7170.c: detecting adv7170 client on address 0x%x\n",
address << 1);
/* Check if the adapter supports the needed features */ /* Check if the adapter supports the needed features */
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return 0; return -ENODEV;
client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); v4l_info(client, "chip found @ 0x%x (%s)\n",
if (!client) client->addr << 1, client->adapter->name);
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)));
encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL); encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
if (encoder == NULL) { if (encoder == NULL)
kfree(client);
return -ENOMEM; return -ENOMEM;
}
encoder->norm = VIDEO_MODE_NTSC; encoder->norm = VIDEO_MODE_NTSC;
encoder->input = 0; encoder->input = 0;
encoder->enable = 1; encoder->enable = 1;
i2c_set_clientdata(client, encoder); 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)); i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
if (i >= 0) { if (i >= 0) {
i = adv7170_write(client, 0x07, TR0MODE | TR0RST); i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
i = adv7170_write(client, 0x07, TR0MODE); i = adv7170_write(client, 0x07, TR0MODE);
i = adv7170_read(client, 0x12); i = adv7170_read(client, 0x12);
dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%02x\n", v4l_dbg(1, debug, client, "revision %d\n", i & 1);
I2C_NAME(client), i & 1, client->addr << 1);
} }
if (i < 0) { if (i < 0)
dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n", v4l_dbg(1, debug, client, "init error 0x%x\n", i);
I2C_NAME(client), i);
}
return 0; return 0;
} }
static int static int adv7170_remove(struct i2c_client *client)
adv7170_attach_adapter (struct i2c_adapter *adapter)
{ {
dprintk(1, kfree(i2c_get_clientdata(client));
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)
{
struct adv7170 *encoder = i2c_get_clientdata(client);
int err;
err = i2c_detach_client(client);
if (err) {
return err;
}
kfree(encoder);
kfree(client);
return 0; return 0;
} }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static struct i2c_driver i2c_driver_adv7170 = { static const struct i2c_device_id adv7170_id[] = {
.driver = { { "adv7170", 0 },
.name = "adv7170", /* name */ { "adv7171", 0 },
}, { }
};
.id = I2C_DRIVERID_ADV7170, MODULE_DEVICE_TABLE(i2c, adv7170_id);
.attach_adapter = adv7170_attach_adapter, static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.detach_client = adv7170_detach_client, .name = "adv7170",
.driverid = I2C_DRIVERID_ADV7170,
.command = adv7170_command, .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);
此差异已折叠。
...@@ -90,6 +90,7 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) ...@@ -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 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
case 72231: /* 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 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 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
break; break;
...@@ -185,7 +186,7 @@ void au0828_gpio_setup(struct au0828_dev *dev) ...@@ -185,7 +186,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
} }
/* table of devices that work with this driver */ /* 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), { USB_DEVICE(0x2040, 0x7200),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x7240), { USB_DEVICE(0x2040, 0x7240),
...@@ -198,6 +199,8 @@ struct usb_device_id au0828_usb_id_table [] = { ...@@ -198,6 +199,8 @@ struct usb_device_id au0828_usb_id_table [] = {
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x721b), { USB_DEVICE(0x2040, 0x721b),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x721e),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x721f), { USB_DEVICE(0x2040, 0x721f),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x7280), { USB_DEVICE(0x2040, 0x7280),
......
...@@ -91,7 +91,8 @@ static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value, ...@@ -91,7 +91,8 @@ static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
status = usb_control_msg(dev->usbdev, status = usb_control_msg(dev->usbdev,
usb_sndctrlpipe(dev->usbdev, 0), usb_sndctrlpipe(dev->usbdev, 0),
request, request,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, USB_DIR_OUT | USB_TYPE_VENDOR |
USB_RECIP_DEVICE,
value, index, value, index,
cp, size, 1000); cp, size, 1000);
......
...@@ -173,7 +173,8 @@ static int start_urb_transfer(struct au0828_dev *dev) ...@@ -173,7 +173,8 @@ static int start_urb_transfer(struct au0828_dev *dev)
purb->status = -EINPROGRESS; purb->status = -EINPROGRESS;
usb_fill_bulk_urb(purb, usb_fill_bulk_urb(purb,
dev->usbdev, dev->usbdev,
usb_rcvbulkpipe(dev->usbdev, _AU0828_BULKPIPE), usb_rcvbulkpipe(dev->usbdev,
_AU0828_BULKPIPE),
purb->transfer_buffer, purb->transfer_buffer,
URB_BUFSIZE, URB_BUFSIZE,
urb_completion, urb_completion,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -131,7 +131,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, ...@@ -131,7 +131,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
printk(" >\n"); printk(" >\n");
} }
for (cnt = 1; cnt < msg->len; cnt++ ) { for (cnt = 1; cnt < msg->len; cnt++) {
/* following bytes */ /* following bytes */
wdata = msg->buf[cnt]; wdata = msg->buf[cnt];
ctrl = bus->i2c_period | (1 << 12) | (1 << 2); ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
...@@ -151,9 +151,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, ...@@ -151,9 +151,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
if (retval == 0) if (retval == 0)
goto eio; goto eio;
if (i2c_debug) { if (i2c_debug) {
printk(" %02x", msg->buf[cnt]); dprintk(1, " %02x", msg->buf[cnt]);
if (!(ctrl & I2C_NOSTOP)) if (!(ctrl & I2C_NOSTOP))
printk(" >\n"); dprintk(1, " >\n");
} }
} }
return msg->len; return msg->len;
...@@ -162,7 +162,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, ...@@ -162,7 +162,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
retval = -EIO; retval = -EIO;
err: err:
if (i2c_debug) if (i2c_debug)
printk(" ERR: %d\n", retval); printk(KERN_ERR " ERR: %d\n", retval);
return retval; return retval;
} }
...@@ -194,12 +194,12 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, ...@@ -194,12 +194,12 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
if (i2c_debug) { if (i2c_debug) {
if (joined) if (joined)
printk(" R"); dprintk(1, " R");
else 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; ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
...@@ -216,9 +216,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, ...@@ -216,9 +216,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
goto eio; goto eio;
msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
if (i2c_debug) { if (i2c_debug) {
printk(" %02x", msg->buf[cnt]); dprintk(1, " %02x", msg->buf[cnt]);
if (!(ctrl & I2C_NOSTOP)) if (!(ctrl & I2C_NOSTOP))
printk(" >\n"); dprintk(1, " >\n");
} }
} }
return msg->len; return msg->len;
...@@ -227,7 +227,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, ...@@ -227,7 +227,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
retval = -EIO; retval = -EIO;
err: err:
if (i2c_debug) if (i2c_debug)
printk(" ERR: %d\n", retval); printk(KERN_ERR " ERR: %d\n", retval);
return retval; return retval;
} }
...@@ -355,13 +355,13 @@ static struct i2c_client cx23885_i2c_client_template = { ...@@ -355,13 +355,13 @@ static struct i2c_client cx23885_i2c_client_template = {
static char *i2c_devs[128] = { static char *i2c_devs[128] = {
[0x10 >> 1] = "tda10048", [0x10 >> 1] = "tda10048",
[0x12 >> 1] = "dib7000pc", [0x12 >> 1] = "dib7000pc",
[ 0x1c >> 1 ] = "lgdt3303", [0x1c >> 1] = "lgdt3303",
[ 0x86 >> 1 ] = "tda9887", [0x86 >> 1] = "tda9887",
[ 0x32 >> 1 ] = "cx24227", [0x32 >> 1] = "cx24227",
[ 0x88 >> 1 ] = "cx25837", [0x88 >> 1] = "cx25837",
[ 0x84 >> 1 ] = "tda8295", [0x84 >> 1] = "tda8295",
[ 0xa0 >> 1 ] = "eeprom", [0xa0 >> 1] = "eeprom",
[ 0xc0 >> 1 ] = "tuner/mt2131/tda8275", [0xc0 >> 1] = "tuner/mt2131/tda8275",
[0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028", [0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028",
[0xc8 >> 1] = "tuner/xc3028L", [0xc8 >> 1] = "tuner/xc3028L",
}; };
...@@ -376,7 +376,7 @@ 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); rc = i2c_master_recv(c, &buf, 0);
if (rc < 0) if (rc < 0)
continue; 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] : "???"); name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
} }
} }
...@@ -408,11 +408,12 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) ...@@ -408,11 +408,12 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
bus->i2c_client.adapter = &bus->i2c_adap; bus->i2c_client.adapter = &bus->i2c_adap;
if (0 == bus->i2c_rc) { 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) if (i2c_scan)
do_i2c_scan(dev->name, &bus->i2c_client); do_i2c_scan(dev->name, &bus->i2c_client);
} else } 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; return bus->i2c_rc;
} }
......
...@@ -285,11 +285,10 @@ static void cx23885_video_wakeup(struct cx23885_dev *dev, ...@@ -285,11 +285,10 @@ static void cx23885_video_wakeup(struct cx23885_dev *dev,
list_del(&buf->vb.queue); list_del(&buf->vb.queue);
wake_up(&buf->vb.done); wake_up(&buf->vb.done);
} }
if (list_empty(&q->active)) { if (list_empty(&q->active))
del_timer(&q->timeout); del_timer(&q->timeout);
} else { else
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
}
if (bc != 1) if (bc != 1)
printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
__func__, bc); __func__, bc);
...@@ -379,12 +378,12 @@ static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, ...@@ -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) 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) 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, 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) ...@@ -887,14 +886,16 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma)
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* VIDEO CTRL IOCTLS */ /* 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__); dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl);
return 0; 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)" dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)"
" (disabled - no action)\n", __func__); " (disabled - no action)\n", __func__);
...@@ -1073,29 +1074,29 @@ static int vidioc_reqbufs(struct file *file, void *priv, ...@@ -1073,29 +1074,29 @@ static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p) struct v4l2_requestbuffers *p)
{ {
struct cx23885_fh *fh = priv; 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, static int vidioc_querybuf(struct file *file, void *priv,
struct v4l2_buffer *p) struct v4l2_buffer *p)
{ {
struct cx23885_fh *fh = priv; 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, static int vidioc_qbuf(struct file *file, void *priv,
struct v4l2_buffer *p) struct v4l2_buffer *p)
{ {
struct cx23885_fh *fh = priv; 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, static int vidioc_dqbuf(struct file *file, void *priv,
struct v4l2_buffer *p) struct v4l2_buffer *p)
{ {
struct cx23885_fh *fh = priv; struct cx23885_fh *fh = priv;
return (videobuf_dqbuf(get_queue(fh), p, return videobuf_dqbuf(get_queue(fh), p,
file->f_flags & O_NONBLOCK)); file->f_flags & O_NONBLOCK);
} }
static int vidioc_streamon(struct file *file, void *priv, static int vidioc_streamon(struct file *file, void *priv,
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include <linux/version.h> #include <linux/version.h>
#include <linux/mutex.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) #define UNSET (-1U)
...@@ -225,7 +225,7 @@ struct cx23885_tsport { ...@@ -225,7 +225,7 @@ struct cx23885_tsport {
int nr; int nr;
int sram_chno; int sram_chno;
struct videobuf_dvb dvb; struct videobuf_dvb_frontends frontends;
/* dma queues */ /* dma queues */
struct cx23885_dmaqueue mpegq; struct cx23885_dmaqueue mpegq;
...@@ -262,6 +262,9 @@ struct cx23885_tsport { ...@@ -262,6 +262,9 @@ struct cx23885_tsport {
u32 src_sel_val; u32 src_sel_val;
u32 vld_misc_val; u32 vld_misc_val;
u32 hw_sop_ctrl_val; u32 hw_sop_ctrl_val;
/* Allow a single tsport to have multiple frontends */
u32 num_frontends;
}; };
struct cx23885_dev { struct cx23885_dev {
...@@ -367,14 +370,14 @@ struct sram_channel { ...@@ -367,14 +370,14 @@ struct sram_channel {
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
#define cx_read(reg) readl(dev->lmmio + ((reg)>>2)) #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)) |\ writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
((value) & (mask)), dev->lmmio+((reg)>>2)) ((value) & (mask)), dev->lmmio+((reg)>>2))
#define cx_set(reg,bit) cx_andor((reg),(bit),(bit)) #define cx_set(reg, bit) cx_andor((reg), (bit), (bit))
#define cx_clear(reg,bit) cx_andor((reg),(bit),0) #define cx_clear(reg, bit) cx_andor((reg), (bit), 0)
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
/* cx23885-core.c */ /* cx23885-core.c */
...@@ -411,7 +414,8 @@ extern const unsigned int cx23885_bcount; ...@@ -411,7 +414,8 @@ extern const unsigned int cx23885_bcount;
extern struct cx23885_subid cx23885_subids[]; extern struct cx23885_subid cx23885_subids[];
extern const unsigned int cx23885_idcount; 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 void cx23885_card_list(struct cx23885_dev *dev);
extern int cx23885_ir_init(struct cx23885_dev *dev); extern int cx23885_ir_init(struct cx23885_dev *dev);
extern void cx23885_gpio_setup(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) ...@@ -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; 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
*/
...@@ -549,7 +549,8 @@ void cx88_wakeup(struct cx88_core *core, ...@@ -549,7 +549,8 @@ void cx88_wakeup(struct cx88_core *core,
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
} }
if (bc != 1) 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) void cx88_shutdown(struct cx88_core *core)
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#define GSPCAV2_H #define GSPCAV2_H
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册