Commit 1702b520 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (42 commits)
  V4L/DVB (8108): Fix open/close race in saa7134
  V4L/DVB (8100): V4L/vivi: fix possible memory leak in vivi_fillbuff
  V4L/DVB (8097): xc5000: check device hardware state to determine if firmware download is needed
  V4L/DVB (8096): au8522: prevent false-positive lock status
  V4L/DVB (8092): videodev: simplify and fix standard enumeration
  V4L/DVB (8075): stv0299: Uncorrected block count and bit error rate fixed
  V4L/DVB (8074): av7110: OSD transfers should not be interrupted
  V4L/DVB (8073): av7110: Catch another type of ARM crash
  V4L/DVB (8071): tda10023: Fix possible kernel oops during initialisation
  V4L/DVB (8069): cx18: Fix S-Video and Compsite inputs for the Yuan MPC718 and enable card entry
  V4L/DVB (8068): cx18: Add I2C slave reset via GPIO upon initialization
  V4L/DVB (8067): cx18: Fix firmware load for case when digital capture happens first
  V4L/DVB (8066): cx18: Fix audio mux input definitions for HVR-1600 Line In 2 and FM radio
  V4L/DVB (8063): cx18: Fix unintended auto configurations in cx18-av-core
  V4L/DVB (8061): cx18: only select tuner / frontend modules if !DVB_FE_CUSTOMISE
  V4L/DVB (8048): saa7134: Fix entries for Avermedia A16d and Avermedia E506
  V4L/DVB (8044): au8522: tuning optimizations
  V4L/DVB (8043): au0828: add support for additional USB device id's
  V4L/DVB (8042): DVB-USB UMT-010 channel scan oops
  V4L/DVB (8040): soc-camera: remove soc_camera_host_class class
  ...
parents 0acbbee4 a1789873
0 -> Unknown board (au0828)
1 -> Hauppauge HVR950Q (au0828) [2040:7200]
1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
2 -> Hauppauge HVR850 (au0828) [2040:7240]
3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
......@@ -2201,3 +2201,41 @@ IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = {
[0x25] = KEY_POWER, /* power */
};
EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel);
IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
[0x20] = KEY_LIST,
[0x00] = KEY_POWER,
[0x28] = KEY_1,
[0x18] = KEY_2,
[0x38] = KEY_3,
[0x24] = KEY_4,
[0x14] = KEY_5,
[0x34] = KEY_6,
[0x2c] = KEY_7,
[0x1c] = KEY_8,
[0x3c] = KEY_9,
[0x12] = KEY_SUBTITLE,
[0x22] = KEY_0,
[0x32] = KEY_REWIND,
[0x3a] = KEY_SHUFFLE,
[0x02] = KEY_PRINT,
[0x11] = KEY_CHANNELDOWN,
[0x31] = KEY_CHANNELUP,
[0x0c] = KEY_ZOOM,
[0x1e] = KEY_VOLUMEDOWN,
[0x3e] = KEY_VOLUMEUP,
[0x0a] = KEY_MUTE,
[0x04] = KEY_AUDIO,
[0x26] = KEY_RECORD,
[0x06] = KEY_PLAY,
[0x36] = KEY_STOP,
[0x16] = KEY_PAUSE,
[0x2e] = KEY_REWIND,
[0x0e] = KEY_FASTFORWARD,
[0x30] = KEY_TEXT,
[0x21] = KEY_GREEN,
[0x01] = KEY_BLUE,
[0x08] = KEY_EPG,
[0x2a] = KEY_MENU,
};
EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d);
......@@ -649,9 +649,17 @@ int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq)
u8 val;
int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val);
/* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range
* for frequencies above 61.1 MHz. In these cases, the internal RF
* tracking filters calibration mechanism is used.
*
* There is no need to warn the user about this.
*/
if (ret < 0)
goto fail;
regs[R_EB14] = val;
fail:
return ret;
}
......
......@@ -45,6 +45,21 @@ static inline int charge_pump_source(struct dvb_frontend *fe, int force)
TDA18271_MAIN_PLL, force);
}
static inline void tda18271_set_if_notch(struct dvb_frontend *fe)
{
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
switch (priv->mode) {
case TDA18271_ANALOG:
regs[R_MPD] &= ~0x80; /* IF notch = 0 */
break;
case TDA18271_DIGITAL:
regs[R_MPD] |= 0x80; /* IF notch = 1 */
break;
}
}
static int tda18271_channel_configuration(struct dvb_frontend *fe,
struct tda18271_std_map_item *map,
u32 freq, u32 bw)
......@@ -60,25 +75,18 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
regs[R_EP3] &= ~0x1f; /* clear std bits */
regs[R_EP3] |= (map->agc_mode << 3) | map->std;
/* set rfagc to high speed mode */
regs[R_EP3] &= ~0x04;
if (priv->id == TDA18271HDC2) {
/* set rfagc to high speed mode */
regs[R_EP3] &= ~0x04;
}
/* set cal mode to normal */
regs[R_EP4] &= ~0x03;
/* update IF output level & IF notch frequency */
/* update IF output level */
regs[R_EP4] &= ~0x1c; /* clear if level bits */
regs[R_EP4] |= (map->if_lvl << 2);
switch (priv->mode) {
case TDA18271_ANALOG:
regs[R_MPD] &= ~0x80; /* IF notch = 0 */
break;
case TDA18271_DIGITAL:
regs[R_MPD] |= 0x80; /* IF notch = 1 */
break;
}
/* update FM_RFn */
regs[R_EP4] &= ~0x80;
regs[R_EP4] |= map->fm_rfn << 7;
......@@ -95,6 +103,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
/* disable Power Level Indicator */
regs[R_EP1] |= 0x40;
/* make sure thermometer is off */
regs[R_TM] &= ~0x10;
/* frequency dependent parameters */
tda18271_calc_ir_measure(fe, &freq);
......@@ -135,6 +146,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
switch (priv->role) {
case TDA18271_MASTER:
tda18271_calc_main_pll(fe, N);
tda18271_set_if_notch(fe);
tda18271_write_regs(fe, R_MPD, 4);
break;
case TDA18271_SLAVE:
......@@ -142,6 +154,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
tda18271_write_regs(fe, R_CPD, 4);
regs[R_MPD] = regs[R_CPD] & 0x7f;
tda18271_set_if_notch(fe);
tda18271_write_regs(fe, R_MPD, 1);
break;
}
......@@ -160,12 +173,14 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
msleep(20);
/* set rfagc to normal speed mode */
if (map->fm_rfn)
regs[R_EP3] &= ~0x04;
else
regs[R_EP3] |= 0x04;
ret = tda18271_write_regs(fe, R_EP3, 1);
if (priv->id == TDA18271HDC2) {
/* set rfagc to normal speed mode */
if (map->fm_rfn)
regs[R_EP3] &= ~0x04;
else
regs[R_EP3] |= 0x04;
ret = tda18271_write_regs(fe, R_EP3, 1);
}
fail:
return ret;
}
......@@ -507,7 +522,7 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe)
/* set cal mode to normal */
regs[R_EP4] &= ~0x03;
/* update IF output level & IF notch frequency */
/* update IF output level */
regs[R_EP4] &= ~0x1c; /* clear if level bits */
ret = tda18271_write_regs(fe, R_EP3, 2);
......
......@@ -177,6 +177,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
{"FM Radio-INPUT1", 0x0208, 0x9002}
};
static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len);
static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len);
static void xc5000_TunerReset(struct dvb_frontend *fe);
......@@ -352,7 +353,7 @@ static int xc_SetTVStandard(struct xc5000_priv *priv,
static int xc_shutdown(struct xc5000_priv *priv)
{
return 0;
return XC_RESULT_SUCCESS;
/* Fixme: cannot bring tuner back alive once shutdown
* without reloading the driver modules.
* return xc_write_reg(priv, XREG_POWER_DOWN, 0);
......@@ -685,6 +686,25 @@ static int xc5000_set_params(struct dvb_frontend *fe,
return 0;
}
static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
{
struct xc5000_priv *priv = fe->tuner_priv;
int ret;
u16 id;
ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
if (ret == XC_RESULT_SUCCESS) {
if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
ret = XC_RESULT_RESET_FAILURE;
else
ret = XC_RESULT_SUCCESS;
}
dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
ret == XC_RESULT_SUCCESS ? "True" : "False", id);
return ret;
}
static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
static int xc5000_set_analog_params(struct dvb_frontend *fe,
......@@ -693,7 +713,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
struct xc5000_priv *priv = fe->tuner_priv;
int ret;
if(priv->fwloaded == 0)
if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
xc_load_fw_and_init_tuner(fe);
dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
......@@ -808,11 +828,10 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
struct xc5000_priv *priv = fe->tuner_priv;
int ret = 0;
if (priv->fwloaded == 0) {
if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
ret = xc5000_fwupload(fe);
if (ret != XC_RESULT_SUCCESS)
return ret;
priv->fwloaded = 1;
}
/* Start the tuner self-calibration process */
......@@ -852,7 +871,6 @@ static int xc5000_sleep(struct dvb_frontend *fe)
return -EREMOTEIO;
}
else {
/* priv->fwloaded = 0; */
return XC_RESULT_SUCCESS;
}
}
......@@ -933,7 +951,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
cfg->i2c_address);
printk(KERN_INFO
"xc5000: Firmware has been loaded previously\n");
priv->fwloaded = 1;
break;
case XC_PRODUCT_ID_FW_NOT_LOADED:
printk(KERN_INFO
......@@ -941,7 +958,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
cfg->i2c_address);
printk(KERN_INFO
"xc5000: Firmware has not been loaded previously\n");
priv->fwloaded = 0;
break;
default:
printk(KERN_ERR
......
......@@ -30,7 +30,6 @@ struct xc5000_priv {
u32 bandwidth;
u8 video_standard;
u8 rf_mode;
u8 fwloaded;
void *devptr;
};
......
......@@ -47,6 +47,8 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
return -EINVAL;
}
msleep(1); /* avoid I2C errors */
return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
value, index, rbuf, rlen, 2000);
}
......@@ -92,16 +94,6 @@ static struct i2c_algorithm gl861_i2c_algo = {
};
/* Callbacks for DVB USB */
static int gl861_identify_state(struct usb_device *udev,
struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc,
int *cold)
{
*cold = 0;
return 0;
}
static struct zl10353_config gl861_zl10353_config = {
.demod_address = 0x0f,
.no_tuner = 1,
......@@ -172,7 +164,6 @@ static struct dvb_usb_device_properties gl861_properties = {
.size_of_priv = 0,
.identify_state = gl861_identify_state,
.num_adapters = 1,
.adapter = {{
......@@ -194,13 +185,15 @@ static struct dvb_usb_device_properties gl861_properties = {
.num_device_descs = 2,
.devices = {
{ "MSI Mega Sky 55801 DVB-T USB2.0",
{ &gl861_table[0], NULL },
{ NULL },
{
.name = "MSI Mega Sky 55801 DVB-T USB2.0",
.cold_ids = { NULL },
.warm_ids = { &gl861_table[0], NULL },
},
{ "A-LINK DTU DVB-T USB2.0",
{ &gl861_table[1], NULL },
{ NULL },
{
.name = "A-LINK DTU DVB-T USB2.0",
.cold_ids = { NULL },
.warm_ids = { &gl861_table[1], NULL },
},
}
};
......
......@@ -107,7 +107,7 @@ static struct dvb_usb_device_properties umt_properties = {
/* parameter for the MPEG2-data transfer */
.stream = {
.type = USB_BULK,
.count = 20,
.count = MAX_NO_URBS_FOR_DATA_STREAM,
.endpoint = 0x06,
.u = {
.bulk = {
......
......@@ -463,10 +463,13 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
struct au8522_state *state = fe->demodulator_priv;
int ret = -EINVAL;
dprintk("%s(frequency=%d)\n", __func__, p->frequency);
state->current_frequency = p->frequency;
if ((state->current_frequency == p->frequency) &&
(state->current_modulation == p->u.vsb.modulation))
return 0;
au8522_enable_modulation(fe, p->u.vsb.modulation);
......@@ -476,11 +479,16 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
if (fe->ops.tuner_ops.set_params) {
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
fe->ops.tuner_ops.set_params(fe, p);
ret = fe->ops.tuner_ops.set_params(fe, p);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
}
if (ret < 0)
return ret;
state->current_frequency = p->frequency;
return 0;
}
......@@ -498,6 +506,16 @@ static int au8522_init(struct dvb_frontend *fe)
return 0;
}
static int au8522_sleep(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
state->current_frequency = 0;
return 0;
}
static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct au8522_state *state = fe->demodulator_priv;
......@@ -509,10 +527,8 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
if (state->current_modulation == VSB_8) {
dprintk("%s() Checking VSB_8\n", __func__);
reg = au8522_readreg(state, 0x4088);
if (reg & 0x01)
*status |= FE_HAS_VITERBI;
if (reg & 0x02)
*status |= FE_HAS_LOCK | FE_HAS_SYNC;
if ((reg & 0x03) == 0x03)
*status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
} else {
dprintk("%s() Checking QAM\n", __func__);
reg = au8522_readreg(state, 0x4541);
......@@ -672,6 +688,7 @@ static struct dvb_frontend_ops au8522_ops = {
},
.init = au8522_init,
.sleep = au8522_sleep,
.i2c_gate_ctrl = au8522_i2c_gate_ctrl,
.set_frontend = au8522_set_frontend,
.get_frontend = au8522_get_frontend,
......
......@@ -63,6 +63,7 @@ struct stv0299_state {
u32 symbol_rate;
fe_code_rate_t fec_inner;
int errmode;
u32 ucblocks;
};
#define STATUS_BER 0
......@@ -501,8 +502,10 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
{
struct stv0299_state* state = fe->demodulator_priv;
if (state->errmode != STATUS_BER) return 0;
*ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
if (state->errmode != STATUS_BER)
return -ENOSYS;
*ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8);
return 0;
}
......@@ -540,8 +543,12 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
{
struct stv0299_state* state = fe->demodulator_priv;
if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
if (state->errmode != STATUS_UCBLOCKS)
return -ENOSYS;
state->ucblocks += stv0299_readreg(state, 0x1e);
state->ucblocks += (stv0299_readreg(state, 0x1d) << 8);
*ucblocks = state->ucblocks;
return 0;
}
......
......@@ -116,9 +116,12 @@ static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
int ret;
ret = i2c_transfer (state->i2c, msg, 2);
if (ret != 2)
printk("DVB: TDA10023: %s: readreg error (ret == %i)\n",
__func__, ret);
if (ret != 2) {
int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error "
"(reg == 0x%02x, ret == %i)\n",
num, __func__, reg, ret);
}
return b1[0];
}
......@@ -129,11 +132,12 @@ static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
int ret;
ret = i2c_transfer (state->i2c, &msg, 1);
if (ret != 1)
printk("DVB: TDA10023(%d): %s, writereg error "
if (ret != 1) {
int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error "
"(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
state->frontend.dvb->num, __func__, reg, data, ret);
num, __func__, reg, data, ret);
}
return (ret != 1) ? -EREMOTEIO : 0;
}
......@@ -464,7 +468,7 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
int i;
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL);
state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL);
if (state == NULL) goto error;
/* setup the state */
......
......@@ -1248,11 +1248,14 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
struct i2c_adapter* i2c)
{
struct tda1004x_state *state;
int id;
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
if (!state)
if (!state) {
printk(KERN_ERR "Can't alocate memory for tda10045 state\n");
return NULL;
}
/* setup the state */
state->config = config;
......@@ -1260,7 +1263,15 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
state->demod_type = TDA1004X_DEMOD_TDA10045;
/* check if the demod is there */
if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) {
id = tda1004x_read_byte(state, TDA1004X_CHIPID);
if (id < 0) {
printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n");
kfree(state);
return NULL;
}
if (id != 0x25) {
printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
kfree(state);
return NULL;
}
......@@ -1307,11 +1318,14 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
struct i2c_adapter* i2c)
{
struct tda1004x_state *state;
int id;
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
if (!state)
if (!state) {
printk(KERN_ERR "Can't alocate memory for tda10046 state\n");
return NULL;
}
/* setup the state */
state->config = config;
......@@ -1319,7 +1333,14 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
state->demod_type = TDA1004X_DEMOD_TDA10046;
/* check if the demod is there */
if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {
id = tda1004x_read_byte(state, TDA1004X_CHIPID);
if (id < 0) {
printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n");
kfree(state);
return NULL;
}
if (id != 0x46) {
printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
kfree(state);
return NULL;
}
......
......@@ -101,6 +101,7 @@ config DVB_BUDGET
config DVB_BUDGET_CI
tristate "Budget cards with onboard CI connector"
depends on DVB_BUDGET_CORE && I2C
depends on INPUT # due to IR
select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
......
......@@ -427,6 +427,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
if (err) {
printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
__func__, type);
av7110->arm_errors++;
return -ETIMEDOUT;
}
msleep(1);
......@@ -853,10 +854,8 @@ static osd_raw_window_t bpp2bit[8] = {
static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
{
int ret = wait_event_interruptible_timeout(av7110->bmpq,
int ret = wait_event_timeout(av7110->bmpq,
av7110->bmp_state != BMP_LOADING, 10*HZ);
if (ret == -ERESTARTSYS)
return ret;
if (ret == 0) {
printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
ret, av7110->bmp_state);
......
......@@ -77,8 +77,14 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
/* Make sure we support the board model */
switch (tv.model) {
case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */
case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
case 72211: /* 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 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */
case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
break;
default:
printk(KERN_WARNING "%s: warning: "
......@@ -175,6 +181,18 @@ struct usb_device_id au0828_usb_id_table [] = {
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR850 },
{ USB_DEVICE(0x0fe9, 0xd620),
.driver_info = AU0828_BOARD_DVICO_FUSIONHDTV7 },
{ USB_DEVICE(0x2040, 0x7210),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x7217),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x721b),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x721f),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x7280),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x0fd9, 0x0008),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ },
};
......
......@@ -10,8 +10,8 @@ config VIDEO_CX18
select VIDEO_TVEEPROM
select VIDEO_CX2341X
select VIDEO_CS5345
select DVB_S5H1409
select MEDIA_TUNER_MXL5005S
select DVB_S5H1409 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE
---help---
This is a video4linux driver for Conexant cx23418 based
PCI combo video recorder devices.
......
......@@ -69,6 +69,58 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
or_value);
}
int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask)
{
int retval;
u32 saved_reg[8] = {0};
if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL);
saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL);
}
if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1);
saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC);
}
if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL);
saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL);
saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG);
saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG);
}
retval = cx18_av_write(cx, addr, value);
if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]);
cx18_av_write4(cx, CXADEC_AFE_CTRL, saved_reg[1]);
}
if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
cx18_av_write4(cx, CXADEC_PLL_CTRL1, saved_reg[2]);
cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]);
}
if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL, saved_reg[4]);
cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL, saved_reg[5]);
cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, saved_reg[6]);
cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]);
}
return retval;
}
int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask,
u8 or_value, int no_acfg_mask)
{
return cx18_av_write_no_acfg(cx, addr,
(cx18_av_read(cx, addr) & and_mask) |
or_value, no_acfg_mask);
}
/* ----------------------------------------------------------------------- */
static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
......@@ -170,13 +222,15 @@ static void input_change(struct cx18 *cx)
/* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
if (std & V4L2_STD_SECAM)
cx18_av_write(cx, 0x402, 0);
cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL);
else {
cx18_av_write(cx, 0x402, 0x04);
cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL);
cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
}
cx18_av_and_or(cx, 0x401, ~0x60, 0);
cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0,
CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60,
CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
if (std & V4L2_STD_525_60) {
if (std == V4L2_STD_NTSC_M_JP) {
......@@ -228,7 +282,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
if ((vid_input & ~0xff0) ||
luma < CX18_AV_SVIDEO_LUMA1 ||
luma > CX18_AV_SVIDEO_LUMA4 ||
luma > CX18_AV_SVIDEO_LUMA8 ||
chroma < CX18_AV_SVIDEO_CHROMA4 ||
chroma > CX18_AV_SVIDEO_CHROMA8) {
CX18_ERR("0x%04x is not a valid video input!\n",
......@@ -262,7 +316,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
cx18_av_write(cx, 0x103, reg);
/* Set INPUT_MODE to Composite (0) or S-Video (1) */
cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02,
CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
......@@ -318,12 +373,12 @@ static int set_v4lstd(struct cx18 *cx)
This happens for example with the Yuan MPC622. */
if (fmt >= 4 && fmt < 8) {
/* Set format to NTSC-M */
cx18_av_and_or(cx, 0x400, ~0xf, 1);
cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE);
/* Turn off LCOMB */
cx18_av_and_or(cx, 0x47b, ~6, 0);
}
cx18_av_and_or(cx, 0x400, ~0xf, fmt);
cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE);
cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL);
cx18_av_vbi_setup(cx);
input_change(cx);
return 0;
......
......@@ -37,12 +37,16 @@ enum cx18_av_video_input {
CX18_AV_COMPOSITE7,
CX18_AV_COMPOSITE8,
/* S-Video inputs consist of one luma input (In1-In4) ORed with one
/* S-Video inputs consist of one luma input (In1-In8) ORed with one
chroma input (In5-In8) */
CX18_AV_SVIDEO_LUMA1 = 0x10,
CX18_AV_SVIDEO_LUMA2 = 0x20,
CX18_AV_SVIDEO_LUMA3 = 0x30,
CX18_AV_SVIDEO_LUMA4 = 0x40,
CX18_AV_SVIDEO_LUMA5 = 0x50,
CX18_AV_SVIDEO_LUMA6 = 0x60,
CX18_AV_SVIDEO_LUMA7 = 0x70,
CX18_AV_SVIDEO_LUMA8 = 0x80,
CX18_AV_SVIDEO_CHROMA4 = 0x400,
CX18_AV_SVIDEO_CHROMA5 = 0x500,
CX18_AV_SVIDEO_CHROMA6 = 0x600,
......@@ -291,14 +295,24 @@ struct cx18_av_state {
#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
/* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/
#define CXADEC_NO_ACFG_AFE 0x01 /* Preserve 0x100-0x107 */
#define CXADEC_NO_ACFG_PLL 0x02 /* Preserve 0x108-0x10f */
#define CXADEC_NO_ACFG_VID 0x04 /* Preserve 0x470-0x47f */
#define CXADEC_NO_ACFG_ALL 0x07
/* ----------------------------------------------------------------------- */
/* cx18_av-core.c */
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value,
int no_acfg_mask);
u8 cx18_av_read(struct cx18 *cx, u16 addr);
u32 cx18_av_read4(struct cx18 *cx, u16 addr);
int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value,
int no_acfg_mask);
int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
/* ----------------------------------------------------------------------- */
......
......@@ -23,6 +23,7 @@
#include "cx18-driver.h"
#include "cx18-cards.h"
#include "cx18-av-core.h"
#include "cx18-i2c.h"
#include <media/cs5345.h>
......@@ -54,22 +55,22 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
CX18_HW_CS5345 | CX18_HW_DVB,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
{ CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 },
{ CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
{ CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
{ CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER,
CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
{ CX18_CARD_INPUT_LINE_IN1,
CX23418_AUDIO_SERIAL, CS5345_IN_2 },
CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
{ CX18_CARD_INPUT_LINE_IN2,
CX23418_AUDIO_SERIAL, CS5345_IN_2 },
CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
CX23418_AUDIO_SERIAL, 0 },
CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
.ddr = {
/* ESMT M13S128324A-5B memory */
.chip_config = 0x003,
......@@ -81,6 +82,11 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
},
.gpio_init.initial_value = 0x3001,
.gpio_init.direction = 0x3001,
.gpio_i2c_slave_reset = {
.active_lo_mask = 0x3001,
.msecs_asserted = 10,
.msecs_recovery = 40,
},
.i2c = &cx18_i2c_std,
};
......@@ -94,22 +100,22 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
CX18_HW_CS5345 | CX18_HW_DVB,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
{ CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 },
{ CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
{ CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
{ CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER,
CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
{ CX18_CARD_INPUT_LINE_IN1,
CX23418_AUDIO_SERIAL, CS5345_IN_2 },
CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
{ CX18_CARD_INPUT_LINE_IN2,
CX23418_AUDIO_SERIAL, CS5345_IN_2 },
CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
CX23418_AUDIO_SERIAL, 0 },
CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
.ddr = {
/* Samsung K4D263238G-VC33 memory */
.chip_config = 0x003,
......@@ -121,6 +127,11 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
},
.gpio_init.initial_value = 0x3001,
.gpio_init.direction = 0x3001,
.gpio_i2c_slave_reset = {
.active_lo_mask = 0x3001,
.msecs_asserted = 10,
.msecs_recovery = 40,
},
.i2c = &cx18_i2c_std,
};
......@@ -141,19 +152,19 @@ static const struct cx18_card cx18_card_h900 = {
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_all = CX18_HW_TUNER,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE2 },
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 },
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 },
CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER,
CX23418_AUDIO8, 0 },
CX18_AV_AUDIO8, 0 },
{ CX18_CARD_INPUT_LINE_IN1,
CX23418_AUDIO_SERIAL, 0 },
CX18_AV_AUDIO_SERIAL, 0 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
CX23418_AUDIO_SERIAL, 0 },
CX18_AV_AUDIO_SERIAL, 0 },
.tuners = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
},
......@@ -183,23 +194,26 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
static const struct cx18_card cx18_card_mpc718 = {
.type = CX18_CARD_YUAN_MPC718,
.name = "Yuan MPC718",
.comment = "Not yet supported!\n",
.v4l2_capabilities = 0,
.comment = "Some Composite and S-Video inputs are currently working.\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_all = CX18_HW_TUNER,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
{ CX18_CARD_INPUT_SVIDEO2, 2,
CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
{ CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
{ CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER,
CX23418_AUDIO8, 0 },
{ CX18_CARD_INPUT_LINE_IN1,
CX23418_AUDIO_SERIAL, 0 },
{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
{ CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 },
{ CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
CX23418_AUDIO_SERIAL, 0 },
.radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 },
.tuners = {
/* XC3028 tuner */
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
......
......@@ -36,36 +36,6 @@
#define CX18_CARD_INPUT_COMPOSITE2 5
#define CX18_CARD_INPUT_COMPOSITE3 6
enum cx34180_video_input {
/* Composite video inputs In1-In8 */
CX23418_COMPOSITE1 = 1,
CX23418_COMPOSITE2,
CX23418_COMPOSITE3,
CX23418_COMPOSITE4,
CX23418_COMPOSITE5,
CX23418_COMPOSITE6,
CX23418_COMPOSITE7,
CX23418_COMPOSITE8,
/* S-Video inputs consist of one luma input (In1-In4) ORed with one
chroma input (In5-In8) */
CX23418_SVIDEO_LUMA1 = 0x10,
CX23418_SVIDEO_LUMA2 = 0x20,
CX23418_SVIDEO_LUMA3 = 0x30,
CX23418_SVIDEO_LUMA4 = 0x40,
CX23418_SVIDEO_CHROMA4 = 0x400,
CX23418_SVIDEO_CHROMA5 = 0x500,
CX23418_SVIDEO_CHROMA6 = 0x600,
CX23418_SVIDEO_CHROMA7 = 0x700,
CX23418_SVIDEO_CHROMA8 = 0x800,
/* S-Video aliases for common luma/chroma combinations */
CX23418_SVIDEO1 = 0x510,
CX23418_SVIDEO2 = 0x620,
CX23418_SVIDEO3 = 0x730,
CX23418_SVIDEO4 = 0x840,
};
/* audio inputs */
#define CX18_CARD_INPUT_AUD_TUNER 1
#define CX18_CARD_INPUT_LINE_IN1 2
......@@ -75,16 +45,6 @@ enum cx34180_video_input {
#define CX18_CARD_MAX_AUDIO_INPUTS 3
#define CX18_CARD_MAX_TUNERS 2
enum cx23418_audio_input {
/* Audio inputs: serial or In4-In8 */
CX23418_AUDIO_SERIAL,
CX23418_AUDIO4 = 4,
CX23418_AUDIO5,
CX23418_AUDIO6,
CX23418_AUDIO7,
CX23418_AUDIO8,
};
/* V4L2 capability aliases */
#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE)
......@@ -118,6 +78,13 @@ struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
u32 initial_value;
};
struct cx18_gpio_i2c_slave_reset {
u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */
u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */
int msecs_asserted; /* time period reset must remain asserted */
int msecs_recovery; /* time after deassert for chips to be ready */
};
struct cx18_card_tuner {
v4l2_std_id std; /* standard for which the tuner is suitable */
int tuner; /* tuner ID (from tuner.h) */
......@@ -154,7 +121,8 @@ struct cx18_card {
/* GPIO card-specific settings */
u8 xceive_pin; /* XCeive tuner GPIO reset pin */
struct cx18_gpio_init gpio_init;
struct cx18_gpio_init gpio_init;
struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
struct cx18_card_tuner_i2c *i2c;
......
......@@ -69,11 +69,21 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
struct dvb_demux *demux = feed->demux;
struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
struct cx18 *cx = stream->cx;
int ret = -EINVAL;
int ret;
u32 v;
CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
feed->pid, feed->index);
mutex_lock(&cx->serialize_lock);
ret = cx18_init_on_first_open(cx);
mutex_unlock(&cx->serialize_lock);
if (ret) {
CX18_ERR("Failed to initialize firmware starting DVB feed\n");
return ret;
}
ret = -EINVAL;
switch (cx->card->type) {
case CX18_CARD_HVR_1600_ESMT:
case CX18_CARD_HVR_1600_SAMSUNG:
......@@ -101,6 +111,11 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
if (stream->dvb.feeding++ == 0) {
CX18_DEBUG_INFO("Starting Transport DMA\n");
ret = cx18_start_v4l2_encode_stream(stream);
if (ret < 0) {
CX18_DEBUG_INFO(
"Failed to start Transport DMA\n");
stream->dvb.feeding--;
}
} else
ret = 0;
mutex_unlock(&stream->dvb.feedlock);
......
......@@ -53,10 +53,34 @@ static void gpio_write(struct cx18 *cx)
write_reg(((dir & 0xffff) << 16) | (val & 0xffff),
CX18_REG_GPIO_OUT1);
write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2);
write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
CX18_REG_GPIO_OUT2);
}
void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
{
const struct cx18_gpio_i2c_slave_reset *p;
p = &cx->card->gpio_i2c_slave_reset;
if ((p->active_lo_mask | p->active_hi_mask) == 0)
return;
/* Assuming that the masks are a subset of the bits in gpio_dir */
/* Assert */
cx->gpio_val =
(cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
gpio_write(cx);
schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
/* Deassert */
cx->gpio_val =
(cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
gpio_write(cx);
schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
}
void cx18_gpio_init(struct cx18 *cx)
{
cx->gpio_dir = cx->card->gpio_init.direction;
......
......@@ -21,4 +21,5 @@
*/
void cx18_gpio_init(struct cx18 *cx);
void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
int cx18_reset_tuner_gpio(void *dev, int cmd, int value);
......@@ -405,6 +405,8 @@ int init_cx18_i2c(struct cx18 *cx)
cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
cx18_reset_i2c_slaves_gpio(cx);
return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
i2c_bit_add_bus(&cx->i2c_adap[1]);
}
......
......@@ -433,7 +433,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
int chroma = vid_input & 0xf00;
if ((vid_input & ~0xff0) ||
luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 ||
luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
v4l_err(client, "0x%04x is not a valid video input!\n",
vid_input);
......
......@@ -332,6 +332,12 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
if (!chip) {
printk(KERN_ERR "BUG: cx88 can't find device struct."
" Can't proceed with open\n");
return -ENODEV;
}
err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
if (err < 0)
goto _error;
......
......@@ -268,6 +268,12 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
dprintk("opening device and trying to acquire exclusive lock\n");
if (!dev) {
printk(KERN_ERR "BUG: em28xx can't find device struct."
" Can't proceed with open\n");
return -ENODEV;
}
/* Sets volume, mute, etc */
dev->mute = 0;
......@@ -415,6 +421,12 @@ static int em28xx_audio_init(struct em28xx *dev)
static int devnr;
int ret, err;
if (dev->has_audio_class) {
/* This device does not support the extension (in this case
the device is expecting the snd-usb-audio module */
return 0;
}
printk(KERN_INFO "em28xx-audio.c: probing for em28x1 "
"non standard usbaudio\n");
printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
......@@ -458,6 +470,12 @@ static int em28xx_audio_fini(struct em28xx *dev)
if (dev == NULL)
return 0;
if (dev->has_audio_class) {
/* This device does not support the extension (in this case
the device is expecting the snd-usb-audio module */
return 0;
}
if (dev->adev) {
snd_card_free(dev->adev->sndcard);
kfree(dev->adev);
......
......@@ -157,6 +157,7 @@ struct em28xx_board em28xx_boards[] = {
.tda9887_conf = TDA9887_PRESENT,
.tuner_type = TUNER_XC2028,
.mts_firmware = 1,
.has_dvb = 1,
.decoder = EM28XX_TVP5150,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
......@@ -524,6 +525,9 @@ void em28xx_pre_card_setup(struct em28xx *dev)
rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
if (rc > 0) {
switch (rc) {
case CHIP_ID_EM2860:
em28xx_info("chip ID is em2860\n");
break;
case CHIP_ID_EM2883:
em28xx_info("chip ID is em2882/em2883\n");
dev->wait_after_write = 0;
......
......@@ -382,6 +382,11 @@ static int dvb_init(struct em28xx *dev)
int result = 0;
struct em28xx_dvb *dvb;
if (!dev->has_dvb) {
/* This device does not support the extension */
return 0;
}
dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
if (dvb == NULL) {
......@@ -444,6 +449,11 @@ static int dvb_init(struct em28xx *dev)
static int dvb_fini(struct em28xx *dev)
{
if (!dev->has_dvb) {
/* This device does not support the extension */
return 0;
}
if (dev->dvb) {
unregister_dvb(dev->dvb);
dev->dvb = NULL;
......
......@@ -84,5 +84,6 @@
/* FIXME: Need to be populated with the other chip ID's */
enum em28xx_chip_id {
CHIP_ID_EM2860 = 34,
CHIP_ID_EM2883 = 36,
};
......@@ -1848,32 +1848,28 @@ static DEFINE_MUTEX(em28xx_extension_devlist_lock);
int em28xx_register_extension(struct em28xx_ops *ops)
{
struct em28xx *h, *dev = NULL;
list_for_each_entry(h, &em28xx_devlist, devlist)
dev = h;
struct em28xx *dev = NULL;
mutex_lock(&em28xx_extension_devlist_lock);
list_add_tail(&ops->next, &em28xx_extension_devlist);
if (dev)
ops->init(dev);
list_for_each_entry(dev, &em28xx_devlist, devlist) {
if (dev)
ops->init(dev);
}
printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
mutex_unlock(&em28xx_extension_devlist_lock);
return 0;
}
EXPORT_SYMBOL(em28xx_register_extension);
void em28xx_unregister_extension(struct em28xx_ops *ops)
{
struct em28xx *h, *dev = NULL;
list_for_each_entry(h, &em28xx_devlist, devlist)
dev = h;
struct em28xx *dev = NULL;
if (dev)
ops->fini(dev);
list_for_each_entry(dev, &em28xx_devlist, devlist) {
if (dev)
ops->fini(dev);
}
mutex_lock(&em28xx_extension_devlist_lock);
printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
......
......@@ -1019,12 +1019,12 @@ static int pxa_camera_probe(struct platform_device *pdev)
struct pxa_camera_dev *pcdev;
struct resource *res;
void __iomem *base;
unsigned int irq;
int irq;
int err = 0;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (!res || !irq) {
if (!res || irq < 0) {
err = -ENODEV;
goto exit;
}
......
......@@ -613,9 +613,15 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
struct snd_pcm_runtime *runtime = substream->runtime;
snd_card_saa7134_pcm_t *pcm;
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
struct saa7134_dev *dev = saa7134->dev;
struct saa7134_dev *dev;
int amux, err;
if (!saa7134) {
printk(KERN_ERR "BUG: saa7134 can't find device struct."
" Can't proceed with open\n");
return -ENODEV;
}
dev = saa7134->dev;
mutex_lock(&dev->dmasound.lock);
dev->dmasound.read_count = 0;
......
......@@ -4114,11 +4114,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
/*
TODO:
.mpeg = SAA7134_MPEG_DVB,
*/
.inputs = {{
.name = name_tv,
.vmux = 1,
......@@ -4157,7 +4153,7 @@ struct saa7134_board saa7134_boards[] = {
} },
.radio = {
.name = name_radio,
.amux = LINE1,
.amux = TV,
},
},
[SAA7134_BOARD_AVERMEDIA_M115] = {
......@@ -4167,6 +4163,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.mpeg = SAA7134_MPEG_DVB,
.inputs = {{
.name = name_tv,
.vmux = 1,
......@@ -5351,22 +5348,21 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev,
{
switch (command) {
case XC2028_TUNER_RESET:
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000);
mdelay(250);
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0);
mdelay(250);
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000);
mdelay(250);
saa_andorl(SAA7133_ANALOG_IO_SELECT >> 2, 0x02, 0x02);
saa_andorl(SAA7134_ANALOG_IN_CTRL1 >> 2, 0x81, 0x81);
saa_andorl(SAA7134_AUDIO_CLOCK0 >> 2, 0x03187de7, 0x03187de7);
saa_andorl(SAA7134_AUDIO_PLL_CTRL >> 2, 0x03, 0x03);
saa_andorl(SAA7134_AUDIO_CLOCKS_PER_FIELD0 >> 2,
0x0001e000, 0x0001e000);
return 0;
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00000000);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000);
switch (dev->board) {
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
saa7134_set_gpio(dev, 23, 0);
msleep(10);
saa7134_set_gpio(dev, 23, 1);
break;
case SAA7134_BOARD_AVERMEDIA_A16D:
saa7134_set_gpio(dev, 21, 0);
msleep(10);
saa7134_set_gpio(dev, 21, 1);
break;
}
return 0;
}
return -EINVAL;
}
......@@ -5553,9 +5549,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000);
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS:
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
case SAA7134_BOARD_AVERMEDIA_M115:
case SAA7134_BOARD_AVERMEDIA_A16D:
/* power-down tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0);
......@@ -5565,6 +5559,18 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
msleep(10);
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
saa7134_set_gpio(dev, 23, 0);
msleep(10);
saa7134_set_gpio(dev, 23, 1);
break;
case SAA7134_BOARD_AVERMEDIA_A16D:
saa7134_set_gpio(dev, 21, 0);
msleep(10);
saa7134_set_gpio(dev, 21, 1);
msleep(1);
dev->has_remote = SAA7134_REMOTE_GPIO;
break;
case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
/* power-down tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x000A8004, 0x000A8004);
......@@ -5615,7 +5621,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
printk("%s: %s: hybrid analog/dvb card\n"
"%s: Sorry, only the analog inputs are supported for now.\n",
"%s: Sorry, only analog s-video and composite input "
"are supported for now.\n",
dev->name, card(dev).name, dev->name);
break;
}
......@@ -5675,6 +5682,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_AVERMEDIA_A16D:
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
ctl.demod = XC3028_FE_ZARLINK456;
break;
default:
......
......@@ -153,12 +153,12 @@ static int mt352_aver777_init(struct dvb_frontend* fe)
return 0;
}
static int mt352_aver_a16d_init(struct dvb_frontend *fe)
static int mt352_avermedia_xc3028_init(struct dvb_frontend *fe)
{
static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
static u8 reset [] = { RESET, 0x80 };
static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 };
static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d };
static u8 reset [] = { RESET, 0x80 };
static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
static u8 agc_cfg [] = { AGC_TARGET, 0xe };
static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 };
mt352_write(fe, clock_config, sizeof(clock_config));
......@@ -167,12 +167,9 @@ static int mt352_aver_a16d_init(struct dvb_frontend *fe)
mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
mt352_write(fe, agc_cfg, sizeof(agc_cfg));
mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
return 0;
}
static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params)
{
......@@ -215,14 +212,10 @@ static struct mt352_config avermedia_777 = {
.demod_init = mt352_aver777_init,
};
static struct mt352_config avermedia_16d = {
.demod_address = 0xf,
.demod_init = mt352_aver_a16d_init,
};
static struct mt352_config avermedia_e506r_mt352_dev = {
static struct mt352_config avermedia_xc3028_mt352_dev = {
.demod_address = (0x1e >> 1),
.no_tuner = 1,
.demod_init = mt352_avermedia_xc3028_init,
};
/* ==================================================================
......@@ -975,9 +968,10 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_AVERMEDIA_A16D:
dprintk("avertv A16D dvb setup\n");
dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_16d,
&dev->i2c_adap);
dprintk("AverMedia A16D dvb setup\n");
dev->dvb.frontend = dvb_attach(mt352_attach,
&avermedia_xc3028_mt352_dev,
&dev->i2c_adap);
attach_xc3028 = 1;
break;
case SAA7134_BOARD_MD7134:
......@@ -1091,7 +1085,8 @@ static int dvb_init(struct saa7134_dev *dev)
ads_tech_duo_config.tuner_address);
goto dettach_frontend;
}
}
} else
wprintk("failed to attach tda10046\n");
break;
case SAA7134_BOARD_TEVION_DVBT_220RF:
if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config,
......@@ -1260,11 +1255,14 @@ static int dvb_init(struct saa7134_dev *dev)
goto dettach_frontend;
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
dprintk("AverMedia E506R dvb setup\n");
saa7134_set_gpio(dev, 25, 0);
msleep(10);
saa7134_set_gpio(dev, 25, 1);
dev->dvb.frontend = dvb_attach(mt352_attach,
&avermedia_e506r_mt352_dev,
&dev->i2c_adap);
&avermedia_xc3028_mt352_dev,
&dev->i2c_adap);
attach_xc3028 = 1;
break;
case SAA7134_BOARD_MD7134_BRIDGE_2:
dev->dvb.frontend = dvb_attach(tda10086_attach,
&sd1878_4m, &dev->i2c_adap);
......@@ -1338,7 +1336,8 @@ static int dvb_init(struct saa7134_dev *dev)
return ret;
dettach_frontend:
dvb_frontend_detach(dev->dvb.frontend);
if (dev->dvb.frontend)
dvb_frontend_detach(dev->dvb.frontend);
dev->dvb.frontend = NULL;
return -1;
......
......@@ -110,9 +110,10 @@ static int ts_release(struct inode *inode, struct file *file)
{
struct saa7134_dev *dev = file->private_data;
mutex_lock(&dev->empress_tsq.vb_lock);
videobuf_stop(&dev->empress_tsq);
videobuf_mmap_free(&dev->empress_tsq);
dev->empress_users--;
/* stop the encoder */
ts_reset_encoder(dev);
......@@ -121,6 +122,10 @@ static int ts_release(struct inode *inode, struct file *file)
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
dev->empress_users--;
mutex_unlock(&dev->empress_tsq.vb_lock);
return 0;
}
......@@ -218,8 +223,7 @@ static int empress_enum_fmt_cap(struct file *file, void *priv,
static int empress_g_fmt_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f);
......@@ -232,8 +236,7 @@ static int empress_g_fmt_cap(struct file *file, void *priv,
static int empress_s_fmt_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f);
......@@ -247,8 +250,7 @@ static int empress_s_fmt_cap(struct file *file, void *priv,
static int empress_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
return videobuf_reqbufs(&dev->empress_tsq, p);
}
......@@ -256,24 +258,21 @@ static int empress_reqbufs(struct file *file, void *priv,
static int empress_querybuf(struct file *file, void *priv,
struct v4l2_buffer *b)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
return videobuf_querybuf(&dev->empress_tsq, b);
}
static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
return videobuf_qbuf(&dev->empress_tsq, b);
}
static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
return videobuf_dqbuf(&dev->empress_tsq, b,
file->f_flags & O_NONBLOCK);
......@@ -282,8 +281,7 @@ static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
static int empress_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
return videobuf_streamon(&dev->empress_tsq);
}
......@@ -291,8 +289,7 @@ static int empress_streamon(struct file *file, void *priv,
static int empress_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
return videobuf_streamoff(&dev->empress_tsq);
}
......@@ -300,8 +297,7 @@ static int empress_streamoff(struct file *file, void *priv,
static int empress_s_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
/* count == 0 is abused in saa6752hs.c, so that special
case is handled here explicitly. */
......@@ -320,8 +316,7 @@ static int empress_s_ext_ctrls(struct file *file, void *priv,
static int empress_g_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
struct saa7134_dev *dev = file->private_data;
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
......
......@@ -323,6 +323,15 @@ int saa7134_input_init1(struct saa7134_dev *dev)
saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
break;
case SAA7134_BOARD_AVERMEDIA_A16D:
ir_codes = ir_codes_avermedia_a16d;
mask_keycode = 0x02F200;
mask_keydown = 0x000400;
polling = 50; /* ms */
/* Without this we won't receive key up events */
saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
break;
case SAA7134_BOARD_KWORLD_TERMINATOR:
ir_codes = ir_codes_pixelview;
mask_keycode = 0x00001f;
......
......@@ -763,15 +763,6 @@ static struct device_driver ic_drv = {
.owner = THIS_MODULE,
};
/*
* Image capture host - this is a host device, not a bus device, so,
* no bus reference, no probing.
*/
static struct class soc_camera_host_class = {
.owner = THIS_MODULE,
.name = "camera_host",
};
static void dummy_release(struct device *dev)
{
}
......@@ -801,7 +792,6 @@ int soc_camera_host_register(struct soc_camera_host *ici)
/* Number might be equal to the platform device ID */
sprintf(ici->dev.bus_id, "camera_host%d", ici->nr);
ici->dev.class = &soc_camera_host_class;
mutex_lock(&list_lock);
list_for_each_entry(ix, &hosts, list) {
......@@ -1003,14 +993,9 @@ static int __init soc_camera_init(void)
ret = driver_register(&ic_drv);
if (ret)
goto edrvr;
ret = class_register(&soc_camera_host_class);
if (ret)
goto eclr;
return 0;
eclr:
driver_unregister(&ic_drv);
edrvr:
bus_unregister(&soc_camera_bus_type);
return ret;
......@@ -1018,7 +1003,6 @@ static int __init soc_camera_init(void)
static void __exit soc_camera_exit(void)
{
class_unregister(&soc_camera_host_class);
driver_unregister(&ic_drv);
bus_unregister(&soc_camera_bus_type);
}
......
......@@ -51,12 +51,51 @@
#define VIDEO_NUM_DEVICES 256
#define VIDEO_NAME "video4linux"
struct std_descr {
v4l2_std_id std;
const char *descr;
};
static const struct std_descr standards[] = {
{ V4L2_STD_NTSC, "NTSC" },
{ V4L2_STD_NTSC_M, "NTSC-M" },
{ V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
{ V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
{ V4L2_STD_NTSC_443, "NTSC-443" },
{ V4L2_STD_PAL, "PAL" },
{ V4L2_STD_PAL_BG, "PAL-BG" },
{ V4L2_STD_PAL_B, "PAL-B" },
{ V4L2_STD_PAL_B1, "PAL-B1" },
{ V4L2_STD_PAL_G, "PAL-G" },
{ V4L2_STD_PAL_H, "PAL-H" },
{ V4L2_STD_PAL_I, "PAL-I" },
{ V4L2_STD_PAL_DK, "PAL-DK" },
{ V4L2_STD_PAL_D, "PAL-D" },
{ V4L2_STD_PAL_D1, "PAL-D1" },
{ V4L2_STD_PAL_K, "PAL-K" },
{ V4L2_STD_PAL_M, "PAL-M" },
{ V4L2_STD_PAL_N, "PAL-N" },
{ V4L2_STD_PAL_Nc, "PAL-Nc" },
{ V4L2_STD_PAL_60, "PAL-60" },
{ V4L2_STD_SECAM, "SECAM" },
{ V4L2_STD_SECAM_B, "SECAM-B" },
{ V4L2_STD_SECAM_G, "SECAM-G" },
{ V4L2_STD_SECAM_H, "SECAM-H" },
{ V4L2_STD_SECAM_DK, "SECAM-DK" },
{ V4L2_STD_SECAM_D, "SECAM-D" },
{ V4L2_STD_SECAM_K, "SECAM-K" },
{ V4L2_STD_SECAM_K1, "SECAM-K1" },
{ V4L2_STD_SECAM_L, "SECAM-L" },
{ V4L2_STD_SECAM_LC, "SECAM-Lc" },
{ 0, "Unknown" }
};
/* video4linux standard ID conversion to standard name
*/
char *v4l2_norm_to_name(v4l2_std_id id)
const char *v4l2_norm_to_name(v4l2_std_id id)
{
char *name;
u32 myid = id;
int i;
/* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
64 bit comparations. So, on that architecture, with some gcc
......@@ -64,110 +103,17 @@ char *v4l2_norm_to_name(v4l2_std_id id)
*/
BUG_ON(myid != id);
switch (myid) {
case V4L2_STD_PAL:
name = "PAL";
break;
case V4L2_STD_PAL_BG:
name = "PAL-BG";
break;
case V4L2_STD_PAL_DK:
name = "PAL-DK";
break;
case V4L2_STD_PAL_B:
name = "PAL-B";
break;
case V4L2_STD_PAL_B1:
name = "PAL-B1";
break;
case V4L2_STD_PAL_G:
name = "PAL-G";
break;
case V4L2_STD_PAL_H:
name = "PAL-H";
break;
case V4L2_STD_PAL_I:
name = "PAL-I";
break;
case V4L2_STD_PAL_D:
name = "PAL-D";
break;
case V4L2_STD_PAL_D1:
name = "PAL-D1";
break;
case V4L2_STD_PAL_K:
name = "PAL-K";
break;
case V4L2_STD_PAL_M:
name = "PAL-M";
break;
case V4L2_STD_PAL_N:
name = "PAL-N";
break;
case V4L2_STD_PAL_Nc:
name = "PAL-Nc";
break;
case V4L2_STD_PAL_60:
name = "PAL-60";
break;
case V4L2_STD_NTSC:
name = "NTSC";
break;
case V4L2_STD_NTSC_M:
name = "NTSC-M";
break;
case V4L2_STD_NTSC_M_JP:
name = "NTSC-M-JP";
break;
case V4L2_STD_NTSC_443:
name = "NTSC-443";
break;
case V4L2_STD_NTSC_M_KR:
name = "NTSC-M-KR";
break;
case V4L2_STD_SECAM:
name = "SECAM";
break;
case V4L2_STD_SECAM_DK:
name = "SECAM-DK";
break;
case V4L2_STD_SECAM_B:
name = "SECAM-B";
break;
case V4L2_STD_SECAM_D:
name = "SECAM-D";
break;
case V4L2_STD_SECAM_G:
name = "SECAM-G";
break;
case V4L2_STD_SECAM_H:
name = "SECAM-H";
break;
case V4L2_STD_SECAM_K:
name = "SECAM-K";
break;
case V4L2_STD_SECAM_K1:
name = "SECAM-K1";
break;
case V4L2_STD_SECAM_L:
name = "SECAM-L";
break;
case V4L2_STD_SECAM_LC:
name = "SECAM-LC";
break;
default:
name = "Unknown";
break;
}
return name;
for (i = 0; standards[i].std; i++)
if (myid == standards[i].std)
break;
return standards[i].descr;
}
EXPORT_SYMBOL(v4l2_norm_to_name);
/* Fill in the fields of a v4l2_standard structure according to the
'id' and 'transmission' parameters. Returns negative on error. */
int v4l2_video_std_construct(struct v4l2_standard *vs,
int id, char *name)
int id, const char *name)
{
u32 index = vs->index;
......@@ -1218,95 +1164,40 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_ENUMSTD:
{
struct v4l2_standard *p = arg;
v4l2_std_id id = vfd->tvnorms,curr_id=0;
unsigned int index = p->index,i;
if (index<0) {
ret=-EINVAL;
break;
}
/* Return norm array on a canonical way */
for (i=0;i<= index && id; i++) {
if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
curr_id = V4L2_STD_PAL;
} else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
curr_id = V4L2_STD_PAL_BG;
} else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
curr_id = V4L2_STD_PAL_DK;
} else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
curr_id = V4L2_STD_PAL_B;
} else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
curr_id = V4L2_STD_PAL_B1;
} else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
curr_id = V4L2_STD_PAL_G;
} else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
curr_id = V4L2_STD_PAL_H;
} else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
curr_id = V4L2_STD_PAL_I;
} else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
curr_id = V4L2_STD_PAL_D;
} else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
curr_id = V4L2_STD_PAL_D1;
} else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
curr_id = V4L2_STD_PAL_K;
} else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
curr_id = V4L2_STD_PAL_M;
} else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
curr_id = V4L2_STD_PAL_N;
} else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
curr_id = V4L2_STD_PAL_Nc;
} else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
curr_id = V4L2_STD_PAL_60;
} else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
curr_id = V4L2_STD_NTSC;
} else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
curr_id = V4L2_STD_NTSC_M;
} else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
curr_id = V4L2_STD_NTSC_M_JP;
} else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
curr_id = V4L2_STD_NTSC_443;
} else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
curr_id = V4L2_STD_NTSC_M_KR;
} else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
curr_id = V4L2_STD_SECAM;
} else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
curr_id = V4L2_STD_SECAM_DK;
} else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
curr_id = V4L2_STD_SECAM_B;
} else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
curr_id = V4L2_STD_SECAM_D;
} else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
curr_id = V4L2_STD_SECAM_G;
} else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
curr_id = V4L2_STD_SECAM_H;
} else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
curr_id = V4L2_STD_SECAM_K;
} else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
curr_id = V4L2_STD_SECAM_K1;
} else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
curr_id = V4L2_STD_SECAM_L;
} else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
curr_id = V4L2_STD_SECAM_LC;
} else {
v4l2_std_id id = vfd->tvnorms, curr_id = 0;
unsigned int index = p->index, i, j = 0;
const char *descr = "";
/* Return norm array in a canonical way */
for (i = 0; i <= index && id; i++) {
/* last std value in the standards array is 0, so this
while always ends there since (id & 0) == 0. */
while ((id & standards[j].std) != standards[j].std)
j++;
curr_id = standards[j].std;
descr = standards[j].descr;
j++;
if (curr_id == 0)
break;
}
id &= ~curr_id;
if (curr_id != V4L2_STD_PAL &&
curr_id != V4L2_STD_SECAM &&
curr_id != V4L2_STD_NTSC)
id &= ~curr_id;
}
if (i<=index)
if (i <= index)
return -EINVAL;
v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
v4l2_video_std_construct(p, curr_id, descr);
p->index = index;
dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
dbgarg(cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
"framelines=%d\n", p->index,
(unsigned long long)p->id, p->name,
p->frameperiod.numerator,
p->frameperiod.denominator,
p->framelines);
ret=0;
ret = 0;
break;
}
case VIDIOC_G_STD:
......
......@@ -327,13 +327,14 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
int hmax = buf->vb.height;
int wmax = buf->vb.width;
struct timeval ts;
char *tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC);
char *tmpbuf;
void *vbuf = videobuf_to_vmalloc(&buf->vb);
if (!tmpbuf)
if (!vbuf)
return;
if (!vbuf)
tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC);
if (!tmpbuf)
return;
for (h = 0; h < hmax; h++) {
......
......@@ -32,12 +32,16 @@ enum cx25840_video_input {
CX25840_COMPOSITE7,
CX25840_COMPOSITE8,
/* S-Video inputs consist of one luma input (In1-In4) ORed with one
/* S-Video inputs consist of one luma input (In1-In8) ORed with one
chroma input (In5-In8) */
CX25840_SVIDEO_LUMA1 = 0x10,
CX25840_SVIDEO_LUMA2 = 0x20,
CX25840_SVIDEO_LUMA3 = 0x30,
CX25840_SVIDEO_LUMA4 = 0x40,
CX25840_SVIDEO_LUMA5 = 0x50,
CX25840_SVIDEO_LUMA6 = 0x60,
CX25840_SVIDEO_LUMA7 = 0x70,
CX25840_SVIDEO_LUMA8 = 0x80,
CX25840_SVIDEO_CHROMA4 = 0x400,
CX25840_SVIDEO_CHROMA5 = 0x500,
CX25840_SVIDEO_CHROMA6 = 0x600,
......
......@@ -146,6 +146,7 @@ extern IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE];
#endif
......
......@@ -40,9 +40,9 @@
#define VFL_TYPE_VTX 3
/* Video standard functions */
extern char *v4l2_norm_to_name(v4l2_std_id id);
extern const char *v4l2_norm_to_name(v4l2_std_id id);
extern int v4l2_video_std_construct(struct v4l2_standard *vs,
int id, char *name);
int id, const char *name);
/* Prints the ioctl in a human-readable format */
extern void v4l_printk_ioctl(unsigned int cmd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment