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

* 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (101 commits)
  [media] staging/lirc: fix mem leaks and ptr err usage
  [media] hdpvr: reduce latency of i2c read/write w/recycled buffer
  [media] hdpvr: enable IR part
  [media] rc/mceusb: timeout should be in ns, not us
  [media] v4l2-device: fix 'use-after-freed' oops
  [media] v4l2-dev: don't memset video_device.dev
  [media] zoran: use video_device_alloc instead of kmalloc
  [media] w9966: zero device state after a detach
  [media] v4l: Fix a use-before-set in the control framework
  [media] v4l: Include linux/videodev2.h in media/v4l2-ctrls.h
  [media] DocBook/v4l: update V4L2 revision and update copyright years
  [media] DocBook/v4l: fix validation error in dev-rds.xml
  [media] v4l2-ctrls: queryctrl shouldn't attempt to replace V4L2_CID_PRIVATE_BASE IDs
  [media] v4l2-ctrls: fix missing 'read-only' check
  [media] pvrusb2: Provide more information about IR units to lirc_zilog and ir-kbd-i2c
  [media] ir-kbd-i2c: Add back defaults setting for Zilog Z8's at addr 0x71
  [media] lirc_zilog: Update TODO.lirc_zilog
  [media] lirc_zilog: Add Andy Walls to copyright notice and authors list
  [media] lirc_zilog: Remove useless struct i2c_driver.command function
  [media] lirc_zilog: Remove unneeded tests for existence of the IR Tx function
  ...
This commit is contained in:
Linus Torvalds 2011-01-21 16:50:31 -08:00
commit 13a3cec844
133 changed files with 2461 additions and 2680 deletions

View file

@ -28,7 +28,7 @@
<holder>Convergence GmbH</holder>
</copyright>
<copyright>
<year>2009-2010</year>
<year>2009-2011</year>
<holder>Mauro Carvalho Chehab</holder>
</copyright>

View file

@ -28,7 +28,7 @@
<title>LINUX MEDIA INFRASTRUCTURE API</title>
<copyright>
<year>2009-2010</year>
<year>2009-2011</year>
<holder>LinuxTV Developers</holder>
</copyright>
@ -86,7 +86,7 @@ Foundation. A copy of the license is included in the chapter entitled
</author>
</authorgroup>
<copyright>
<year>2009-2010</year>
<year>2009-2011</year>
<holder>Mauro Carvalho Chehab</holder>
</copyright>

View file

@ -75,6 +75,7 @@ as follows:</para>
</section>
<section>
<title>RDS datastructures</title>
<table frame="none" pgwide="1" id="v4l2-rds-data">
<title>struct
<structname>v4l2_rds_data</structname></title>
@ -129,10 +130,11 @@ as follows:</para>
<table frame="none" pgwide="1" id="v4l2-rds-block-codes">
<title>Block defines</title>
<tgroup cols="3">
<tgroup cols="4">
<colspec colname="c1" colwidth="1*" />
<colspec colname="c2" colwidth="1*" />
<colspec colname="c3" colwidth="5*" />
<colspec colname="c3" colwidth="1*" />
<colspec colname="c4" colwidth="5*" />
<tbody valign="top">
<row>
<entry>V4L2_RDS_BLOCK_MSK</entry>

View file

@ -100,6 +100,7 @@ Remote Controller chapter.</contrib>
<year>2008</year>
<year>2009</year>
<year>2010</year>
<year>2011</year>
<holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder>
</copyright>
@ -381,7 +382,7 @@ and discussions on the V4L mailing list.</revremark>
</partinfo>
<title>Video for Linux Two API Specification</title>
<subtitle>Revision 2.6.33</subtitle>
<subtitle>Revision 2.6.38</subtitle>
<chapter id="common">
&sub-common;

View file

@ -285,6 +285,9 @@ implement g_volatile_ctrl like this:
The 'new value' union is not used in g_volatile_ctrl. In general controls
that need to implement g_volatile_ctrl are read-only controls.
Note that if one or more controls in a control cluster are marked as volatile,
then all the controls in the cluster are seen as volatile.
To mark a control as volatile you have to set the is_volatile flag:
ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...);
@ -462,6 +465,15 @@ pointer to the v4l2_ctrl_ops struct that is used for that cluster.
Obviously, all controls in the cluster array must be initialized to either
a valid control or to NULL.
In rare cases you might want to know which controls of a cluster actually
were set explicitly by the user. For this you can check the 'is_new' flag of
each control. For example, in the case of a volume/mute cluster the 'is_new'
flag of the mute control would be set if the user called VIDIOC_S_CTRL for
mute only. If the user would call VIDIOC_S_EXT_CTRLS for both mute and volume
controls, then the 'is_new' flag would be 1 for both controls.
The 'is_new' flag is always 1 when called from v4l2_ctrl_handler_setup().
VIDIOC_LOG_STATUS Support
=========================

View file

@ -452,7 +452,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device));
dev->ext = ext;
mutex_init(&dev->lock);
mutex_init(&dev->v4l2_lock);
spin_lock_init(&dev->int_slock);
spin_lock_init(&dev->slock);

View file

@ -15,18 +15,15 @@ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
}
/* is it free? */
mutex_lock(&dev->lock);
if (vv->resources & bit) {
DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
/* no, someone else uses it */
mutex_unlock(&dev->lock);
return 0;
}
/* it's free, grab it */
fh->resources |= bit;
vv->resources |= bit;
DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources));
mutex_unlock(&dev->lock);
return 1;
}
@ -37,11 +34,9 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
BUG_ON((fh->resources & bits) != bits);
mutex_lock(&dev->lock);
fh->resources &= ~bits;
vv->resources &= ~bits;
DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources));
mutex_unlock(&dev->lock);
}
@ -396,7 +391,7 @@ static const struct v4l2_file_operations video_fops =
.write = fops_write,
.poll = fops_poll,
.mmap = fops_mmap,
.ioctl = video_ioctl2,
.unlocked_ioctl = video_ioctl2,
};
static void vv_callback(struct saa7146_dev *dev, unsigned long status)
@ -505,6 +500,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
vfd->fops = &video_fops;
vfd->ioctl_ops = &dev->ext_vv_data->ops;
vfd->release = video_device_release;
vfd->lock = &dev->v4l2_lock;
vfd->tvnorms = 0;
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
vfd->tvnorms |= dev->ext_vv_data->stds[i].id;

View file

@ -412,7 +412,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
V4L2_BUF_TYPE_VBI_CAPTURE,
V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
sizeof(struct saa7146_buf),
file, NULL);
file, &dev->v4l2_lock);
init_timer(&fh->vbi_read_timeout);
fh->vbi_read_timeout.function = vbi_read_timeout;

View file

@ -553,8 +553,6 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
}
}
mutex_lock(&dev->lock);
/* ok, accept it */
vv->ov_fb = *fb;
vv->ov_fmt = fmt;
@ -563,8 +561,6 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline));
}
mutex_unlock(&dev->lock);
return 0;
}
@ -649,8 +645,6 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
return -EINVAL;
}
mutex_lock(&dev->lock);
switch (ctrl->type) {
case V4L2_CTRL_TYPE_BOOLEAN:
case V4L2_CTRL_TYPE_MENU:
@ -693,7 +687,6 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
/* fixme: we can support changing VFLIP and HFLIP here... */
if (IS_CAPTURE_ACTIVE(fh) != 0) {
DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
mutex_unlock(&dev->lock);
return -EBUSY;
}
vv->hflip = c->value;
@ -701,16 +694,13 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
case V4L2_CID_VFLIP:
if (IS_CAPTURE_ACTIVE(fh) != 0) {
DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
mutex_unlock(&dev->lock);
return -EBUSY;
}
vv->vflip = c->value;
break;
default:
mutex_unlock(&dev->lock);
return -EINVAL;
}
mutex_unlock(&dev->lock);
if (IS_OVERLAY_ACTIVE(fh) != 0) {
saa7146_stop_preview(fh);
@ -902,22 +892,18 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_f
err = vidioc_try_fmt_vid_overlay(file, fh, f);
if (0 != err)
return err;
mutex_lock(&dev->lock);
fh->ov.win = f->fmt.win;
fh->ov.nclips = f->fmt.win.clipcount;
if (fh->ov.nclips > 16)
fh->ov.nclips = 16;
if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
sizeof(struct v4l2_clip) * fh->ov.nclips)) {
mutex_unlock(&dev->lock);
return -EFAULT;
}
/* fh->ov.fh is used to indicate that we have valid overlay informations, too */
fh->ov.fh = fh;
mutex_unlock(&dev->lock);
/* check if our current overlay is active */
if (IS_OVERLAY_ACTIVE(fh) != 0) {
saa7146_stop_preview(fh);
@ -976,8 +962,6 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
}
}
mutex_lock(&dev->lock);
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
if (*id & dev->ext_vv_data->stds[i].id)
break;
@ -988,8 +972,6 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
found = 1;
}
mutex_unlock(&dev->lock);
if (vv->ov_suspend != NULL) {
saa7146_start_preview(vv->ov_suspend);
vv->ov_suspend = NULL;
@ -1354,7 +1336,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_INTERLACED,
sizeof(struct saa7146_buf),
file, NULL);
file, &dev->v4l2_lock);
return 0;
}

View file

@ -95,8 +95,7 @@ static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close)
msleep(20);
} else {
msg = disable;
tuner_i2c_xfer_send(&priv->i2c_props, msg, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props, msg, 1, &msg[1], 1);
buf[2] = msg[1];
buf[2] &= ~0x04;
@ -233,19 +232,22 @@ static void tda8290_set_params(struct dvb_frontend *fe,
tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
}
tda8290_i2c_bridge(fe, 1);
if (fe->ops.tuner_ops.set_analog_params)
fe->ops.tuner_ops.set_analog_params(fe, params);
for (i = 0; i < 3; i++) {
tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&addr_pll_stat, 1, &pll_stat, 1);
if (pll_stat & 0x80) {
tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&addr_adc_sat, 1,
&adc_sat, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&addr_agc_stat, 1,
&agc_stat, 1);
tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
break;
} else {
@ -259,20 +261,22 @@ static void tda8290_set_params(struct dvb_frontend *fe,
agc_stat, adc_sat, pll_stat & 0x80);
tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
msleep(100);
tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&addr_agc_stat, 1, &agc_stat, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&addr_pll_stat, 1, &pll_stat, 1);
if ((agc_stat > 115) || !(pll_stat & 0x80)) {
tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
agc_stat, pll_stat & 0x80);
if (priv->cfg.agcf)
priv->cfg.agcf(fe);
msleep(100);
tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&addr_agc_stat, 1,
&agc_stat, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&addr_pll_stat, 1,
&pll_stat, 1);
if((agc_stat > 115) || !(pll_stat & 0x80)) {
tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
@ -284,10 +288,12 @@ static void tda8290_set_params(struct dvb_frontend *fe,
/* l/ l' deadlock? */
if(priv->tda8290_easy_mode & 0x60) {
tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&addr_adc_sat, 1,
&adc_sat, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&addr_pll_stat, 1,
&pll_stat, 1);
if ((adc_sat > 20) || !(pll_stat & 0x80)) {
tuner_dbg("trying to resolve SECAM L deadlock\n");
tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
@ -307,8 +313,7 @@ static void tda8295_power(struct dvb_frontend *fe, int enable)
struct tda8290_priv *priv = fe->analog_demod_priv;
unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */
tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
if (enable)
buf[1] = 0x01;
@ -323,8 +328,7 @@ static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable)
struct tda8290_priv *priv = fe->analog_demod_priv;
unsigned char buf[] = { 0x01, 0x00 };
tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
if (enable)
buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */
@ -353,8 +357,7 @@ static void tda8295_agc1_out(struct dvb_frontend *fe, int enable)
struct tda8290_priv *priv = fe->analog_demod_priv;
unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */
tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
if (enable)
buf[1] &= ~0x40;
@ -370,10 +373,10 @@ static void tda8295_agc2_out(struct dvb_frontend *fe, int enable)
unsigned char set_gpio_cf[] = { 0x44, 0x00 };
unsigned char set_gpio_val[] = { 0x46, 0x00 };
tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1);
tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&set_gpio_cf[0], 1, &set_gpio_cf[1], 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&set_gpio_val[0], 1, &set_gpio_val[1], 1);
set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */
@ -392,8 +395,7 @@ static int tda8295_has_signal(struct dvb_frontend *fe)
unsigned char hvpll_stat = 0x26;
unsigned char ret;
tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1);
return (ret & 0x01) ? 65535 : 0;
}
@ -413,8 +415,8 @@ static void tda8295_set_params(struct dvb_frontend *fe,
tda8295_power(fe, 1);
tda8295_agc1_out(fe, 1);
tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1);
tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
&blanking_mode[0], 1, &blanking_mode[1], 1);
tda8295_set_video_std(fe);
@ -447,8 +449,8 @@ static int tda8290_has_signal(struct dvb_frontend *fe)
unsigned char i2c_get_afc[1] = { 0x1B };
unsigned char afc = 0;
tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1);
tuner_i2c_xfer_send_recv(&priv->i2c_props,
i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1);
return (afc & 0x80)? 65535:0;
}
@ -654,20 +656,26 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
static int tda8290_probe(struct tuner_i2c_props *i2c_props)
{
#define TDA8290_ID 0x89
unsigned char tda8290_id[] = { 0x1f, 0x00 };
u8 reg = 0x1f, id;
struct i2c_msg msg_read[] = {
{ .addr = 0x4b, .flags = 0, .len = 1, .buf = &reg },
{ .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id },
};
/* detect tda8290 */
tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1);
tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1);
if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n",
__func__, reg);
return -ENODEV;
}
if (tda8290_id[1] == TDA8290_ID) {
if (id == TDA8290_ID) {
if (debug)
printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n",
__func__, i2c_adapter_id(i2c_props->adap),
i2c_props->addr);
return 0;
}
return -ENODEV;
}
@ -675,16 +683,23 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props)
{
#define TDA8295_ID 0x8a
#define TDA8295C2_ID 0x8b
unsigned char tda8295_id[] = { 0x2f, 0x00 };
u8 reg = 0x2f, id;
struct i2c_msg msg_read[] = {
{ .addr = 0x4b, .flags = 0, .len = 1, .buf = &reg },
{ .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id },
};
/* detect tda8295 */
tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1);
tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1);
/* detect tda8290 */
if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n",
__func__, reg);
return -ENODEV;
}
if ((tda8295_id[1] & 0xfe) == TDA8295_ID) {
if ((id & 0xfe) == TDA8295_ID) {
if (debug)
printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n",
__func__, (tda8295_id[1] == TDA8295_ID) ?
__func__, (id == TDA8295_ID) ?
"tda8295c1" : "tda8295c2",
i2c_adapter_id(i2c_props->adap),
i2c_props->addr);
@ -740,9 +755,11 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
sizeof(struct analog_demod_ops));
}
if ((!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) &&
(tda829x_find_tuner(fe) < 0))
goto fail;
if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) {
tda8295_power(fe, 1);
if (tda829x_find_tuner(fe) < 0)
goto fail;
}
switch (priv->ver) {
case TDA8290:
@ -786,6 +803,8 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
return fe;
fail:
memset(&fe->ops.analog_ops, 0, sizeof(struct analog_demod_ops));
tda829x_release(fe);
return NULL;
}
@ -809,8 +828,8 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
int i;
/* rule out tda9887, which would return the same byte repeatedly */
tuner_i2c_xfer_send(&i2c_props, soft_reset, 1);
tuner_i2c_xfer_recv(&i2c_props, buf, PROBE_BUFFER_SIZE);
tuner_i2c_xfer_send_recv(&i2c_props,
soft_reset, 1, buf, PROBE_BUFFER_SIZE);
for (i = 1; i < PROBE_BUFFER_SIZE; i++) {
if (buf[i] != buf[0])
break;
@ -827,13 +846,12 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
/* fall back to old probing method */
tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
tuner_i2c_xfer_recv(&i2c_props, &data, 1);
tuner_i2c_xfer_send_recv(&i2c_props, &addr_dto_lsb, 1, &data, 1);
if (data == 0) {
tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
tuner_i2c_xfer_recv(&i2c_props, &data, 1);
tuner_i2c_xfer_send_recv(&i2c_props,
&addr_dto_lsb, 1, &data, 1);
if (data == 0x7b) {
return 0;
}

View file

@ -514,8 +514,8 @@ struct dib0700_rc_response {
union {
u16 system16;
struct {
u8 system;
u8 not_system;
u8 system;
};
};
u8 data;
@ -575,7 +575,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
deb_data("NEC extended protocol\n");
/* NEC extended code - 24 bits */
keycode = poll_reply->system16 << 8 | poll_reply->data;
keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data;
} else {
deb_data("NEC normal protocol\n");
/* normal NEC code - 16 bits */
@ -587,7 +587,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
deb_data("RC5 protocol\n");
/* RC5 Protocol */
toggle = poll_reply->report_id;
keycode = poll_reply->system16 << 8 | poll_reply->data;
keycode = poll_reply->system << 8 | poll_reply->data;
break;
}

View file

@ -172,7 +172,8 @@ void fdtv_unregister_rc(struct firedtv *fdtv)
void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
{
u16 *keycode = fdtv->remote_ctrl_dev->keycode;
struct input_dev *idev = fdtv->remote_ctrl_dev;
u16 *keycode = idev->keycode;
if (code >= 0x0300 && code <= 0x031f)
code = keycode[code - 0x0300];
@ -188,6 +189,8 @@ void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
return;
}
input_report_key(fdtv->remote_ctrl_dev, code, 1);
input_report_key(fdtv->remote_ctrl_dev, code, 0);
input_report_key(idev, code, 1);
input_sync(idev);
input_report_key(idev, code, 0);
input_sync(idev);
}

View file

@ -334,11 +334,11 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw)
if_sample_freq = 3300000; /* 3.3 MHz */
break;
case BANDWIDTH_7_MHZ:
if_sample_freq = 3800000; /* 3.8 MHz */
if_sample_freq = 3500000; /* 3.5 MHz */
break;
case BANDWIDTH_8_MHZ:
default:
if_sample_freq = 4300000; /* 4.3 MHz */
if_sample_freq = 4000000; /* 4.0 MHz */
break;
}
} else if (state->config.tuner == AF9013_TUNER_TDA18218) {

View file

@ -311,7 +311,7 @@ struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
return fe;
error:
ix2505v_release(fe);
kfree(state);
return NULL;
}
EXPORT_SYMBOL(ix2505v_attach);

View file

@ -43,6 +43,8 @@ struct mb86a20s_state {
const struct mb86a20s_config *config;
struct dvb_frontend frontend;
bool need_init;
};
struct regdata {
@ -318,7 +320,7 @@ static int mb86a20s_i2c_writereg(struct mb86a20s_state *state,
rc = i2c_transfer(state->i2c, &msg, 1);
if (rc != 1) {
printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
printk("%s: writereg error (rc == %i, reg == 0x%02x,"
" data == 0x%02x)\n", __func__, rc, reg, data);
return rc;
}
@ -353,7 +355,7 @@ static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
rc = i2c_transfer(state->i2c, msg, 2);
if (rc != 2) {
rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
rc("%s: reg=0x%x (error=%d)\n", __func__, reg, rc);
return rc;
}
@ -382,23 +384,31 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
/* Initialize the frontend */
rc = mb86a20s_writeregdata(state, mb86a20s_init);
if (rc < 0)
return rc;
goto err;
if (!state->config->is_serial) {
regD5 &= ~1;
rc = mb86a20s_writereg(state, 0x50, 0xd5);
if (rc < 0)
return rc;
goto err;
rc = mb86a20s_writereg(state, 0x51, regD5);
if (rc < 0)
return rc;
goto err;
}
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
return 0;
err:
if (rc < 0) {
state->need_init = true;
printk(KERN_INFO "mb86a20s: Init failed. Will try again later\n");
} else {
state->need_init = false;
dprintk("Initialization succeded.\n");
}
return rc;
}
static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
@ -485,8 +495,22 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe,
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
dprintk("Calling tuner set parameters\n");
fe->ops.tuner_ops.set_params(fe, p);
/*
* Make it more reliable: if, for some reason, the initial
* device initialization doesn't happen, initialize it when
* a SBTVD parameters are adjusted.
*
* Unfortunately, due to a hard to track bug at tda829x/tda18271,
* the agc callback logic is not called during DVB attach time,
* causing mb86a20s to not be initialized with Kworld SBTVD.
* So, this hack is needed, in order to make Kworld SBTVD to work.
*/
if (state->need_init)
mb86a20s_initfe(fe);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);

View file

@ -277,7 +277,7 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg)
{
ca_slot_info_t *info=(ca_slot_info_t *)parg;
if (info->num > 1)
if (info->num < 0 || info->num > 1)
return -EINVAL;
av7110->ci_slot[info->num].num = info->num;
av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?

View file

@ -151,20 +151,6 @@ config RADIO_GEMTEK_PROBE
following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and
0x28c.
config RADIO_GEMTEK_PCI
tristate "GemTek PCI Radio Card support"
depends on VIDEO_V4L2 && PCI
---help---
Choose Y here if you have this PCI FM radio card.
In order to control your radio card, you will need to use programs
that are compatible with the Video for Linux API. Information on
this API and pointers to "v4l" programs may be found at
<file:Documentation/video4linux/API.html>.
To compile this driver as a module, choose M here: the
module will be called radio-gemtek-pci.
config RADIO_MAXIRADIO
tristate "Guillemot MAXI Radio FM 2000 radio"
depends on VIDEO_V4L2 && PCI

View file

@ -13,7 +13,6 @@ obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o
obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o

View file

@ -31,6 +31,7 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* msleep */
#include <linux/videodev2.h> /* kernel radio structs */
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/io.h> /* outb, outb_p */

View file

@ -1,478 +0,0 @@
/*
***************************************************************************
*
* radio-gemtek-pci.c - Gemtek PCI Radio driver
* (C) 2001 Vladimir Shebordaev <vshebordaev@mail.ru>
*
***************************************************************************
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
* USA.
*
***************************************************************************
*
* Gemtek Corp still silently refuses to release any specifications
* of their multimedia devices, so the protocol still has to be
* reverse engineered.
*
* The v4l code was inspired by Jonas Munsin's Gemtek serial line
* radio device driver.
*
* Please, let me know if this piece of code was useful :)
*
* TODO: multiple device support and portability were not tested
*
* Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*
***************************************************************************
*/
#include <linux/types.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/videodev2.h>
#include <linux/errno.h>
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/io.h>
#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
MODULE_AUTHOR("Vladimir Shebordaev <vshebordaev@mail.ru>");
MODULE_DESCRIPTION("The video4linux driver for the Gemtek PCI Radio Card");
MODULE_LICENSE("GPL");
static int nr_radio = -1;
static int mx = 1;
module_param(mx, bool, 0);
MODULE_PARM_DESC(mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not");
module_param(nr_radio, int, 0);
MODULE_PARM_DESC(nr_radio, "video4linux device number to use");
#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
#ifndef PCI_VENDOR_ID_GEMTEK
#define PCI_VENDOR_ID_GEMTEK 0x5046
#endif
#ifndef PCI_DEVICE_ID_GEMTEK_PR103
#define PCI_DEVICE_ID_GEMTEK_PR103 0x1001
#endif
#ifndef GEMTEK_PCI_RANGE_LOW
#define GEMTEK_PCI_RANGE_LOW (87*16000)
#endif
#ifndef GEMTEK_PCI_RANGE_HIGH
#define GEMTEK_PCI_RANGE_HIGH (108*16000)
#endif
struct gemtek_pci {
struct v4l2_device v4l2_dev;
struct video_device vdev;
struct mutex lock;
struct pci_dev *pdev;
u32 iobase;
u32 length;
u32 current_frequency;
u8 mute;
};
static inline struct gemtek_pci *to_gemtek_pci(struct v4l2_device *v4l2_dev)
{
return container_of(v4l2_dev, struct gemtek_pci, v4l2_dev);
}
static inline u8 gemtek_pci_out(u16 value, u32 port)
{
outw(value, port);
return (u8)value;
}
#define _b0(v) (*((u8 *)&v))
static void __gemtek_pci_cmd(u16 value, u32 port, u8 *last_byte, int keep)
{
u8 byte = *last_byte;
if (!value) {
if (!keep)
value = (u16)port;
byte &= 0xfd;
} else
byte |= 2;
_b0(value) = byte;
outw(value, port);
byte |= 1;
_b0(value) = byte;
outw(value, port);
byte &= 0xfe;
_b0(value) = byte;
outw(value, port);
*last_byte = byte;
}
static inline void gemtek_pci_nil(u32 port, u8 *last_byte)
{
__gemtek_pci_cmd(0x00, port, last_byte, false);
}
static inline void gemtek_pci_cmd(u16 cmd, u32 port, u8 *last_byte)
{
__gemtek_pci_cmd(cmd, port, last_byte, true);
}
static void gemtek_pci_setfrequency(struct gemtek_pci *card, unsigned long frequency)
{
int i;
u32 value = frequency / 200 + 856;
u16 mask = 0x8000;
u8 last_byte;
u32 port = card->iobase;
mutex_lock(&card->lock);
card->current_frequency = frequency;
last_byte = gemtek_pci_out(0x06, port);
i = 0;
do {
gemtek_pci_nil(port, &last_byte);
i++;
} while (i < 9);
i = 0;
do {
gemtek_pci_cmd(value & mask, port, &last_byte);
mask >>= 1;
i++;
} while (i < 16);
outw(0x10, port);
mutex_unlock(&card->lock);
}
static void gemtek_pci_mute(struct gemtek_pci *card)
{
mutex_lock(&card->lock);
outb(0x1f, card->iobase);
card->mute = true;
mutex_unlock(&card->lock);
}
static void gemtek_pci_unmute(struct gemtek_pci *card)
{
if (card->mute) {
gemtek_pci_setfrequency(card, card->current_frequency);
card->mute = false;
}
}
static int gemtek_pci_getsignal(struct gemtek_pci *card)
{
int sig;
mutex_lock(&card->lock);
sig = (inb(card->iobase) & 0x08) ? 0 : 1;
mutex_unlock(&card->lock);
return sig;
}
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
struct gemtek_pci *card = video_drvdata(file);
strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));
strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card));
snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(card->pdev));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct gemtek_pci *card = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
v->rangelow = GEMTEK_PCI_RANGE_LOW;
v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
v->signal = 0xffff * gemtek_pci_getsignal(card);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
struct gemtek_pci *card = video_drvdata(file);
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
return -EINVAL;
if (f->frequency < GEMTEK_PCI_RANGE_LOW ||
f->frequency > GEMTEK_PCI_RANGE_HIGH)
return -EINVAL;
gemtek_pci_setfrequency(card, f->frequency);
card->mute = false;
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
struct gemtek_pci *card = video_drvdata(file);
if (f->tuner != 0)
return -EINVAL;
f->type = V4L2_TUNER_RADIO;
f->frequency = card->current_frequency;
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
switch (qc->id) {
case V4L2_CID_AUDIO_MUTE:
return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
case V4L2_CID_AUDIO_VOLUME:
return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
}
return -EINVAL;
}
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct gemtek_pci *card = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
ctrl->value = card->mute;
return 0;
case V4L2_CID_AUDIO_VOLUME:
if (card->mute)
ctrl->value = 0;
else
ctrl->value = 65535;
return 0;
}
return -EINVAL;
}
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct gemtek_pci *card = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value)
gemtek_pci_mute(card);
else
gemtek_pci_unmute(card);
return 0;
case V4L2_CID_AUDIO_VOLUME:
if (ctrl->value)
gemtek_pci_unmute(card);
else
gemtek_pci_mute(card);
return 0;
}
return -EINVAL;
}
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
return 0;
}
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
return i ? -EINVAL : 0;
}
static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
a->index = 0;
strlcpy(a->name, "Radio", sizeof(a->name));
a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
return a->index ? -EINVAL : 0;
}
enum {
GEMTEK_PR103
};
static char *card_names[] __devinitdata = {
"GEMTEK_PR103"
};
static struct pci_device_id gemtek_pci_id[] =
{
{ PCI_VENDOR_ID_GEMTEK, PCI_DEVICE_ID_GEMTEK_PR103,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, GEMTEK_PR103 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
static const struct v4l2_file_operations gemtek_pci_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_audio = vidioc_g_audio,
.vidioc_s_audio = vidioc_s_audio,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_queryctrl = vidioc_queryctrl,
.vidioc_g_ctrl = vidioc_g_ctrl,
.vidioc_s_ctrl = vidioc_s_ctrl,
};
static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
{
struct gemtek_pci *card;
struct v4l2_device *v4l2_dev;
int res;
card = kzalloc(sizeof(struct gemtek_pci), GFP_KERNEL);
if (card == NULL) {
dev_err(&pdev->dev, "out of memory\n");
return -ENOMEM;
}
v4l2_dev = &card->v4l2_dev;
mutex_init(&card->lock);
card->pdev = pdev;
strlcpy(v4l2_dev->name, "gemtek_pci", sizeof(v4l2_dev->name));
res = v4l2_device_register(&pdev->dev, v4l2_dev);
if (res < 0) {
v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
kfree(card);
return res;
}
if (pci_enable_device(pdev))
goto err_pci;
card->iobase = pci_resource_start(pdev, 0);
card->length = pci_resource_len(pdev, 0);
if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) {
v4l2_err(v4l2_dev, "i/o port already in use\n");
goto err_pci;
}
strlcpy(card->vdev.name, v4l2_dev->name, sizeof(card->vdev.name));
card->vdev.v4l2_dev = v4l2_dev;
card->vdev.fops = &gemtek_pci_fops;
card->vdev.ioctl_ops = &gemtek_pci_ioctl_ops;
card->vdev.release = video_device_release_empty;
video_set_drvdata(&card->vdev, card);
gemtek_pci_mute(card);
if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)
goto err_video;
v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
pdev->revision, card->iobase, card->iobase + card->length - 1);
return 0;
err_video:
release_region(card->iobase, card->length);
err_pci:
v4l2_device_unregister(v4l2_dev);
kfree(card);
return -ENODEV;
}
static void __devexit gemtek_pci_remove(struct pci_dev *pdev)
{
struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
struct gemtek_pci *card = to_gemtek_pci(v4l2_dev);
video_unregister_device(&card->vdev);
v4l2_device_unregister(v4l2_dev);
release_region(card->iobase, card->length);
if (mx)
gemtek_pci_mute(card);
kfree(card);
}
static struct pci_driver gemtek_pci_driver = {
.name = "gemtek_pci",
.id_table = gemtek_pci_id,
.probe = gemtek_pci_probe,
.remove = __devexit_p(gemtek_pci_remove),
};
static int __init gemtek_pci_init(void)
{
return pci_register_driver(&gemtek_pci_driver);
}
static void __exit gemtek_pci_exit(void)
{
pci_unregister_driver(&gemtek_pci_driver);
}
module_init(gemtek_pci_init);
module_exit(gemtek_pci_exit);

View file

@ -77,8 +77,8 @@ MODULE_PARM_DESC(debug, "activates debug info");
/* TEA5757 pin mappings */
static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16;
#define FREQ_LO (50 * 16000)
#define FREQ_HI (150 * 16000)
#define FREQ_LO (87 * 16000)
#define FREQ_HI (108 * 16000)
#define FREQ_IF 171200 /* 10.7*16000 */
#define FREQ_STEP 200 /* 12.5*16 */

View file

@ -1407,7 +1407,7 @@ static const struct v4l2_file_operations wl1273_fops = {
.read = wl1273_fm_fops_read,
.write = wl1273_fm_fops_write,
.poll = wl1273_fm_fops_poll,
.ioctl = video_ioctl2,
.unlocked_ioctl = video_ioctl2,
.open = wl1273_fm_fops_open,
.release = wl1273_fm_fops_release,
};

View file

@ -357,7 +357,8 @@ int si470x_start(struct si470x_device *radio)
goto done;
/* sysconfig 1 */
radio->registers[SYSCONFIG1] = SYSCONFIG1_DE;
radio->registers[SYSCONFIG1] =
(de << 11) & SYSCONFIG1_DE; /* DE*/
retval = si470x_set_register(radio, SYSCONFIG1);
if (retval < 0)
goto done;
@ -687,12 +688,8 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
/* driver constants */
strcpy(tuner->name, "FM");
tuner->type = V4L2_TUNER_RADIO;
#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO;
#else
tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
#endif
/* range limits */
switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
@ -718,12 +715,10 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
else
tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
/* If there is a reliable method of detecting an RDS channel,
then this code should check for that before setting this
RDS subchannel. */
tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;
#endif
/* mono/stereo selector */
if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)

View file

@ -446,27 +446,27 @@ static void ene_rx_setup(struct ene_device *dev)
select_timeout:
if (dev->rx_fan_input_inuse) {
dev->rdev->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
dev->rdev->rx_resolution = US_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
/* Fan input doesn't support timeouts, it just ends the
input with a maximum sample */
dev->rdev->min_timeout = dev->rdev->max_timeout =
MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
US_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
ENE_FW_SAMPLE_PERIOD_FAN);
} else {
dev->rdev->rx_resolution = MS_TO_NS(sample_period);
dev->rdev->rx_resolution = US_TO_NS(sample_period);
/* Theoreticly timeout is unlimited, but we cap it
* because it was seen that on one device, it
* would stop sending spaces after around 250 msec.
* Besides, this is close to 2^32 anyway and timeout is u32.
*/
dev->rdev->min_timeout = MS_TO_NS(127 * sample_period);
dev->rdev->max_timeout = MS_TO_NS(200000);
dev->rdev->min_timeout = US_TO_NS(127 * sample_period);
dev->rdev->max_timeout = US_TO_NS(200000);
}
if (dev->hw_learning_and_tx_capable)
dev->rdev->tx_resolution = MS_TO_NS(sample_period);
dev->rdev->tx_resolution = US_TO_NS(sample_period);
if (dev->rdev->timeout > dev->rdev->max_timeout)
dev->rdev->timeout = dev->rdev->max_timeout;
@ -801,7 +801,7 @@ static irqreturn_t ene_isr(int irq, void *data)
dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space");
ev.duration = MS_TO_NS(hw_sample);
ev.duration = US_TO_NS(hw_sample);
ev.pulse = pulse;
ir_raw_event_store_with_filter(dev->rdev, &ev);
}
@ -821,7 +821,7 @@ static void ene_setup_default_settings(struct ene_device *dev)
dev->learning_mode_enabled = learning_mode_force;
/* Set reasonable default timeout */
dev->rdev->timeout = MS_TO_NS(150000);
dev->rdev->timeout = US_TO_NS(150000);
}
/* Upload all hardware settings at once. Used at load and resume time */
@ -1004,6 +1004,10 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
/* validate resources */
error = -ENODEV;
/* init these to -1, as 0 is valid for both */
dev->hw_io = -1;
dev->irq = -1;
if (!pnp_port_valid(pnp_dev, 0) ||
pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE)
goto error;
@ -1072,6 +1076,8 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
rdev->input_name = "ENE eHome Infrared Remote Transceiver";
}
dev->rdev = rdev;
ene_rx_setup_hw_buffer(dev);
ene_setup_default_settings(dev);
ene_setup_hw_settings(dev);
@ -1083,7 +1089,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
if (error < 0)
goto error;
dev->rdev = rdev;
ene_notice("driver has been succesfully loaded");
return 0;
error:

View file

@ -201,8 +201,6 @@
#define dbg_verbose(format, ...) __dbg(2, format, ## __VA_ARGS__)
#define dbg_regs(format, ...) __dbg(3, format, ## __VA_ARGS__)
#define MS_TO_NS(msec) ((msec) * 1000)
struct ene_device {
struct pnp_dev *pnp_dev;
struct rc_dev *rdev;

View file

@ -988,7 +988,6 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
int retval;
struct imon_context *ictx = rc->priv;
struct device *dev = ictx->dev;
bool pad_mouse;
unsigned char ir_proto_packet[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
@ -1000,29 +999,20 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
case RC_TYPE_RC6:
dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
ir_proto_packet[0] = 0x01;
pad_mouse = false;
break;
case RC_TYPE_UNKNOWN:
case RC_TYPE_OTHER:
dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
if (pad_stabilize && !nomouse)
pad_mouse = true;
else {
if (!pad_stabilize)
dev_dbg(dev, "PAD stabilize functionality disabled\n");
pad_mouse = false;
}
/* ir_proto_packet[0] = 0x00; // already the default */
rc_type = RC_TYPE_OTHER;
break;
default:
dev_warn(dev, "Unsupported IR protocol specified, overriding "
"to iMON IR protocol\n");
if (pad_stabilize && !nomouse)
pad_mouse = true;
else {
if (!pad_stabilize)
dev_dbg(dev, "PAD stabilize functionality disabled\n");
pad_mouse = false;
}
/* ir_proto_packet[0] = 0x00; // already the default */
rc_type = RC_TYPE_OTHER;
break;
@ -1035,7 +1025,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
goto out;
ictx->rc_type = rc_type;
ictx->pad_mouse = pad_mouse;
ictx->pad_mouse = false;
out:
return retval;
@ -1517,7 +1507,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
spin_unlock_irqrestore(&ictx->kc_lock, flags);
return;
} else {
ictx->pad_mouse = 0;
ictx->pad_mouse = false;
dev_dbg(dev, "mouse mode disabled, passing key value\n");
}
}
@ -1756,7 +1746,6 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
ictx->display_type = detected_display_type;
ictx->rdev->allowed_protos = allowed_protos;
ictx->rc_type = allowed_protos;
}
@ -1839,10 +1828,6 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
rdev->allowed_protos = RC_TYPE_OTHER | RC_TYPE_RC6; /* iMON PAD or MCE */
rdev->change_protocol = imon_ir_change_protocol;
rdev->driver_name = MOD_NAME;
if (ictx->rc_type == RC_TYPE_RC6)
rdev->map_name = RC_MAP_IMON_MCE;
else
rdev->map_name = RC_MAP_IMON_PAD;
/* Enable front-panel buttons and/or knobs */
memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
@ -1851,11 +1836,18 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
if (ret)
dev_info(ictx->dev, "panel buttons/knobs setup failed\n");
if (ictx->product == 0xffdc)
if (ictx->product == 0xffdc) {
imon_get_ffdc_type(ictx);
rdev->allowed_protos = ictx->rc_type;
}
imon_set_display_type(ictx);
if (ictx->rc_type == RC_TYPE_RC6)
rdev->map_name = RC_MAP_IMON_MCE;
else
rdev->map_name = RC_MAP_IMON_PAD;
ret = rc_register_device(rdev);
if (ret < 0) {
dev_err(ictx->dev, "remote input dev register failed\n");
@ -2108,18 +2100,6 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
goto find_endpoint_failed;
}
ictx->idev = imon_init_idev(ictx);
if (!ictx->idev) {
dev_err(dev, "%s: input device setup failed\n", __func__);
goto idev_setup_failed;
}
ictx->rdev = imon_init_rdev(ictx);
if (!ictx->rdev) {
dev_err(dev, "%s: rc device setup failed\n", __func__);
goto rdev_setup_failed;
}
usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
usb_rcvintpipe(ictx->usbdev_intf0,
ictx->rx_endpoint_intf0->bEndpointAddress),
@ -2133,13 +2113,25 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
goto urb_submit_failed;
}
ictx->idev = imon_init_idev(ictx);
if (!ictx->idev) {
dev_err(dev, "%s: input device setup failed\n", __func__);
goto idev_setup_failed;
}
ictx->rdev = imon_init_rdev(ictx);
if (!ictx->rdev) {
dev_err(dev, "%s: rc device setup failed\n", __func__);
goto rdev_setup_failed;
}
return ictx;
urb_submit_failed:
rc_unregister_device(ictx->rdev);
rdev_setup_failed:
input_unregister_device(ictx->idev);
idev_setup_failed:
usb_kill_urb(ictx->rx_urb_intf0);
urb_submit_failed:
find_endpoint_failed:
mutex_unlock(&ictx->lock);
usb_free_urb(tx_urb);

View file

@ -233,7 +233,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_handle);
/* used internally by the sysfs interface */
u64
ir_raw_get_allowed_protocols()
ir_raw_get_allowed_protocols(void)
{
u64 protocols;
mutex_lock(&ir_raw_handler_lock);

View file

@ -19,35 +19,35 @@
static struct rc_map_table dib0700_nec_table[] = {
/* Key codes for the Pixelview SBTVD remote */
{ 0x8613, KEY_MUTE },
{ 0x8612, KEY_POWER },
{ 0x8601, KEY_1 },
{ 0x8602, KEY_2 },
{ 0x8603, KEY_3 },
{ 0x8604, KEY_4 },
{ 0x8605, KEY_5 },
{ 0x8606, KEY_6 },
{ 0x8607, KEY_7 },
{ 0x8608, KEY_8 },
{ 0x8609, KEY_9 },
{ 0x8600, KEY_0 },
{ 0x860d, KEY_CHANNELUP },
{ 0x8619, KEY_CHANNELDOWN },
{ 0x8610, KEY_VOLUMEUP },
{ 0x860c, KEY_VOLUMEDOWN },
{ 0x866b13, KEY_MUTE },
{ 0x866b12, KEY_POWER },
{ 0x866b01, KEY_1 },
{ 0x866b02, KEY_2 },
{ 0x866b03, KEY_3 },
{ 0x866b04, KEY_4 },
{ 0x866b05, KEY_5 },
{ 0x866b06, KEY_6 },
{ 0x866b07, KEY_7 },
{ 0x866b08, KEY_8 },
{ 0x866b09, KEY_9 },
{ 0x866b00, KEY_0 },
{ 0x866b0d, KEY_CHANNELUP },
{ 0x866b19, KEY_CHANNELDOWN },
{ 0x866b10, KEY_VOLUMEUP },
{ 0x866b0c, KEY_VOLUMEDOWN },
{ 0x860a, KEY_CAMERA },
{ 0x860b, KEY_ZOOM },
{ 0x861b, KEY_BACKSPACE },
{ 0x8615, KEY_ENTER },
{ 0x866b0a, KEY_CAMERA },
{ 0x866b0b, KEY_ZOOM },
{ 0x866b1b, KEY_BACKSPACE },
{ 0x866b15, KEY_ENTER },
{ 0x861d, KEY_UP },
{ 0x861e, KEY_DOWN },
{ 0x860e, KEY_LEFT },
{ 0x860f, KEY_RIGHT },
{ 0x866b1d, KEY_UP },
{ 0x866b1e, KEY_DOWN },
{ 0x866b0e, KEY_LEFT },
{ 0x866b0f, KEY_RIGHT },
{ 0x8618, KEY_RECORD },
{ 0x861a, KEY_STOP },
{ 0x866b18, KEY_RECORD },
{ 0x866b1a, KEY_STOP },
/* Key codes for the EvolutePC TVWay+ remote */
{ 0x7a00, KEY_MENU },

View file

@ -48,7 +48,6 @@
#define USB_BUFLEN 32 /* USB reception buffer length */
#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
#define MS_TO_NS(msec) ((msec) * 1000)
/* MCE constants */
#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
@ -858,7 +857,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
ir->rem--;
rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
* MS_TO_NS(MCE_TIME_UNIT);
* MS_TO_US(MCE_TIME_UNIT);
dev_dbg(ir->dev, "Storing %s with duration %d\n",
rawir.pulse ? "pulse" : "space",

View file

@ -141,15 +141,6 @@ config VIDEO_TDA9840
To compile this driver as a module, choose M here: the
module will be called tda9840.
config VIDEO_TDA9875
tristate "Philips TDA9875 audio processor"
depends on VIDEO_V4L2 && I2C
---help---
Support for tda9875 audio decoder chip found on some bt8xx boards.
To compile this driver as a module, choose M here: the
module will be called tda9875.
config VIDEO_TEA6415C
tristate "Philips TEA6415C audio processor"
depends on I2C

View file

@ -27,7 +27,6 @@ obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
obj-$(CONFIG_VIDEO_TUNER) += tuner.o
obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o

View file

@ -303,11 +303,22 @@ static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
}
static int adv7175_s_power(struct v4l2_subdev *sd, int on)
{
if (on)
adv7175_write(sd, 0x01, 0x00);
else
adv7175_write(sd, 0x01, 0x78);
return 0;
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops adv7175_core_ops = {
.g_chip_ident = adv7175_g_chip_ident,
.init = adv7175_init,
.s_power = adv7175_s_power,
};
static const struct v4l2_subdev_video_ops adv7175_video_ops = {

View file

@ -1373,7 +1373,6 @@ struct tvcard bttv_tvcards[] = {
.gpiomute = 0x1800,
.audio_mode_gpio= fv2000s_audio,
.no_msp34xx = 1,
.no_tda9875 = 1,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
@ -1511,7 +1510,6 @@ struct tvcard bttv_tvcards[] = {
.gpiomute = 0x09,
.needs_tvaudio = 1,
.no_msp34xx = 1,
.no_tda9875 = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@ -1550,7 +1548,6 @@ struct tvcard bttv_tvcards[] = {
.gpiomask2 = 0x07ff,
.muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.muxsel_hook = rv605_muxsel,
@ -1686,7 +1683,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
[BTTV_BOARD_OSPREY1x0_848] = {
@ -1699,7 +1695,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
@ -1714,7 +1709,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
[BTTV_BOARD_OSPREY1x1] = {
@ -1727,7 +1721,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
[BTTV_BOARD_OSPREY1x1_SVID] = {
@ -1740,7 +1733,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
[BTTV_BOARD_OSPREY2xx] = {
@ -1753,7 +1745,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
@ -1768,7 +1759,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
[BTTV_BOARD_OSPREY2x0] = {
@ -1781,7 +1771,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
[BTTV_BOARD_OSPREY500] = {
@ -1794,7 +1783,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
[BTTV_BOARD_OSPREY540] = {
@ -1805,7 +1793,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
@ -1820,7 +1807,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
},
[BTTV_BOARD_IDS_EAGLE] = {
@ -1835,7 +1821,6 @@ struct tvcard bttv_tvcards[] = {
.muxsel = MUXSEL(2, 2, 2, 2),
.muxsel_hook = eagle_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
.pll = PLL_28,
},
[BTTV_BOARD_PINNACLESAT] = {
@ -1846,7 +1831,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.muxsel = MUXSEL(3, 1),
.pll = PLL_28,
@ -1897,7 +1881,6 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.muxsel = MUXSEL(2, 0, 1),
.pll = PLL_28,
@ -1970,7 +1953,6 @@ struct tvcard bttv_tvcards[] = {
/* Tuner, CVid, SVid, CVid over SVid connector */
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomask = 0,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
@ -2017,7 +1999,6 @@ struct tvcard bttv_tvcards[] = {
.muxsel = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0),
.muxsel_hook = xguard_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
},
@ -2029,7 +2010,6 @@ struct tvcard bttv_tvcards[] = {
.svhs = NO_SVHS,
.muxsel = MUXSEL(2, 3, 1, 0),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.tuner_type = TUNER_ABSENT,
@ -2134,7 +2114,6 @@ struct tvcard bttv_tvcards[] = {
.svhs = NO_SVHS, /* card has no svhs */
.needs_tvaudio = 0,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.gpiomask = 0x00,
.muxsel = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
@ -2156,7 +2135,6 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_TWINHAN_DST] = {
.name = "Twinhan DST + clones",
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
@ -2171,7 +2149,6 @@ struct tvcard bttv_tvcards[] = {
/* Vid In, SVid In, Vid over SVid in connector */
.muxsel = MUXSEL(3, 1, 1, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
@ -2226,7 +2203,6 @@ struct tvcard bttv_tvcards[] = {
.svhs = NO_SVHS,
.muxsel = MUXSEL(2, 3, 1, 0),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.needs_tvaudio = 0,
.tuner_type = TUNER_ABSENT,
@ -2278,7 +2254,6 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0,
.gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
/*878A input is always MUX0, see above.*/
.muxsel = MUXSEL(2, 2, 2, 2),
@ -2302,7 +2277,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
},
[BTTV_BOARD_AVDVBT_771] = {
/* Wolfram Joost <wojo@frokaschwei.de> */
@ -2313,7 +2287,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_addr = ADDR_UNSET,
.muxsel = MUXSEL(3, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.has_dvb = 1,
@ -2329,7 +2302,6 @@ struct tvcard bttv_tvcards[] = {
.svhs = 1,
.muxsel = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.tuner_type = TUNER_ABSENT,
@ -2393,7 +2365,6 @@ struct tvcard bttv_tvcards[] = {
/* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
.name = "DViCO FusionHDTV DVB-T Lite",
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.no_video = 1,
@ -2440,7 +2411,6 @@ struct tvcard bttv_tvcards[] = {
.muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
@ -2478,7 +2448,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
.no_tda9875 = 1,
.muxsel_hook = kodicom4400r_muxsel,
},
[BTTV_BOARD_KODICOM_4400R_SL] = {
@ -2500,7 +2469,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
.no_tda9875 = 1,
.muxsel_hook = kodicom4400r_muxsel,
},
/* ---- card 0x86---------------------------------- */
@ -2530,7 +2498,6 @@ struct tvcard bttv_tvcards[] = {
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
.gpiomute = 0x00c00007,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.has_dvb = 1,
},
@ -2630,7 +2597,6 @@ struct tvcard bttv_tvcards[] = {
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
/* ---- card 0x8d ---------------------------------- */
@ -2658,7 +2624,6 @@ struct tvcard bttv_tvcards[] = {
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 100000, 100002, 100002, 100000 },
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.tuner_type = TUNER_TNF_5335MF,
@ -2674,7 +2639,6 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x0f, /* old: 7 */
.muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
@ -2732,7 +2696,6 @@ struct tvcard bttv_tvcards[] = {
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
.gpiomute = 0x00c00007,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
},
/* ---- card 0x95---------------------------------- */
@ -2874,7 +2837,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
.no_tda9875 = 1,
.muxsel_hook = gv800s_muxsel,
},
[BTTV_BOARD_GEOVISION_GV800S_SL] = {
@ -2899,7 +2861,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
.no_tda9875 = 1,
.muxsel_hook = gv800s_muxsel,
},
[BTTV_BOARD_PV183] = {

View file

@ -234,7 +234,6 @@ struct tvcard {
/* i2c audio flags */
unsigned int no_msp34xx:1;
unsigned int no_tda9875:1;
unsigned int no_tda7432:1;
unsigned int needs_tvaudio:1;
unsigned int msp34xx_alt:1;

View file

@ -2001,6 +2001,11 @@ static int cafe_pci_probe(struct pci_dev *pdev,
.min_width = 320,
.min_height = 240,
};
struct i2c_board_info ov7670_info = {
.type = "ov7670",
.addr = 0x42,
.platform_data = &sensor_cfg,
};
/*
* Start putting together one of our big camera structures.
@ -2062,9 +2067,9 @@ static int cafe_pci_probe(struct pci_dev *pdev,
if (dmi_check_system(olpc_xo1_dmi))
sensor_cfg.clock_speed = 45;
cam->sensor_addr = 0x42;
cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter,
"ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL);
cam->sensor_addr = ov7670_info.addr;
cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev, &cam->i2c_adapter,
&ov7670_info, NULL);
if (cam->sensor == NULL) {
ret = -ENODEV;
goto out_smbus;

View file

@ -378,7 +378,7 @@ struct cpia2_fh {
struct camera_data {
/* locks */
struct mutex busy_lock; /* guard against SMP multithreading */
struct mutex v4l2_lock; /* serialize file operations */
struct v4l2_prio_state prio;
/* camera status */

View file

@ -2247,7 +2247,7 @@ struct camera_data *cpia2_init_camera_struct(void)
cam->present = 1;
mutex_init(&cam->busy_lock);
mutex_init(&cam->v4l2_lock);
init_waitqueue_head(&cam->wq_stream);
return cam;
@ -2365,9 +2365,9 @@ long cpia2_read(struct camera_data *cam,
char __user *buf, unsigned long count, int noblock)
{
struct framebuf *frame;
if (!count) {
if (!count)
return 0;
}
if (!buf) {
ERR("%s: buffer NULL\n",__func__);
@ -2379,17 +2379,12 @@ long cpia2_read(struct camera_data *cam,
return -EINVAL;
}
/* make this _really_ smp and multithread-safe */
if (mutex_lock_interruptible(&cam->busy_lock))
return -ERESTARTSYS;
if (!cam->present) {
LOG("%s: camera removed\n",__func__);
mutex_unlock(&cam->busy_lock);
return 0; /* EOF */
}
if(!cam->streaming) {
if (!cam->streaming) {
/* Start streaming */
cpia2_usb_stream_start(cam,
cam->params.camera_state.stream_mode);
@ -2398,42 +2393,31 @@ long cpia2_read(struct camera_data *cam,
/* Copy cam->curbuff in case it changes while we're processing */
frame = cam->curbuff;
if (noblock && frame->status != FRAME_READY) {
mutex_unlock(&cam->busy_lock);
return -EAGAIN;
}
if(frame->status != FRAME_READY) {
mutex_unlock(&cam->busy_lock);
if (frame->status != FRAME_READY) {
mutex_unlock(&cam->v4l2_lock);
wait_event_interruptible(cam->wq_stream,
!cam->present ||
(frame = cam->curbuff)->status == FRAME_READY);
mutex_lock(&cam->v4l2_lock);
if (signal_pending(current))
return -ERESTARTSYS;
/* make this _really_ smp and multithread-safe */
if (mutex_lock_interruptible(&cam->busy_lock)) {
return -ERESTARTSYS;
}
if(!cam->present) {
mutex_unlock(&cam->busy_lock);
if (!cam->present)
return 0;
}
}
/* copy data to user space */
if (frame->length > count) {
mutex_unlock(&cam->busy_lock);
if (frame->length > count)
return -EFAULT;
}
if (copy_to_user(buf, frame->data, frame->length)) {
mutex_unlock(&cam->busy_lock);
if (copy_to_user(buf, frame->data, frame->length))
return -EFAULT;
}
count = frame->length;
frame->status = FRAME_EMPTY;
mutex_unlock(&cam->busy_lock);
return count;
}
@ -2447,17 +2431,13 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
{
unsigned int status=0;
if(!cam) {
if (!cam) {
ERR("%s: Internal error, camera_data not found!\n",__func__);
return POLLERR;
}
mutex_lock(&cam->busy_lock);
if(!cam->present) {
mutex_unlock(&cam->busy_lock);
if (!cam->present)
return POLLHUP;
}
if(!cam->streaming) {
/* Start streaming */
@ -2465,16 +2445,13 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
cam->params.camera_state.stream_mode);
}
mutex_unlock(&cam->busy_lock);
poll_wait(filp, &cam->wq_stream, wait);
mutex_lock(&cam->busy_lock);
if(!cam->present)
status = POLLHUP;
else if(cam->curbuff->status == FRAME_READY)
status = POLLIN | POLLRDNORM;
mutex_unlock(&cam->busy_lock);
return status;
}
@ -2496,29 +2473,19 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
DBG("mmap offset:%ld size:%ld\n", start_offset, size);
/* make this _really_ smp-safe */
if (mutex_lock_interruptible(&cam->busy_lock))
return -ERESTARTSYS;
if (!cam->present) {
mutex_unlock(&cam->busy_lock);
if (!cam->present)
return -ENODEV;
}
if (size > cam->frame_size*cam->num_frames ||
(start_offset % cam->frame_size) != 0 ||
(start_offset+size > cam->frame_size*cam->num_frames)) {
mutex_unlock(&cam->busy_lock);
(start_offset+size > cam->frame_size*cam->num_frames))
return -EINVAL;
}
pos = ((unsigned long) (cam->frame_buffer)) + start_offset;
while (size > 0) {
page = kvirt_to_pa(pos);
if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) {
mutex_unlock(&cam->busy_lock);
if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED))
return -EAGAIN;
}
start += PAGE_SIZE;
pos += PAGE_SIZE;
if (size > PAGE_SIZE)
@ -2528,7 +2495,5 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
}
cam->mmapped = true;
mutex_unlock(&cam->busy_lock);
return 0;
}

View file

@ -238,59 +238,40 @@ static struct v4l2_queryctrl controls[] = {
static int cpia2_open(struct file *file)
{
struct camera_data *cam = video_drvdata(file);
int retval = 0;
struct cpia2_fh *fh;
if (!cam) {
ERR("Internal error, camera_data not found!\n");
return -ENODEV;
}
if(mutex_lock_interruptible(&cam->busy_lock))
return -ERESTARTSYS;
if (!cam->present)
return -ENODEV;
if(!cam->present) {
retval = -ENODEV;
goto err_return;
if (cam->open_count == 0) {
if (cpia2_allocate_buffers(cam))
return -ENOMEM;
/* reset the camera */
if (cpia2_reset_camera(cam) < 0)
return -EIO;
cam->APP_len = 0;
cam->COM_len = 0;
}
if (cam->open_count > 0) {
goto skip_init;
}
if (cpia2_allocate_buffers(cam)) {
retval = -ENOMEM;
goto err_return;
}
/* reset the camera */
if (cpia2_reset_camera(cam) < 0) {
retval = -EIO;
goto err_return;
}
cam->APP_len = 0;
cam->COM_len = 0;
skip_init:
{
struct cpia2_fh *fh = kmalloc(sizeof(*fh),GFP_KERNEL);
if(!fh) {
retval = -ENOMEM;
goto err_return;
}
file->private_data = fh;
fh->prio = V4L2_PRIORITY_UNSET;
v4l2_prio_open(&cam->prio, &fh->prio);
fh->mmapped = 0;
}
fh = kmalloc(sizeof(*fh), GFP_KERNEL);
if (!fh)
return -ENOMEM;
file->private_data = fh;
fh->prio = V4L2_PRIORITY_UNSET;
v4l2_prio_open(&cam->prio, &fh->prio);
fh->mmapped = 0;
++cam->open_count;
cpia2_dbg_dump_registers(cam);
err_return:
mutex_unlock(&cam->busy_lock);
return retval;
return 0;
}
/******************************************************************************
@ -304,15 +285,11 @@ static int cpia2_close(struct file *file)
struct camera_data *cam = video_get_drvdata(dev);
struct cpia2_fh *fh = file->private_data;
mutex_lock(&cam->busy_lock);
if (cam->present &&
(cam->open_count == 1
|| fh->prio == V4L2_PRIORITY_RECORD
)) {
(cam->open_count == 1 || fh->prio == V4L2_PRIORITY_RECORD)) {
cpia2_usb_stream_stop(cam);
if(cam->open_count == 1) {
if (cam->open_count == 1) {
/* save camera state for later open */
cpia2_save_camera_state(cam);
@ -321,26 +298,21 @@ static int cpia2_close(struct file *file)
}
}
{
if(fh->mmapped)
cam->mmapped = 0;
v4l2_prio_close(&cam->prio, fh->prio);
file->private_data = NULL;
kfree(fh);
}
if (fh->mmapped)
cam->mmapped = 0;
v4l2_prio_close(&cam->prio, fh->prio);
file->private_data = NULL;
kfree(fh);
if (--cam->open_count == 0) {
cpia2_free_buffers(cam);
if (!cam->present) {
video_unregister_device(dev);
mutex_unlock(&cam->busy_lock);
kfree(cam);
return 0;
}
}
mutex_unlock(&cam->busy_lock);
return 0;
}
@ -405,11 +377,11 @@ static int sync(struct camera_data *cam, int frame_nr)
return 0;
}
mutex_unlock(&cam->busy_lock);
mutex_unlock(&cam->v4l2_lock);
wait_event_interruptible(cam->wq_stream,
!cam->streaming ||
frame->status == FRAME_READY);
mutex_lock(&cam->busy_lock);
mutex_lock(&cam->v4l2_lock);
if (signal_pending(current))
return -ERESTARTSYS;
if(!cam->present)
@ -1293,11 +1265,11 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
if(frame < 0) {
/* Wait for a frame to become available */
struct framebuf *cb=cam->curbuff;
mutex_unlock(&cam->busy_lock);
mutex_unlock(&cam->v4l2_lock);
wait_event_interruptible(cam->wq_stream,
!cam->present ||
(cb=cam->curbuff)->status == FRAME_READY);
mutex_lock(&cam->busy_lock);
mutex_lock(&cam->v4l2_lock);
if (signal_pending(current))
return -ERESTARTSYS;
if(!cam->present)
@ -1337,14 +1309,8 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
if (!cam)
return -ENOTTY;
/* make this _really_ smp-safe */
if (mutex_lock_interruptible(&cam->busy_lock))
return -ERESTARTSYS;
if (!cam->present) {
mutex_unlock(&cam->busy_lock);
if (!cam->present)
return -ENODEV;
}
/* Priority check */
switch (cmd) {
@ -1352,10 +1318,8 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct cpia2_fh *fh = file->private_data;
retval = v4l2_prio_check(&cam->prio, fh->prio);
if(retval) {
mutex_unlock(&cam->busy_lock);
if (retval)
return retval;
}
break;
}
default:
@ -1529,7 +1493,6 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
break;
}
mutex_unlock(&cam->busy_lock);
return retval;
}
@ -1596,7 +1559,7 @@ static const struct v4l2_file_operations cpia2_fops = {
.release = cpia2_close,
.read = cpia2_v4l_read,
.poll = cpia2_v4l_poll,
.ioctl = cpia2_ioctl,
.unlocked_ioctl = cpia2_ioctl,
.mmap = cpia2_mmap,
};
@ -1620,6 +1583,7 @@ int cpia2_register_camera(struct camera_data *cam)
memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template));
video_set_drvdata(cam->vdev, cam);
cam->vdev->lock = &cam->v4l2_lock;
reset_camera_struct_v4l(cam);

View file

@ -664,7 +664,7 @@ static int __devinit cx18_create_in_workq(struct cx18 *cx)
{
snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
cx->v4l2_dev.name);
cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name);
cx->in_work_queue = alloc_ordered_workqueue(cx->in_workq_name, 0);
if (cx->in_work_queue == NULL) {
CX18_ERR("Unable to create incoming mailbox handler thread\n");
return -ENOMEM;
@ -672,18 +672,6 @@ static int __devinit cx18_create_in_workq(struct cx18 *cx)
return 0;
}
static int __devinit cx18_create_out_workq(struct cx18 *cx)
{
snprintf(cx->out_workq_name, sizeof(cx->out_workq_name), "%s-out",
cx->v4l2_dev.name);
cx->out_work_queue = create_workqueue(cx->out_workq_name);
if (cx->out_work_queue == NULL) {
CX18_ERR("Unable to create outgoing mailbox handler threads\n");
return -ENOMEM;
}
return 0;
}
static void __devinit cx18_init_in_work_orders(struct cx18 *cx)
{
int i;
@ -710,16 +698,10 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
mutex_init(&cx->epu2apu_mb_lock);
mutex_init(&cx->epu2cpu_mb_lock);
ret = cx18_create_out_workq(cx);
ret = cx18_create_in_workq(cx);
if (ret)
return ret;
ret = cx18_create_in_workq(cx);
if (ret) {
destroy_workqueue(cx->out_work_queue);
return ret;
}
cx18_init_in_work_orders(cx);
/* start counting open_id at 1 */
@ -1107,7 +1089,6 @@ free_mem:
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
free_workqueues:
destroy_workqueue(cx->in_work_queue);
destroy_workqueue(cx->out_work_queue);
err:
if (retval == 0)
retval = -ENODEV;
@ -1259,7 +1240,6 @@ static void cx18_remove(struct pci_dev *pci_dev)
cx18_halt_firmware(cx);
destroy_workqueue(cx->in_work_queue);
destroy_workqueue(cx->out_work_queue);
cx18_streams_cleanup(cx, 1);

View file

@ -617,9 +617,6 @@ struct cx18 {
struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS];
char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
struct workqueue_struct *out_work_queue;
char out_workq_name[12]; /* "cx18-NN-out" */
/* i2c */
struct i2c_adapter i2c_adap[2];
struct i2c_algo_bit_data i2c_algo[2];

View file

@ -42,8 +42,7 @@ static inline bool cx18_stream_enabled(struct cx18_stream *s)
/* Related to submission of mdls to firmware */
static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
{
struct cx18 *cx = s->cx;
queue_work(cx->out_work_queue, &s->out_work_order);
schedule_work(&s->out_work_order);
}
static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s,

View file

@ -28,7 +28,6 @@
#include <media/videobuf-vmalloc.h>
#include "xc5000.h"
#include "dvb_dummy_fe.h"
#include "s5h1432.h"
#include "tda18271.h"
#include "s5h1411.h"
@ -619,7 +618,7 @@ static int dvb_init(struct cx231xx *dev)
if (dev->dvb->frontend == NULL) {
printk(DRIVER_NAME
": Failed to attach dummy front end\n");
": Failed to attach s5h1411 front end\n");
result = -EINVAL;
goto out_free;
}
@ -665,7 +664,7 @@ static int dvb_init(struct cx231xx *dev)
if (dev->dvb->frontend == NULL) {
printk(DRIVER_NAME
": Failed to attach dummy front end\n");
": Failed to attach s5h1411 front end\n");
result = -EINVAL;
goto out_free;
}

View file

@ -1682,20 +1682,6 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
return 0;
}
static int cx25840_s_config(struct v4l2_subdev *sd, int irq, void *platform_data)
{
struct cx25840_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
if (platform_data) {
struct cx25840_platform_data *pdata = platform_data;
state->pvr150_workaround = pdata->pvr150_workaround;
set_input(client, state->vid_input, state->aud_input);
}
return 0;
}
static int cx23885_irq_handler(struct v4l2_subdev *sd, u32 status,
bool *handled)
{
@ -1787,7 +1773,6 @@ static const struct v4l2_ctrl_ops cx25840_ctrl_ops = {
static const struct v4l2_subdev_core_ops cx25840_core_ops = {
.log_status = cx25840_log_status,
.s_config = cx25840_s_config,
.g_chip_ident = cx25840_g_chip_ident,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
@ -1974,7 +1959,6 @@ static int cx25840_probe(struct i2c_client *client,
state->vid_input = CX25840_COMPOSITE7;
state->aud_input = CX25840_AUDIO8;
state->audclk_freq = 48000;
state->pvr150_workaround = 0;
state->audmode = V4L2_TUNER_MODE_LANG1;
state->vbi_line_offset = 8;
state->id = id;
@ -2034,6 +2018,12 @@ static int cx25840_probe(struct i2c_client *client,
v4l2_ctrl_cluster(2, &state->volume);
v4l2_ctrl_handler_setup(&state->hdl);
if (client->dev.platform_data) {
struct cx25840_platform_data *pdata = client->dev.platform_data;
state->pvr150_workaround = pdata->pvr150_workaround;
}
cx25840_ir_probe(sd);
return 0;
}

View file

@ -41,6 +41,183 @@ spinlock_t vpif_lock;
void __iomem *vpif_base;
/**
* ch_params: video standard configuration parameters for vpif
* The table must include all presets from supported subdevices.
*/
const struct vpif_channel_config_params ch_params[] = {
/* HDTV formats */
{
.name = "480p59_94",
.width = 720,
.height = 480,
.frm_fmt = 1,
.ycmux_mode = 0,
.eav2sav = 138-8,
.sav2eav = 720,
.l1 = 1,
.l3 = 43,
.l5 = 523,
.vsize = 525,
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
.dv_preset = V4L2_DV_480P59_94,
},
{
.name = "576p50",
.width = 720,
.height = 576,
.frm_fmt = 1,
.ycmux_mode = 0,
.eav2sav = 144-8,
.sav2eav = 720,
.l1 = 1,
.l3 = 45,
.l5 = 621,
.vsize = 625,
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
.dv_preset = V4L2_DV_576P50,
},
{
.name = "720p50",
.width = 1280,
.height = 720,
.frm_fmt = 1,
.ycmux_mode = 0,
.eav2sav = 700-8,
.sav2eav = 1280,
.l1 = 1,
.l3 = 26,
.l5 = 746,
.vsize = 750,
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
.dv_preset = V4L2_DV_720P50,
},
{
.name = "720p60",
.width = 1280,
.height = 720,
.frm_fmt = 1,
.ycmux_mode = 0,
.eav2sav = 370 - 8,
.sav2eav = 1280,
.l1 = 1,
.l3 = 26,
.l5 = 746,
.vsize = 750,
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
.dv_preset = V4L2_DV_720P60,
},
{
.name = "1080I50",
.width = 1920,
.height = 1080,
.frm_fmt = 0,
.ycmux_mode = 0,
.eav2sav = 720 - 8,
.sav2eav = 1920,
.l1 = 1,
.l3 = 21,
.l5 = 561,
.l7 = 563,
.l9 = 584,
.l11 = 1124,
.vsize = 1125,
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
.dv_preset = V4L2_DV_1080I50,
},
{
.name = "1080I60",
.width = 1920,
.height = 1080,
.frm_fmt = 0,
.ycmux_mode = 0,
.eav2sav = 280 - 8,
.sav2eav = 1920,
.l1 = 1,
.l3 = 21,
.l5 = 561,
.l7 = 563,
.l9 = 584,
.l11 = 1124,
.vsize = 1125,
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
.dv_preset = V4L2_DV_1080I60,
},
{
.name = "1080p60",
.width = 1920,
.height = 1080,
.frm_fmt = 1,
.ycmux_mode = 0,
.eav2sav = 280 - 8,
.sav2eav = 1920,
.l1 = 1,
.l3 = 42,
.l5 = 1122,
.vsize = 1125,
.capture_format = 0,
.vbi_supported = 0,
.hd_sd = 1,
.dv_preset = V4L2_DV_1080P60,
},
/* SDTV formats */
{
.name = "NTSC_M",
.width = 720,
.height = 480,
.frm_fmt = 0,
.ycmux_mode = 1,
.eav2sav = 268,
.sav2eav = 1440,
.l1 = 1,
.l3 = 23,
.l5 = 263,
.l7 = 266,
.l9 = 286,
.l11 = 525,
.vsize = 525,
.capture_format = 0,
.vbi_supported = 1,
.hd_sd = 0,
.stdid = V4L2_STD_525_60,
},
{
.name = "PAL_BDGHIK",
.width = 720,
.height = 576,
.frm_fmt = 0,
.ycmux_mode = 1,
.eav2sav = 280,
.sav2eav = 1440,
.l1 = 1,
.l3 = 23,
.l5 = 311,
.l7 = 313,
.l9 = 336,
.l11 = 624,
.vsize = 625,
.capture_format = 0,
.vbi_supported = 1,
.hd_sd = 0,
.stdid = V4L2_STD_625_50,
},
};
const unsigned int vpif_ch_params_count = ARRAY_SIZE(ch_params);
static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
{
if (val)

View file

@ -577,12 +577,10 @@ struct vpif_channel_config_params {
char name[VPIF_MAX_NAME]; /* Name of the mode */
u16 width; /* Indicates width of the image */
u16 height; /* Indicates height of the image */
u8 fps;
u8 frm_fmt; /* Indicates whether this is interlaced
* or progressive format */
u8 ycmux_mode; /* Indicates whether this mode requires
* single or two channels */
u16 eav2sav; /* length of sav 2 eav */
u8 frm_fmt; /* Interlaced (0) or progressive (1) */
u8 ycmux_mode; /* This mode requires one (0) or two (1)
channels */
u16 eav2sav; /* length of eav 2 sav */
u16 sav2eav; /* length of sav 2 eav */
u16 l1, l3, l5, l7, l9, l11; /* Other parameter configurations */
u16 vsize; /* Vertical size of the image */
@ -590,10 +588,14 @@ struct vpif_channel_config_params {
* is in BT or in CCD/CMOS */
u8 vbi_supported; /* Indicates whether this mode
* supports capturing vbi or not */
u8 hd_sd;
v4l2_std_id stdid;
u8 hd_sd; /* HDTV (1) or SDTV (0) format */
v4l2_std_id stdid; /* SDTV format */
u32 dv_preset; /* HDTV format */
};
extern const unsigned int vpif_ch_params_count;
extern const struct vpif_channel_config_params ch_params[];
struct vpif_video_params;
struct vpif_params;
struct vpif_vbi_params;

View file

@ -37,6 +37,7 @@
#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-chip-ident.h>
#include "vpif_capture.h"
#include "vpif.h"
@ -80,20 +81,6 @@ static struct vpif_config_params config_params = {
static struct vpif_device vpif_obj = { {NULL} };
static struct device *vpif_dev;
/**
* ch_params: video standard configuration parameters for vpif
*/
static const struct vpif_channel_config_params ch_params[] = {
{
"NTSC_M", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
},
{
"PAL_BDGHIK", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
},
};
/**
* vpif_uservirt_to_phys : translate user/virtual address to phy address
* @virtp: user/virtual address
@ -342,7 +329,7 @@ static void vpif_schedule_next_buffer(struct common_obj *common)
* @dev_id: dev_id ptr
*
* It changes status of the captured buffer, takes next buffer from the queue
* and sets its address in VPIF registers
* and sets its address in VPIF registers
*/
static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
{
@ -435,24 +422,31 @@ static int vpif_update_std_info(struct channel_obj *ch)
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
struct vpif_params *vpifparams = &ch->vpifparams;
const struct vpif_channel_config_params *config;
struct vpif_channel_config_params *std_info;
struct vpif_channel_config_params *std_info = &vpifparams->std_info;
struct video_obj *vid_ch = &ch->video;
int index;
vpif_dbg(2, debug, "vpif_update_std_info\n");
std_info = &vpifparams->std_info;
for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
for (index = 0; index < vpif_ch_params_count; index++) {
config = &ch_params[index];
if (config->stdid & vid_ch->stdid) {
memcpy(std_info, config, sizeof(*config));
break;
if (config->hd_sd == 0) {
vpif_dbg(2, debug, "SD format\n");
if (config->stdid & vid_ch->stdid) {
memcpy(std_info, config, sizeof(*config));
break;
}
} else {
vpif_dbg(2, debug, "HD format\n");
if (config->dv_preset == vid_ch->dv_preset) {
memcpy(std_info, config, sizeof(*config));
break;
}
}
}
/* standard not found */
if (index == ARRAY_SIZE(ch_params))
if (index == vpif_ch_params_count)
return -EINVAL;
common->fmt.fmt.pix.width = std_info->width;
@ -462,6 +456,7 @@ static int vpif_update_std_info(struct channel_obj *ch)
common->fmt.fmt.pix.bytesperline = std_info->width;
vpifparams->video_params.hpitch = std_info->width;
vpifparams->video_params.storage_mode = std_info->frm_fmt;
return 0;
}
@ -757,7 +752,7 @@ static int vpif_open(struct file *filep)
struct video_obj *vid_ch;
struct channel_obj *ch;
struct vpif_fh *fh;
int i, ret = 0;
int i;
vpif_dbg(2, debug, "vpif_open\n");
@ -766,9 +761,6 @@ static int vpif_open(struct file *filep)
vid_ch = &ch->video;
common = &ch->common[VPIF_VIDEO_INDEX];
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
if (NULL == ch->curr_subdev_info) {
/**
* search through the sub device to see a registered
@ -785,8 +777,7 @@ static int vpif_open(struct file *filep)
}
if (i == config->subdev_count) {
vpif_err("No sub device registered\n");
ret = -ENOENT;
goto exit;
return -ENOENT;
}
}
@ -794,8 +785,7 @@ static int vpif_open(struct file *filep)
fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
if (NULL == fh) {
vpif_err("unable to allocate memory for file handle object\n");
ret = -ENOMEM;
goto exit;
return -ENOMEM;
}
/* store pointer to fh in private_data member of filep */
@ -815,9 +805,7 @@ static int vpif_open(struct file *filep)
/* Initialize priority of this instance to default priority */
fh->prio = V4L2_PRIORITY_UNSET;
v4l2_prio_open(&ch->prio, &fh->prio);
exit:
mutex_unlock(&common->lock);
return ret;
return 0;
}
/**
@ -837,9 +825,6 @@ static int vpif_release(struct file *filep)
common = &ch->common[VPIF_VIDEO_INDEX];
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
/* if this instance is doing IO */
if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
/* Reset io_usrs member of channel object */
@ -863,9 +848,6 @@ static int vpif_release(struct file *filep)
/* Decrement channel usrs counter */
ch->usrs--;
/* unlock mutex on channel object */
mutex_unlock(&common->lock);
/* Close the priority */
v4l2_prio_close(&ch->prio, fh->prio);
@ -890,7 +872,6 @@ static int vpif_reqbufs(struct file *file, void *priv,
struct channel_obj *ch = fh->channel;
struct common_obj *common;
u8 index = 0;
int ret = 0;
vpif_dbg(2, debug, "vpif_reqbufs\n");
@ -913,13 +894,8 @@ static int vpif_reqbufs(struct file *file, void *priv,
common = &ch->common[index];
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
if (0 != common->io_usrs) {
ret = -EBUSY;
goto reqbuf_exit;
}
if (0 != common->io_usrs)
return -EBUSY;
/* Initialize videobuf queue as per the buffer type */
videobuf_queue_dma_contig_init(&common->buffer_queue,
@ -928,7 +904,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
reqbuf->type,
common->fmt.fmt.pix.field,
sizeof(struct videobuf_buffer), fh,
NULL);
&common->lock);
/* Set io allowed member of file handle to TRUE */
fh->io_allowed[index] = 1;
@ -939,11 +915,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
INIT_LIST_HEAD(&common->dma_queue);
/* Allocate buffers */
ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
reqbuf_exit:
mutex_unlock(&common->lock);
return ret;
return videobuf_reqbufs(&common->buffer_queue, reqbuf);
}
/**
@ -1157,11 +1129,6 @@ static int vpif_streamon(struct file *file, void *priv,
return ret;
}
if (mutex_lock_interruptible(&common->lock)) {
ret = -ERESTARTSYS;
goto streamoff_exit;
}
/* If buffer queue is empty, return error */
if (list_empty(&common->dma_queue)) {
vpif_dbg(1, debug, "buffer queue is empty\n");
@ -1240,13 +1207,10 @@ static int vpif_streamon(struct file *file, void *priv,
enable_channel1(1);
}
channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
mutex_unlock(&common->lock);
return ret;
exit:
mutex_unlock(&common->lock);
streamoff_exit:
ret = videobuf_streamoff(&common->buffer_queue);
videobuf_streamoff(&common->buffer_queue);
return ret;
}
@ -1284,9 +1248,6 @@ static int vpif_streamoff(struct file *file, void *priv,
return -EINVAL;
}
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
/* disable channel */
if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
enable_channel0(0);
@ -1304,8 +1265,6 @@ static int vpif_streamoff(struct file *file, void *priv,
if (ret && (ret != -ENOIOCTLCMD))
vpif_dbg(1, debug, "stream off failed in subdev\n");
mutex_unlock(&common->lock);
return videobuf_streamoff(&common->buffer_queue);
}
@ -1381,21 +1340,16 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
int ret = 0;
vpif_dbg(2, debug, "vpif_querystd\n");
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
/* Call querystd function of decoder device */
ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
querystd, std_id);
if (ret < 0)
vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
mutex_unlock(&common->lock);
return ret;
}
@ -1451,16 +1405,14 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
fh->initialized = 1;
/* Call encoder subdevice function to set the standard */
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
ch->video.stdid = *std_id;
ch->video.dv_preset = V4L2_DV_INVALID;
memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
/* Get the information about the standard */
if (vpif_update_std_info(ch)) {
ret = -EINVAL;
vpif_err("Error getting the standard info\n");
goto s_std_exit;
return -EINVAL;
}
/* Configure the default format information */
@ -1471,9 +1423,6 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
s_std, *std_id);
if (ret < 0)
vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
s_std_exit:
mutex_unlock(&common->lock);
return ret;
}
@ -1567,9 +1516,6 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
return -EINVAL;
}
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
/* first setup input path from sub device to vpif */
if (config->setup_input_path) {
ret = config->setup_input_path(ch->channel_id,
@ -1578,7 +1524,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
vpif_dbg(1, debug, "couldn't setup input path for the"
" sub device %s, for input index %d\n",
subdev_info->name, index);
goto exit;
return ret;
}
}
@ -1589,7 +1535,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
input, output, 0);
if (ret < 0) {
vpif_dbg(1, debug, "Failed to set input\n");
goto exit;
return ret;
}
}
vid_ch->input_idx = index;
@ -1600,9 +1546,6 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
/* update tvnorms from the sub device input info */
ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
exit:
mutex_unlock(&common->lock);
return ret;
}
@ -1671,11 +1614,7 @@ static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
return -EINVAL;
/* Fill in the information about format */
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
*fmt = common->fmt;
mutex_unlock(&common->lock);
return 0;
}
@ -1694,7 +1633,7 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_pix_format *pixfmt;
int ret = 0;
vpif_dbg(2, debug, "VIDIOC_S_FMT\n");
vpif_dbg(2, debug, "%s\n", __func__);
/* If streaming is started, return error */
if (common->started) {
@ -1723,12 +1662,7 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
if (ret)
return ret;
/* store the format in the channel object */
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
common->fmt = *fmt;
mutex_unlock(&common->lock);
return 0;
}
@ -1807,6 +1741,306 @@ static int vpif_cropcap(struct file *file, void *priv,
return 0;
}
/**
* vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
* @file: file ptr
* @priv: file handle
* @preset: input preset
*/
static int vpif_enum_dv_presets(struct file *file, void *priv,
struct v4l2_dv_enum_preset *preset)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
video, enum_dv_presets, preset);
}
/**
* vpif_query_dv_presets() - QUERY_DV_PRESET handler
* @file: file ptr
* @priv: file handle
* @preset: input preset
*/
static int vpif_query_dv_preset(struct file *file, void *priv,
struct v4l2_dv_preset *preset)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
video, query_dv_preset, preset);
}
/**
* vpif_s_dv_presets() - S_DV_PRESETS handler
* @file: file ptr
* @priv: file handle
* @preset: input preset
*/
static int vpif_s_dv_preset(struct file *file, void *priv,
struct v4l2_dv_preset *preset)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
int ret = 0;
if (common->started) {
vpif_dbg(1, debug, "streaming in progress\n");
return -EBUSY;
}
if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
(VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
if (!fh->initialized) {
vpif_dbg(1, debug, "Channel Busy\n");
return -EBUSY;
}
}
ret = v4l2_prio_check(&ch->prio, fh->prio);
if (ret)
return ret;
fh->initialized = 1;
/* Call encoder subdevice function to set the standard */
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
ch->video.dv_preset = preset->preset;
ch->video.stdid = V4L2_STD_UNKNOWN;
memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
/* Get the information about the standard */
if (vpif_update_std_info(ch)) {
vpif_dbg(1, debug, "Error getting the standard info\n");
ret = -EINVAL;
} else {
/* Configure the default format information */
vpif_config_format(ch);
ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
video, s_dv_preset, preset);
}
mutex_unlock(&common->lock);
return ret;
}
/**
* vpif_g_dv_presets() - G_DV_PRESETS handler
* @file: file ptr
* @priv: file handle
* @preset: input preset
*/
static int vpif_g_dv_preset(struct file *file, void *priv,
struct v4l2_dv_preset *preset)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
preset->preset = ch->video.dv_preset;
return 0;
}
/**
* vpif_s_dv_timings() - S_DV_TIMINGS handler
* @file: file ptr
* @priv: file handle
* @timings: digital video timings
*/
static int vpif_s_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct vpif_params *vpifparams = &ch->vpifparams;
struct vpif_channel_config_params *std_info = &vpifparams->std_info;
struct video_obj *vid_ch = &ch->video;
struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
int ret;
if (timings->type != V4L2_DV_BT_656_1120) {
vpif_dbg(2, debug, "Timing type not defined\n");
return -EINVAL;
}
/* Configure subdevice timings, if any */
ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
video, s_dv_timings, timings);
if (ret == -ENOIOCTLCMD) {
vpif_dbg(2, debug, "Custom DV timings not supported by "
"subdevice\n");
return -EINVAL;
}
if (ret < 0) {
vpif_dbg(2, debug, "Error setting custom DV timings\n");
return ret;
}
if (!(timings->bt.width && timings->bt.height &&
(timings->bt.hbackporch ||
timings->bt.hfrontporch ||
timings->bt.hsync) &&
timings->bt.vfrontporch &&
(timings->bt.vbackporch ||
timings->bt.vsync))) {
vpif_dbg(2, debug, "Timings for width, height, "
"horizontal back porch, horizontal sync, "
"horizontal front porch, vertical back porch, "
"vertical sync and vertical back porch "
"must be defined\n");
return -EINVAL;
}
*bt = timings->bt;
/* Configure video port timings */
std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
bt->hsync - 8;
std_info->sav2eav = bt->width;
std_info->l1 = 1;
std_info->l3 = bt->vsync + bt->vbackporch + 1;
if (bt->interlaced) {
if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
std_info->vsize = bt->height * 2 +
bt->vfrontporch + bt->vsync + bt->vbackporch +
bt->il_vfrontporch + bt->il_vsync +
bt->il_vbackporch;
std_info->l5 = std_info->vsize/2 -
(bt->vfrontporch - 1);
std_info->l7 = std_info->vsize/2 + 1;
std_info->l9 = std_info->l7 + bt->il_vsync +
bt->il_vbackporch + 1;
std_info->l11 = std_info->vsize -
(bt->il_vfrontporch - 1);
} else {
vpif_dbg(2, debug, "Required timing values for "
"interlaced BT format missing\n");
return -EINVAL;
}
} else {
std_info->vsize = bt->height + bt->vfrontporch +
bt->vsync + bt->vbackporch;
std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
}
strncpy(std_info->name, "Custom timings BT656/1120", VPIF_MAX_NAME);
std_info->width = bt->width;
std_info->height = bt->height;
std_info->frm_fmt = bt->interlaced ? 0 : 1;
std_info->ycmux_mode = 0;
std_info->capture_format = 0;
std_info->vbi_supported = 0;
std_info->hd_sd = 1;
std_info->stdid = 0;
std_info->dv_preset = V4L2_DV_INVALID;
vid_ch->stdid = 0;
vid_ch->dv_preset = V4L2_DV_INVALID;
return 0;
}
/**
* vpif_g_dv_timings() - G_DV_TIMINGS handler
* @file: file ptr
* @priv: file handle
* @timings: digital video timings
*/
static int vpif_g_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct video_obj *vid_ch = &ch->video;
struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
timings->bt = *bt;
return 0;
}
/*
* vpif_g_chip_ident() - Identify the chip
* @file: file ptr
* @priv: file handle
* @chip: chip identity
*
* Returns zero or -EINVAL if read operations fails.
*/
static int vpif_g_chip_ident(struct file *file, void *priv,
struct v4l2_dbg_chip_ident *chip)
{
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
vpif_dbg(2, debug, "match_type is invalid.\n");
return -EINVAL;
}
return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
g_chip_ident, chip);
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
/*
* vpif_dbg_g_register() - Read register
* @file: file ptr
* @priv: file handle
* @reg: register to be read
*
* Debugging only
* Returns zero or -EINVAL if read operations fails.
*/
static int vpif_dbg_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg){
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
g_register, reg);
}
/*
* vpif_dbg_s_register() - Write to register
* @file: file ptr
* @priv: file handle
* @reg: register to be modified
*
* Debugging only
* Returns zero or -EINVAL if write operations fails.
*/
static int vpif_dbg_s_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg){
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
s_register, reg);
}
#endif
/*
* vpif_log_status() - Status information
* @file: file ptr
* @priv: file handle
*
* Returns zero.
*/
static int vpif_log_status(struct file *filep, void *priv)
{
/* status for sub devices */
v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
return 0;
}
/* vpif capture ioctl operations */
static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
.vidioc_querycap = vpif_querycap,
@ -1829,6 +2063,18 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
.vidioc_streamon = vpif_streamon,
.vidioc_streamoff = vpif_streamoff,
.vidioc_cropcap = vpif_cropcap,
.vidioc_enum_dv_presets = vpif_enum_dv_presets,
.vidioc_s_dv_preset = vpif_s_dv_preset,
.vidioc_g_dv_preset = vpif_g_dv_preset,
.vidioc_query_dv_preset = vpif_query_dv_preset,
.vidioc_s_dv_timings = vpif_s_dv_timings,
.vidioc_g_dv_timings = vpif_g_dv_timings,
.vidioc_g_chip_ident = vpif_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vpif_dbg_g_register,
.vidioc_s_register = vpif_dbg_s_register,
#endif
.vidioc_log_status = vpif_log_status,
};
/* vpif file operations */
@ -1836,7 +2082,7 @@ static struct v4l2_file_operations vpif_fops = {
.owner = THIS_MODULE,
.open = vpif_open,
.release = vpif_release,
.ioctl = video_ioctl2,
.unlocked_ioctl = video_ioctl2,
.mmap = vpif_mmap,
.poll = vpif_poll
};
@ -1979,6 +2225,7 @@ static __init int vpif_probe(struct platform_device *pdev)
common = &(ch->common[VPIF_VIDEO_INDEX]);
spin_lock_init(&common->irqlock);
mutex_init(&common->lock);
ch->video_dev->lock = &common->lock;
/* Initialize prio member of channel object */
v4l2_prio_init(&ch->prio);
err = video_register_device(ch->video_dev,
@ -2026,9 +2273,9 @@ static __init int vpif_probe(struct platform_device *pdev)
if (vpif_obj.sd[i])
vpif_obj.sd[i]->grp_id = 1 << i;
}
v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF Capture driver"
" initialized\n");
v4l2_info(&vpif_obj.v4l2_dev,
"DM646x VPIF capture driver initialized\n");
return 0;
probe_subdev_out:

View file

@ -59,6 +59,8 @@ struct video_obj {
enum v4l2_field buf_field;
/* Currently selected or default standard */
v4l2_std_id stdid;
u32 dv_preset;
struct v4l2_bt_timings bt_timings;
/* This is to track the last input that is passed to application */
u32 input_idx;
};

View file

@ -38,6 +38,7 @@
#include <media/adv7343.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-chip-ident.h>
#include <mach/dm646x.h>
@ -84,17 +85,6 @@ static struct vpif_config_params config_params = {
static struct vpif_device vpif_obj = { {NULL} };
static struct device *vpif_dev;
static const struct vpif_channel_config_params ch_params[] = {
{
"NTSC", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
},
{
"PAL", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
},
};
/*
* vpif_uservirt_to_phys: This function is used to convert user
* space virtual address to physical address.
@ -373,30 +363,54 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
static int vpif_get_std_info(struct channel_obj *ch)
static int vpif_update_std_info(struct channel_obj *ch)
{
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
struct video_obj *vid_ch = &ch->video;
struct vpif_params *vpifparams = &ch->vpifparams;
struct vpif_channel_config_params *std_info = &vpifparams->std_info;
const struct vpif_channel_config_params *config;
int index;
int i;
std_info->stdid = vid_ch->stdid;
if (!std_info->stdid)
return -1;
for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
config = &ch_params[index];
if (config->stdid & std_info->stdid) {
memcpy(std_info, config, sizeof(*config));
break;
for (i = 0; i < vpif_ch_params_count; i++) {
config = &ch_params[i];
if (config->hd_sd == 0) {
vpif_dbg(2, debug, "SD format\n");
if (config->stdid & vid_ch->stdid) {
memcpy(std_info, config, sizeof(*config));
break;
}
} else {
vpif_dbg(2, debug, "HD format\n");
if (config->dv_preset == vid_ch->dv_preset) {
memcpy(std_info, config, sizeof(*config));
break;
}
}
}
if (index == ARRAY_SIZE(ch_params))
return -1;
if (i == vpif_ch_params_count) {
vpif_dbg(1, debug, "Format not found\n");
return -EINVAL;
}
return 0;
}
static int vpif_update_resolution(struct channel_obj *ch)
{
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
struct video_obj *vid_ch = &ch->video;
struct vpif_params *vpifparams = &ch->vpifparams;
struct vpif_channel_config_params *std_info = &vpifparams->std_info;
if (!vid_ch->stdid && !vid_ch->dv_preset && !vid_ch->bt_timings.height)
return -EINVAL;
if (vid_ch->stdid || vid_ch->dv_preset) {
if (vpif_update_std_info(ch))
return -EINVAL;
}
common->fmt.fmt.pix.width = std_info->width;
common->fmt.fmt.pix.height = std_info->height;
@ -404,8 +418,8 @@ static int vpif_get_std_info(struct channel_obj *ch)
common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
/* Set height and width paramateres */
ch->common[VPIF_VIDEO_INDEX].height = std_info->height;
ch->common[VPIF_VIDEO_INDEX].width = std_info->width;
common->height = std_info->height;
common->width = std_info->width;
return 0;
}
@ -516,10 +530,8 @@ static int vpif_check_format(struct channel_obj *ch,
else
sizeimage = config_params.channel_bufsize[ch->channel_id];
if (vpif_get_std_info(ch)) {
vpif_err("Error getting the standard info\n");
if (vpif_update_resolution(ch))
return -EINVAL;
}
hpitch = pixfmt->bytesperline;
vpitch = sizeimage / (hpitch * 2);
@ -568,7 +580,10 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
{
struct vpif_fh *fh = filep->private_data;
struct common_obj *common = &fh->channel->common[VPIF_VIDEO_INDEX];
struct channel_obj *ch = fh->channel;
struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
vpif_dbg(2, debug, "vpif_mmap\n");
return videobuf_mmap_mapper(&common->buffer_queue, vma);
}
@ -637,9 +652,6 @@ static int vpif_release(struct file *filep)
struct channel_obj *ch = fh->channel;
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
/* if this instance is doing IO */
if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
/* Reset io_usrs member of channel object */
@ -662,8 +674,6 @@ static int vpif_release(struct file *filep)
config_params.numbuffers[ch->channel_id];
}
mutex_unlock(&common->lock);
/* Decrement channel usrs counter */
atomic_dec(&ch->usrs);
/* If this file handle has initialize encoder device, reset it */
@ -680,7 +690,12 @@ static int vpif_release(struct file *filep)
}
/* functions implementing ioctls */
/**
* vpif_querycap() - QUERYCAP handler
* @file: file ptr
* @priv: file handle
* @cap: ptr to v4l2_capability structure
*/
static int vpif_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
@ -722,17 +737,9 @@ static int vpif_g_fmt_vid_out(struct file *file, void *priv,
if (common->fmt.type != fmt->type)
return -EINVAL;
/* Fill in the information about format */
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
if (vpif_get_std_info(ch)) {
vpif_err("Error getting the standard info\n");
if (vpif_update_resolution(ch))
return -EINVAL;
}
*fmt = common->fmt;
mutex_unlock(&common->lock);
return 0;
}
@ -773,12 +780,7 @@ static int vpif_s_fmt_vid_out(struct file *file, void *priv,
/* store the pix format in the channel object */
common->fmt.fmt.pix = *pixfmt;
/* store the format in the channel object */
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
common->fmt = *fmt;
mutex_unlock(&common->lock);
return 0;
}
@ -808,7 +810,6 @@ static int vpif_reqbufs(struct file *file, void *priv,
struct common_obj *common;
enum v4l2_field field;
u8 index = 0;
int ret = 0;
/* This file handle has not initialized the channel,
It is not allowed to do settings */
@ -826,18 +827,12 @@ static int vpif_reqbufs(struct file *file, void *priv,
index = VPIF_VIDEO_INDEX;
common = &ch->common[index];
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
if (common->fmt.type != reqbuf->type) {
ret = -EINVAL;
goto reqbuf_exit;
}
if (common->fmt.type != reqbuf->type)
return -EINVAL;
if (0 != common->io_usrs) {
ret = -EBUSY;
goto reqbuf_exit;
}
if (0 != common->io_usrs)
return -EBUSY;
if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
@ -854,7 +849,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
&common->irqlock,
reqbuf->type, field,
sizeof(struct videobuf_buffer), fh,
NULL);
&common->lock);
/* Set io allowed member of file handle to TRUE */
fh->io_allowed[index] = 1;
@ -865,11 +860,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
INIT_LIST_HEAD(&common->dma_queue);
/* Allocate buffers */
ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
reqbuf_exit:
mutex_unlock(&common->lock);
return ret;
return videobuf_reqbufs(&common->buffer_queue, reqbuf);
}
static int vpif_querybuf(struct file *file, void *priv,
@ -990,22 +981,19 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
}
/* Call encoder subdevice function to set the standard */
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
ch->video.stdid = *std_id;
ch->video.dv_preset = V4L2_DV_INVALID;
memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
/* Get the information about the standard */
if (vpif_get_std_info(ch)) {
vpif_err("Error getting the standard info\n");
if (vpif_update_resolution(ch))
return -EINVAL;
}
if ((ch->vpifparams.std_info.width *
ch->vpifparams.std_info.height * 2) >
config_params.channel_bufsize[ch->channel_id]) {
vpif_err("invalid std for this size\n");
ret = -EINVAL;
goto s_std_exit;
return -EINVAL;
}
common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
@ -1016,16 +1004,13 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
s_std_output, *std_id);
if (ret < 0) {
vpif_err("Failed to set output standard\n");
goto s_std_exit;
return ret;
}
ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
s_std, *std_id);
if (ret < 0)
vpif_err("Failed to set standard for sub devices\n");
s_std_exit:
mutex_unlock(&common->lock);
return ret;
}
@ -1090,21 +1075,17 @@ static int vpif_streamon(struct file *file, void *priv,
if (ret < 0)
return ret;
/* Call videobuf_streamon to start streaming in videobuf */
/* Call videobuf_streamon to start streaming in videobuf */
ret = videobuf_streamon(&common->buffer_queue);
if (ret < 0) {
vpif_err("videobuf_streamon\n");
return ret;
}
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
/* If buffer queue is empty, return error */
if (list_empty(&common->dma_queue)) {
vpif_err("buffer queue is empty\n");
ret = -EIO;
goto streamon_exit;
return -EIO;
}
/* Get the next frame from the buffer queue */
@ -1130,8 +1111,7 @@ static int vpif_streamon(struct file *file, void *priv,
|| (!ch->vpifparams.std_info.frm_fmt
&& (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
vpif_err("conflict in field format and std format\n");
ret = -EINVAL;
goto streamon_exit;
return -EINVAL;
}
/* clock settings */
@ -1140,13 +1120,13 @@ static int vpif_streamon(struct file *file, void *priv,
ch->vpifparams.std_info.hd_sd);
if (ret < 0) {
vpif_err("can't set clock\n");
goto streamon_exit;
return ret;
}
/* set the parameters and addresses */
ret = vpif_set_video_params(vpif, ch->channel_id + 2);
if (ret < 0)
goto streamon_exit;
return ret;
common->started = ret;
vpif_config_addr(ch, ret);
@ -1171,9 +1151,6 @@ static int vpif_streamon(struct file *file, void *priv,
}
channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
}
streamon_exit:
mutex_unlock(&common->lock);
return ret;
}
@ -1199,9 +1176,6 @@ static int vpif_streamoff(struct file *file, void *priv,
return -EINVAL;
}
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
/* disable channel */
if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
@ -1216,8 +1190,6 @@ static int vpif_streamoff(struct file *file, void *priv,
}
common->started = 0;
mutex_unlock(&common->lock);
return videobuf_streamoff(&common->buffer_queue);
}
@ -1264,13 +1236,9 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i)
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
int ret = 0;
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
if (common->started) {
vpif_err("Streaming in progress\n");
ret = -EBUSY;
goto s_output_exit;
return -EBUSY;
}
ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
@ -1280,9 +1248,6 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i)
vpif_err("Failed to set output standard\n");
vid_ch->output_id = i;
s_output_exit:
mutex_unlock(&common->lock);
return ret;
}
@ -1315,6 +1280,287 @@ static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
return v4l2_prio_change(&ch->prio, &fh->prio, p);
}
/**
* vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
* @file: file ptr
* @priv: file handle
* @preset: input preset
*/
static int vpif_enum_dv_presets(struct file *file, void *priv,
struct v4l2_dv_enum_preset *preset)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct video_obj *vid_ch = &ch->video;
return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
video, enum_dv_presets, preset);
}
/**
* vpif_s_dv_presets() - S_DV_PRESETS handler
* @file: file ptr
* @priv: file handle
* @preset: input preset
*/
static int vpif_s_dv_preset(struct file *file, void *priv,
struct v4l2_dv_preset *preset)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
struct video_obj *vid_ch = &ch->video;
int ret = 0;
if (common->started) {
vpif_dbg(1, debug, "streaming in progress\n");
return -EBUSY;
}
ret = v4l2_prio_check(&ch->prio, fh->prio);
if (ret != 0)
return ret;
fh->initialized = 1;
/* Call encoder subdevice function to set the standard */
if (mutex_lock_interruptible(&common->lock))
return -ERESTARTSYS;
ch->video.dv_preset = preset->preset;
ch->video.stdid = V4L2_STD_UNKNOWN;
memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
/* Get the information about the standard */
if (vpif_update_resolution(ch)) {
ret = -EINVAL;
} else {
/* Configure the default format information */
vpif_config_format(ch);
ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
video, s_dv_preset, preset);
}
mutex_unlock(&common->lock);
return ret;
}
/**
* vpif_g_dv_presets() - G_DV_PRESETS handler
* @file: file ptr
* @priv: file handle
* @preset: input preset
*/
static int vpif_g_dv_preset(struct file *file, void *priv,
struct v4l2_dv_preset *preset)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
preset->preset = ch->video.dv_preset;
return 0;
}
/**
* vpif_s_dv_timings() - S_DV_TIMINGS handler
* @file: file ptr
* @priv: file handle
* @timings: digital video timings
*/
static int vpif_s_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct vpif_params *vpifparams = &ch->vpifparams;
struct vpif_channel_config_params *std_info = &vpifparams->std_info;
struct video_obj *vid_ch = &ch->video;
struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
int ret;
if (timings->type != V4L2_DV_BT_656_1120) {
vpif_dbg(2, debug, "Timing type not defined\n");
return -EINVAL;
}
/* Configure subdevice timings, if any */
ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
video, s_dv_timings, timings);
if (ret == -ENOIOCTLCMD) {
vpif_dbg(2, debug, "Custom DV timings not supported by "
"subdevice\n");
return -EINVAL;
}
if (ret < 0) {
vpif_dbg(2, debug, "Error setting custom DV timings\n");
return ret;
}
if (!(timings->bt.width && timings->bt.height &&
(timings->bt.hbackporch ||
timings->bt.hfrontporch ||
timings->bt.hsync) &&
timings->bt.vfrontporch &&
(timings->bt.vbackporch ||
timings->bt.vsync))) {
vpif_dbg(2, debug, "Timings for width, height, "
"horizontal back porch, horizontal sync, "
"horizontal front porch, vertical back porch, "
"vertical sync and vertical back porch "
"must be defined\n");
return -EINVAL;
}
*bt = timings->bt;
/* Configure video port timings */
std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
bt->hsync - 8;
std_info->sav2eav = bt->width;
std_info->l1 = 1;
std_info->l3 = bt->vsync + bt->vbackporch + 1;
if (bt->interlaced) {
if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
std_info->vsize = bt->height * 2 +
bt->vfrontporch + bt->vsync + bt->vbackporch +
bt->il_vfrontporch + bt->il_vsync +
bt->il_vbackporch;
std_info->l5 = std_info->vsize/2 -
(bt->vfrontporch - 1);
std_info->l7 = std_info->vsize/2 + 1;
std_info->l9 = std_info->l7 + bt->il_vsync +
bt->il_vbackporch + 1;
std_info->l11 = std_info->vsize -
(bt->il_vfrontporch - 1);
} else {
vpif_dbg(2, debug, "Required timing values for "
"interlaced BT format missing\n");
return -EINVAL;
}
} else {
std_info->vsize = bt->height + bt->vfrontporch +
bt->vsync + bt->vbackporch;
std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
}
strncpy(std_info->name, "Custom timings BT656/1120",
VPIF_MAX_NAME);
std_info->width = bt->width;
std_info->height = bt->height;
std_info->frm_fmt = bt->interlaced ? 0 : 1;
std_info->ycmux_mode = 0;
std_info->capture_format = 0;
std_info->vbi_supported = 0;
std_info->hd_sd = 1;
std_info->stdid = 0;
std_info->dv_preset = V4L2_DV_INVALID;
vid_ch->stdid = 0;
vid_ch->dv_preset = V4L2_DV_INVALID;
return 0;
}
/**
* vpif_g_dv_timings() - G_DV_TIMINGS handler
* @file: file ptr
* @priv: file handle
* @timings: digital video timings
*/
static int vpif_g_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct video_obj *vid_ch = &ch->video;
struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
timings->bt = *bt;
return 0;
}
/*
* vpif_g_chip_ident() - Identify the chip
* @file: file ptr
* @priv: file handle
* @chip: chip identity
*
* Returns zero or -EINVAL if read operations fails.
*/
static int vpif_g_chip_ident(struct file *file, void *priv,
struct v4l2_dbg_chip_ident *chip)
{
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
vpif_dbg(2, debug, "match_type is invalid.\n");
return -EINVAL;
}
return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
g_chip_ident, chip);
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
/*
* vpif_dbg_g_register() - Read register
* @file: file ptr
* @priv: file handle
* @reg: register to be read
*
* Debugging only
* Returns zero or -EINVAL if read operations fails.
*/
static int vpif_dbg_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg){
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct video_obj *vid_ch = &ch->video;
return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
g_register, reg);
}
/*
* vpif_dbg_s_register() - Write to register
* @file: file ptr
* @priv: file handle
* @reg: register to be modified
*
* Debugging only
* Returns zero or -EINVAL if write operations fails.
*/
static int vpif_dbg_s_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg){
struct vpif_fh *fh = priv;
struct channel_obj *ch = fh->channel;
struct video_obj *vid_ch = &ch->video;
return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
s_register, reg);
}
#endif
/*
* vpif_log_status() - Status information
* @file: file ptr
* @priv: file handle
*
* Returns zero.
*/
static int vpif_log_status(struct file *filep, void *priv)
{
/* status for sub devices */
v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
return 0;
}
/* vpif display ioctl operations */
static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
.vidioc_querycap = vpif_querycap,
@ -1336,13 +1582,24 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
.vidioc_s_output = vpif_s_output,
.vidioc_g_output = vpif_g_output,
.vidioc_cropcap = vpif_cropcap,
.vidioc_enum_dv_presets = vpif_enum_dv_presets,
.vidioc_s_dv_preset = vpif_s_dv_preset,
.vidioc_g_dv_preset = vpif_g_dv_preset,
.vidioc_s_dv_timings = vpif_s_dv_timings,
.vidioc_g_dv_timings = vpif_g_dv_timings,
.vidioc_g_chip_ident = vpif_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vpif_dbg_g_register,
.vidioc_s_register = vpif_dbg_s_register,
#endif
.vidioc_log_status = vpif_log_status,
};
static const struct v4l2_file_operations vpif_fops = {
.owner = THIS_MODULE,
.open = vpif_open,
.release = vpif_release,
.ioctl = video_ioctl2,
.unlocked_ioctl = video_ioctl2,
.mmap = vpif_mmap,
.poll = vpif_poll
};
@ -1526,6 +1783,7 @@ static __init int vpif_probe(struct platform_device *pdev)
v4l2_prio_init(&ch->prio);
ch->common[VPIF_VIDEO_INDEX].fmt.type =
V4L2_BUF_TYPE_VIDEO_OUTPUT;
ch->video_dev->lock = &common->lock;
/* register video device */
vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
@ -1565,6 +1823,8 @@ static __init int vpif_probe(struct platform_device *pdev)
vpif_obj.sd[i]->grp_id = 1 << i;
}
v4l2_info(&vpif_obj.v4l2_dev,
"DM646x VPIF display driver initialized\n");
return 0;
probe_subdev_out:

View file

@ -67,6 +67,8 @@ struct video_obj {
* most recent displayed frame only */
v4l2_std_id stdid; /* Currently selected or default
* standard */
u32 dv_preset;
struct v4l2_bt_timings bt_timings;
u32 output_id; /* Current output id */
};

View file

@ -33,6 +33,7 @@
#include <media/saa7115.h>
#include <media/tvp5150.h>
#include <media/tvaudio.h>
#include <media/mt9v011.h>
#include <media/i2c-addr.h>
#include <media/tveeprom.h>
#include <media/v4l2-common.h>
@ -1917,11 +1918,6 @@ static unsigned short tvp5150_addrs[] = {
I2C_CLIENT_END
};
static unsigned short mt9v011_addrs[] = {
0xba >> 1,
I2C_CLIENT_END
};
static unsigned short msp3400_addrs[] = {
0x80 >> 1,
0x88 >> 1,
@ -2437,6 +2433,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
dev->init_data.ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW;
dev->init_data.get_key = em28xx_get_key_em_haup;
dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
break;
case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE;
dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe;
@ -2623,11 +2620,17 @@ void em28xx_card_setup(struct em28xx *dev)
"tvp5150", 0, tvp5150_addrs);
if (dev->em28xx_sensor == EM28XX_MT9V011) {
struct mt9v011_platform_data pdata;
struct i2c_board_info mt9v011_info = {
.type = "mt9v011",
.addr = 0xba >> 1,
.platform_data = &pdata,
};
struct v4l2_subdev *sd;
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_adap, "mt9v011", 0, mt9v011_addrs);
v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
pdata.xtal = dev->sensor_xtal;
sd = v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap,
&mt9v011_info, NULL);
}

View file

@ -59,31 +59,7 @@
/*****************************************************************************/
static const struct usb_device_id et61x251_id_table[] = {
{ USB_DEVICE(0x102c, 0x6151), },
{ USB_DEVICE(0x102c, 0x6251), },
{ USB_DEVICE(0x102c, 0x6253), },
{ USB_DEVICE(0x102c, 0x6254), },
{ USB_DEVICE(0x102c, 0x6255), },
{ USB_DEVICE(0x102c, 0x6256), },
{ USB_DEVICE(0x102c, 0x6257), },
{ USB_DEVICE(0x102c, 0x6258), },
{ USB_DEVICE(0x102c, 0x6259), },
{ USB_DEVICE(0x102c, 0x625a), },
{ USB_DEVICE(0x102c, 0x625b), },
{ USB_DEVICE(0x102c, 0x625c), },
{ USB_DEVICE(0x102c, 0x625d), },
{ USB_DEVICE(0x102c, 0x625e), },
{ USB_DEVICE(0x102c, 0x625f), },
{ USB_DEVICE(0x102c, 0x6260), },
{ USB_DEVICE(0x102c, 0x6261), },
{ USB_DEVICE(0x102c, 0x6262), },
{ USB_DEVICE(0x102c, 0x6263), },
{ USB_DEVICE(0x102c, 0x6264), },
{ USB_DEVICE(0x102c, 0x6265), },
{ USB_DEVICE(0x102c, 0x6266), },
{ USB_DEVICE(0x102c, 0x6267), },
{ USB_DEVICE(0x102c, 0x6268), },
{ USB_DEVICE(0x102c, 0x6269), },
{ }
};

View file

@ -276,7 +276,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x04a5, 0x3035)},
{}
};

View file

@ -1040,14 +1040,14 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const struct usb_device_id device_table[] __devinitconst = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0572, 0x0041)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
static int __devinit sd_probe(struct usb_interface *intf,
static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

View file

@ -2088,7 +2088,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0553, 0x0002)},
{USB_DEVICE(0x0813, 0x0001)},
{}

View file

@ -864,7 +864,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const struct usb_device_id device_table[] __devinitconst = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
@ -875,7 +875,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
static int __devinit sd_probe(struct usb_interface *intf,
static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

View file

@ -229,7 +229,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
}
/* Table of supported USB devices */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x04cb, 0x0104)},
{USB_DEVICE(0x04cb, 0x0109)},
{USB_DEVICE(0x04cb, 0x010b)},

View file

@ -488,7 +488,7 @@ static void sd_callback(struct gspca_dev *gspca_dev)
/*=================== USB driver structure initialisation ==================*/
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x05e3, 0x0503)},
{USB_DEVICE(0x05e3, 0xf191)},
{}

View file

@ -55,7 +55,7 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 11, 0)
#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 12, 0)
#ifdef GSPCA_DEBUG
int gspca_debug = D_ERR | D_PROBE;
@ -508,8 +508,8 @@ static int gspca_is_compressed(__u32 format)
return 0;
}
static int frame_alloc(struct gspca_dev *gspca_dev,
unsigned int count)
static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file,
enum v4l2_memory memory, unsigned int count)
{
struct gspca_frame *frame;
unsigned int frsz;
@ -519,7 +519,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
frsz = gspca_dev->cam.cam_mode[i].sizeimage;
PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
frsz = PAGE_ALIGN(frsz);
gspca_dev->frsz = frsz;
if (count >= GSPCA_MAX_FRAMES)
count = GSPCA_MAX_FRAMES - 1;
gspca_dev->frbuf = vmalloc_32(frsz * count);
@ -527,6 +526,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
err("frame alloc failed");
return -ENOMEM;
}
gspca_dev->capt_file = file;
gspca_dev->memory = memory;
gspca_dev->frsz = frsz;
gspca_dev->nframes = count;
for (i = 0; i < count; i++) {
frame = &gspca_dev->frame[i];
@ -535,7 +537,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
frame->v4l2_buf.flags = 0;
frame->v4l2_buf.field = V4L2_FIELD_NONE;
frame->v4l2_buf.length = frsz;
frame->v4l2_buf.memory = gspca_dev->memory;
frame->v4l2_buf.memory = memory;
frame->v4l2_buf.sequence = 0;
frame->data = gspca_dev->frbuf + i * frsz;
frame->v4l2_buf.m.offset = i * frsz;
@ -558,6 +560,9 @@ static void frame_free(struct gspca_dev *gspca_dev)
gspca_dev->frame[i].data = NULL;
}
gspca_dev->nframes = 0;
gspca_dev->frsz = 0;
gspca_dev->capt_file = NULL;
gspca_dev->memory = GSPCA_MEMORY_NO;
}
static void destroy_urbs(struct gspca_dev *gspca_dev)
@ -1210,29 +1215,15 @@ static void gspca_release(struct video_device *vfd)
static int dev_open(struct file *file)
{
struct gspca_dev *gspca_dev;
int ret;
PDEBUG(D_STREAM, "[%s] open", current->comm);
gspca_dev = (struct gspca_dev *) video_devdata(file);
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
if (!gspca_dev->present) {
ret = -ENODEV;
goto out;
}
if (gspca_dev->users > 4) { /* (arbitrary value) */
ret = -EBUSY;
goto out;
}
if (!gspca_dev->present)
return -ENODEV;
/* protect the subdriver against rmmod */
if (!try_module_get(gspca_dev->module)) {
ret = -ENODEV;
goto out;
}
gspca_dev->users++;
if (!try_module_get(gspca_dev->module))
return -ENODEV;
file->private_data = gspca_dev;
#ifdef GSPCA_DEBUG
@ -1244,14 +1235,7 @@ static int dev_open(struct file *file)
gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
| V4L2_DEBUG_IOCTL_ARG);
#endif
ret = 0;
out:
mutex_unlock(&gspca_dev->queue_lock);
if (ret != 0)
PDEBUG(D_ERR|D_STREAM, "open failed err %d", ret);
else
PDEBUG(D_STREAM, "open done");
return ret;
return 0;
}
static int dev_close(struct file *file)
@ -1261,7 +1245,6 @@ static int dev_close(struct file *file)
PDEBUG(D_STREAM, "[%s] close", current->comm);
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
gspca_dev->users--;
/* if the file did the capture, free the streaming resources */
if (gspca_dev->capt_file == file) {
@ -1272,8 +1255,6 @@ static int dev_close(struct file *file)
mutex_unlock(&gspca_dev->usb_lock);
}
frame_free(gspca_dev);
gspca_dev->capt_file = NULL;
gspca_dev->memory = GSPCA_MEMORY_NO;
}
file->private_data = NULL;
module_put(gspca_dev->module);
@ -1516,6 +1497,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
return -ERESTARTSYS;
if (gspca_dev->memory != GSPCA_MEMORY_NO
&& gspca_dev->memory != GSPCA_MEMORY_READ
&& gspca_dev->memory != rb->memory) {
ret = -EBUSY;
goto out;
@ -1544,19 +1526,18 @@ static int vidioc_reqbufs(struct file *file, void *priv,
gspca_stream_off(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
/* Don't restart the stream when switching from read to mmap mode */
if (gspca_dev->memory == GSPCA_MEMORY_READ)
streaming = 0;
/* free the previous allocated buffers, if any */
if (gspca_dev->nframes != 0) {
if (gspca_dev->nframes != 0)
frame_free(gspca_dev);
gspca_dev->capt_file = NULL;
}
if (rb->count == 0) /* unrequest */
goto out;
gspca_dev->memory = rb->memory;
ret = frame_alloc(gspca_dev, rb->count);
ret = frame_alloc(gspca_dev, file, rb->memory, rb->count);
if (ret == 0) {
rb->count = gspca_dev->nframes;
gspca_dev->capt_file = file;
if (streaming)
ret = gspca_init_transfer(gspca_dev);
}
@ -1630,11 +1611,15 @@ static int vidioc_streamoff(struct file *file, void *priv,
if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
if (!gspca_dev->streaming)
return 0;
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
if (!gspca_dev->streaming) {
ret = 0;
goto out;
}
/* check the capture file */
if (gspca_dev->capt_file != file) {
ret = -EBUSY;
@ -1649,6 +1634,8 @@ static int vidioc_streamoff(struct file *file, void *priv,
gspca_dev->usb_err = 0;
gspca_stream_off(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
/* In case another thread is waiting in dqbuf */
wake_up_interruptible(&gspca_dev->wq);
/* empty the transfer queues */
atomic_set(&gspca_dev->fr_q, 0);
@ -1827,43 +1814,29 @@ out:
return ret;
}
/*
* wait for a video frame
*
* If a frame is ready, its index is returned.
*/
static int frame_wait(struct gspca_dev *gspca_dev,
int nonblock_ing)
static int frame_ready_nolock(struct gspca_dev *gspca_dev, struct file *file,
enum v4l2_memory memory)
{
int i, ret;
if (!gspca_dev->present)
return -ENODEV;
if (gspca_dev->capt_file != file || gspca_dev->memory != memory ||
!gspca_dev->streaming)
return -EINVAL;
/* check if a frame is ready */
i = gspca_dev->fr_o;
if (i == atomic_read(&gspca_dev->fr_i)) {
if (nonblock_ing)
return -EAGAIN;
return gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i);
}
/* wait till a frame is ready */
ret = wait_event_interruptible_timeout(gspca_dev->wq,
i != atomic_read(&gspca_dev->fr_i) ||
!gspca_dev->streaming || !gspca_dev->present,
msecs_to_jiffies(3000));
if (ret < 0)
return ret;
if (ret == 0 || !gspca_dev->streaming || !gspca_dev->present)
return -EIO;
}
static int frame_ready(struct gspca_dev *gspca_dev, struct file *file,
enum v4l2_memory memory)
{
int ret;
gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES;
if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->usb_err = 0;
if (gspca_dev->present)
gspca_dev->sd_desc->dq_callback(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
return gspca_dev->fr_queue[i];
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
ret = frame_ready_nolock(gspca_dev, file, memory);
mutex_unlock(&gspca_dev->queue_lock);
return ret;
}
/*
@ -1876,33 +1849,57 @@ static int vidioc_dqbuf(struct file *file, void *priv,
{
struct gspca_dev *gspca_dev = priv;
struct gspca_frame *frame;
int i, ret;
int i, j, ret;
PDEBUG(D_FRAM, "dqbuf");
if (v4l2_buf->memory != gspca_dev->memory)
return -EINVAL;
if (!gspca_dev->present)
return -ENODEV;
/* if not streaming, be sure the application will not loop forever */
if (!(file->f_flags & O_NONBLOCK)
&& !gspca_dev->streaming && gspca_dev->users == 1)
return -EINVAL;
/* only the capturing file may dequeue */
if (gspca_dev->capt_file != file)
return -EINVAL;
/* only one dequeue / read at a time */
if (mutex_lock_interruptible(&gspca_dev->read_lock))
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
ret = frame_wait(gspca_dev, file->f_flags & O_NONBLOCK);
if (ret < 0)
goto out;
i = ret; /* frame index */
frame = &gspca_dev->frame[i];
for (;;) {
ret = frame_ready_nolock(gspca_dev, file, v4l2_buf->memory);
if (ret < 0)
goto out;
if (ret > 0)
break;
mutex_unlock(&gspca_dev->queue_lock);
if (file->f_flags & O_NONBLOCK)
return -EAGAIN;
/* wait till a frame is ready */
ret = wait_event_interruptible_timeout(gspca_dev->wq,
frame_ready(gspca_dev, file, v4l2_buf->memory),
msecs_to_jiffies(3000));
if (ret < 0)
return ret;
if (ret == 0)
return -EIO;
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
}
i = gspca_dev->fr_o;
j = gspca_dev->fr_queue[i];
frame = &gspca_dev->frame[j];
gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES;
if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->usb_err = 0;
if (gspca_dev->present)
gspca_dev->sd_desc->dq_callback(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
PDEBUG(D_FRAM, "dqbuf %d", j);
ret = 0;
if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
frame->data,
@ -1910,15 +1907,10 @@ static int vidioc_dqbuf(struct file *file, void *priv,
PDEBUG(D_ERR|D_STREAM,
"dqbuf cp to user failed");
ret = -EFAULT;
goto out;
}
}
frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
PDEBUG(D_FRAM, "dqbuf %d", i);
ret = 0;
out:
mutex_unlock(&gspca_dev->read_lock);
mutex_unlock(&gspca_dev->queue_lock);
return ret;
}
@ -2033,9 +2025,7 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
poll_wait(file, &gspca_dev->wq, wait);
/* if reqbufs is not done, the user would use read() */
if (gspca_dev->nframes == 0) {
if (gspca_dev->memory != GSPCA_MEMORY_NO)
return POLLERR; /* not the 1st time */
if (gspca_dev->memory == GSPCA_MEMORY_NO) {
ret = read_alloc(gspca_dev, file);
if (ret != 0)
return POLLERR;
@ -2067,18 +2057,10 @@ static ssize_t dev_read(struct file *file, char __user *data,
PDEBUG(D_FRAM, "read (%zd)", count);
if (!gspca_dev->present)
return -ENODEV;
switch (gspca_dev->memory) {
case GSPCA_MEMORY_NO: /* first time */
if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */
ret = read_alloc(gspca_dev, file);
if (ret != 0)
return ret;
break;
case GSPCA_MEMORY_READ:
if (gspca_dev->capt_file == file)
break;
/* fall thru */
default:
return -EINVAL;
}
/* get a frame */
@ -2266,7 +2248,6 @@ int gspca_dev_probe2(struct usb_interface *intf,
goto out;
mutex_init(&gspca_dev->usb_lock);
mutex_init(&gspca_dev->read_lock);
mutex_init(&gspca_dev->queue_lock);
init_waitqueue_head(&gspca_dev->wq);
@ -2341,12 +2322,11 @@ void gspca_disconnect(struct usb_interface *intf)
PDEBUG(D_PROBE, "%s disconnect",
video_device_node_name(&gspca_dev->vdev));
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->present = 0;
if (gspca_dev->streaming) {
destroy_urbs(gspca_dev);
wake_up_interruptible(&gspca_dev->wq);
}
gspca_dev->present = 0;
wake_up_interruptible(&gspca_dev->wq);
destroy_urbs(gspca_dev);
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
gspca_input_destroy_urb(gspca_dev);

View file

@ -205,14 +205,12 @@ struct gspca_dev {
wait_queue_head_t wq; /* wait queue */
struct mutex usb_lock; /* usb exchange protection */
struct mutex read_lock; /* read protection */
struct mutex queue_lock; /* ISOC queue protection */
int usb_err; /* USB error - protected by usb_lock */
u16 pkt_size; /* ISOC packet size */
#ifdef CONFIG_PM
char frozen; /* suspend - resume */
#endif
char users; /* number of opens */
char present; /* device connected */
char nbufread; /* number of buffers for read() */
char memory; /* memory type (V4L2_MEMORY_xxx) */

View file

@ -314,7 +314,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
/* Table of supported USB devices */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0979, 0x0280)},
{}
};

View file

@ -141,9 +141,9 @@ static void jpeg_define(u8 *jpeg_hdr,
memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
#ifndef CONEX_CAM
jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height & 0xff;
jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height;
jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width & 0xff;
jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width;
jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
#endif
}

View file

@ -607,7 +607,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x04c8, 0x0720)}, /* Intel YC 76 */
{}
};

View file

@ -28,7 +28,7 @@ int force_sensor;
static int dump_bridge;
int dump_sensor;
static const __devinitdata struct usb_device_id m5602_table[] = {
static const struct usb_device_id m5602_table[] = {
{USB_DEVICE(0x0402, 0x5602)},
{}
};

View file

@ -490,7 +490,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x050f)},
{}
};

View file

@ -1229,7 +1229,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */
{USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
{USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */

View file

@ -488,7 +488,6 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
#define R511_SNAP_PXDIV 0x1c
#define R511_SNAP_LNDIV 0x1d
#define R511_SNAP_UV_EN 0x1e
#define R511_SNAP_UV_EN 0x1e
#define R511_SNAP_OPTS 0x1f
#define R511_DRAM_FLOW_CTL 0x20
@ -1847,8 +1846,7 @@ static const struct ov_i2c_regvals norm_7670[] = {
{ 0x6c, 0x0a },
{ 0x6d, 0x55 },
{ 0x6e, 0x11 },
{ 0x6f, 0x9f },
/* "9e for advance AWB" */
{ 0x6f, 0x9f }, /* "9e for advance AWB" */
{ 0x6a, 0x40 },
{ OV7670_R01_BLUE, 0x40 },
{ OV7670_R02_RED, 0x60 },
@ -3054,7 +3052,7 @@ static void ov519_configure(struct sd *sd)
{
static const struct ov_regvals init_519[] = {
{ 0x5a, 0x6d }, /* EnableSystem */
{ 0x53, 0x9b },
{ 0x53, 0x9b }, /* don't enable the microcontroller */
{ OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
{ 0x5d, 0x03 },
{ 0x49, 0x01 },
@ -4747,7 +4745,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
{USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },

View file

@ -479,15 +479,20 @@ static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
struct usb_device *udev = gspca_dev->dev;
int ret;
PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
if (gspca_dev->usb_err < 0)
return;
PDEBUG(D_USBO, "SET 01 0000 %04x %02x", reg, val);
gspca_dev->usb_buf[0] = val;
ret = usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
0x01,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
if (ret < 0)
if (ret < 0) {
err("write failed %d", ret);
gspca_dev->usb_err = ret;
}
}
static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
@ -495,14 +500,18 @@ static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
struct usb_device *udev = gspca_dev->dev;
int ret;
if (gspca_dev->usb_err < 0)
return 0;
ret = usb_control_msg(udev,
usb_rcvctrlpipe(udev, 0),
0x01,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
if (ret < 0)
PDEBUG(D_USBI, "GET 01 0000 %04x %02x", reg, gspca_dev->usb_buf[0]);
if (ret < 0) {
err("read failed %d", ret);
gspca_dev->usb_err = ret;
}
return gspca_dev->usb_buf[0];
}
@ -558,13 +567,15 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
{
PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val);
PDEBUG(D_USBO, "sccb write: %02x %02x", reg, val);
ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
if (!sccb_check_status(gspca_dev))
if (!sccb_check_status(gspca_dev)) {
err("sccb_reg_write failed");
gspca_dev->usb_err = -EIO;
}
}
static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
@ -885,7 +896,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
ov534_set_led(gspca_dev, 0);
set_frame_rate(gspca_dev);
return 0;
return gspca_dev->usb_err;
}
static int sd_start(struct gspca_dev *gspca_dev)
@ -920,7 +931,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
ov534_set_led(gspca_dev, 1);
ov534_reg_write(gspca_dev, 0xe0, 0x00);
return 0;
return gspca_dev->usb_err;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
@ -1289,7 +1300,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x1415, 0x2000)},
{}
};

View file

@ -1429,7 +1429,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x06f8, 0x3003)},
{}
};

View file

@ -530,7 +530,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x4028)},
{USB_DEVICE(0x093a, 0x2460)},
{USB_DEVICE(0x093a, 0x2461)},

View file

@ -1184,7 +1184,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const struct usb_device_id device_table[] __devinitconst = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x06f8, 0x3009)},
{USB_DEVICE(0x093a, 0x2620)},
{USB_DEVICE(0x093a, 0x2621)},
@ -1201,7 +1201,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
static int __devinit sd_probe(struct usb_interface *intf,
static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

View file

@ -837,7 +837,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const struct usb_device_id device_table[] __devinitconst = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2600)},
{USB_DEVICE(0x093a, 0x2601)},
{USB_DEVICE(0x093a, 0x2603)},
@ -849,7 +849,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
static int __devinit sd_probe(struct usb_interface *intf,
static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

View file

@ -703,7 +703,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */
/* The Genius Smart is untested. I can't find an owner ! */
/* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */

View file

@ -2470,7 +2470,7 @@ static const struct sd_desc sd_desc = {
| (SENSOR_ ## sensor << 8) \
| (i2c_addr)
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
{USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
{USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},

View file

@ -23,8 +23,15 @@
/* Some documentation on known sonixb registers:
Reg Use
sn9c101 / sn9c102:
0x10 high nibble red gain low nibble blue gain
0x11 low nibble green gain
sn9c103:
0x05 red gain 0-127
0x06 blue gain 0-127
0x07 green gain 0-127
all:
0x08-0x0f i2c / 3wire registers
0x12 hstart
0x13 vstart
0x15 hsize (hsize = register-value * 16)
@ -88,12 +95,9 @@ struct sd {
typedef const __u8 sensor_init_t[8];
struct sensor_data {
const __u8 *bridge_init[2];
int bridge_init_size[2];
const __u8 *bridge_init;
sensor_init_t *sensor_init;
int sensor_init_size;
sensor_init_t *sensor_bridge_init[2];
int sensor_bridge_init_size[2];
int flags;
unsigned ctrl_dis;
__u8 sensor_addr;
@ -114,7 +118,6 @@ struct sensor_data {
#define NO_FREQ (1 << FREQ_IDX)
#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
#define COMP2 0x8f
#define COMP 0xc7 /* 0x87 //0x07 */
#define COMP1 0xc9 /* 0x89 //0x09 */
@ -123,15 +126,11 @@ struct sensor_data {
#define SYS_CLK 0x04
#define SENS(bridge_1, bridge_3, sensor, sensor_1, \
sensor_3, _flags, _ctrl_dis, _sensor_addr) \
#define SENS(bridge, sensor, _flags, _ctrl_dis, _sensor_addr) \
{ \
.bridge_init = { bridge_1, bridge_3 }, \
.bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
.bridge_init = bridge, \
.sensor_init = sensor, \
.sensor_init_size = sizeof(sensor), \
.sensor_bridge_init = { sensor_1, sensor_3,}, \
.sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
.flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
}
@ -311,7 +310,6 @@ static const __u8 initHv7131d[] = {
0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
0x28, 0x1e, 0x60, 0x8e, 0x42,
0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
};
static const __u8 hv7131d_sensor_init[][8] = {
{0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
@ -326,7 +324,6 @@ static const __u8 initHv7131r[] = {
0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
0x28, 0x1e, 0x60, 0x8a, 0x20,
0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
};
static const __u8 hv7131r_sensor_init[][8] = {
{0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
@ -339,7 +336,7 @@ static const __u8 initOv6650[] = {
0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
0x10,
};
static const __u8 ov6650_sensor_init[][8] = {
/* Bright, contrast, etc are set through SCBB interface.
@ -378,24 +375,13 @@ static const __u8 initOv7630[] = {
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
0x28, 0x1e, /* H & V sizes r15 .. r16 */
0x68, COMP2, MCK_INIT1, /* r17 .. r19 */
0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
};
static const __u8 initOv7630_3[] = {
0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
0x28, 0x1e, /* H & V sizes r15 .. r16 */
0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
};
static const __u8 ov7630_sensor_init[][8] = {
{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
{0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
{0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
{0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
{0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
{0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
@ -413,16 +399,11 @@ static const __u8 ov7630_sensor_init[][8] = {
{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
};
static const __u8 ov7630_sensor_init_3[][8] = {
{0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
};
static const __u8 initPas106[] = {
0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
0x16, 0x12, 0x24, COMP1, MCK_INIT1,
0x18, 0x10, 0x02, 0x02, 0x09, 0x07
};
/* compression 0x86 mckinit1 0x2b */
@ -496,7 +477,6 @@ static const __u8 initPas202[] = {
0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
0x28, 0x1e, 0x20, 0x89, 0x20,
0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
};
/* "Known" PAS202BCB registers:
@ -537,7 +517,6 @@ static const __u8 initTas5110c[] = {
0x00, 0x00,
0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
0x16, 0x12, 0x60, 0x86, 0x2b,
0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
};
/* Same as above, except a different hstart */
static const __u8 initTas5110d[] = {
@ -545,12 +524,19 @@ static const __u8 initTas5110d[] = {
0x00, 0x00,
0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
0x16, 0x12, 0x60, 0x86, 0x2b,
0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
};
static const __u8 tas5110_sensor_init[][8] = {
/* tas5110c is 3 wire, tas5110d is 2 wire (regular i2c) */
static const __u8 tas5110c_sensor_init[][8] = {
{0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
{0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
{0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
};
/* Known TAS5110D registers
* reg02: gain, bit order reversed!! 0 == max gain, 255 == min gain
* reg03: bit3: vflip, bit4: ~hflip, bit7: ~gainboost (~ == inverted)
* Note: writing reg03 seems to only work when written together with 02
*/
static const __u8 tas5110d_sensor_init[][8] = {
{0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, /* reset */
};
static const __u8 initTas5130[] = {
@ -558,7 +544,6 @@ static const __u8 initTas5130[] = {
0x00, 0x00,
0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
0x28, 0x1e, 0x60, COMP, MCK_INIT,
0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
};
static const __u8 tas5130_sensor_init[][8] = {
/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
@ -569,21 +554,18 @@ static const __u8 tas5130_sensor_init[][8] = {
};
static struct sensor_data sensor_data[] = {
SENS(initHv7131d, NULL, hv7131d_sensor_init, NULL, NULL, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
SENS(initHv7131r, NULL, hv7131r_sensor_init, NULL, NULL, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
F_GAIN, 0, 0x21),
SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ,
0),
SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN,
NO_FREQ, 0),
SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL,
F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL,
F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
0),
SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60),
SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21),
SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0),
SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0),
SENS(initTas5110c, tas5110c_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
NO_BRIGHTNESS|NO_FREQ, 0),
SENS(initTas5110d, tas5110d_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
NO_BRIGHTNESS|NO_FREQ, 0),
SENS(initTas5130, tas5130_sensor_init, F_GAIN,
NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
};
/* get one byte in gspca_dev->usb_buf */
@ -655,7 +637,6 @@ static void i2c_w_vector(struct gspca_dev *gspca_dev,
static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
__u8 value;
switch (sd->sensor) {
case SENSOR_OV6650:
@ -697,17 +678,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
goto err;
break;
}
case SENSOR_TAS5130CXX: {
__u8 i2c[] =
{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
value = 0xff - sd->brightness;
i2c[4] = value;
PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
if (i2c_w(gspca_dev, i2c) < 0)
goto err;
break;
}
}
return;
err:
@ -733,7 +703,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
break;
}
case SENSOR_TAS5110C:
case SENSOR_TAS5110D: {
case SENSOR_TAS5130CXX: {
__u8 i2c[] =
{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
@ -742,6 +712,23 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
goto err;
break;
}
case SENSOR_TAS5110D: {
__u8 i2c[] = {
0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 };
gain = 255 - gain;
/* The bits in the register are the wrong way around!! */
i2c[3] |= (gain & 0x80) >> 7;
i2c[3] |= (gain & 0x40) >> 5;
i2c[3] |= (gain & 0x20) >> 3;
i2c[3] |= (gain & 0x10) >> 1;
i2c[3] |= (gain & 0x08) << 1;
i2c[3] |= (gain & 0x04) << 3;
i2c[3] |= (gain & 0x02) << 5;
i2c[3] |= (gain & 0x01) << 7;
if (i2c_w(gspca_dev, i2c) < 0)
goto err;
break;
}
case SENSOR_OV6650:
gain >>= 1;
@ -796,7 +783,7 @@ static void setgain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
__u8 gain;
__u8 buf[2] = { 0, 0 };
__u8 buf[3] = { 0, 0, 0 };
if (sensor_data[sd->sensor].flags & F_GAIN) {
/* Use the sensor gain to do the actual gain */
@ -804,13 +791,18 @@ static void setgain(struct gspca_dev *gspca_dev)
return;
}
gain = sd->gain >> 4;
/* red and blue gain */
buf[0] = gain << 4 | gain;
/* green gain */
buf[1] = gain;
reg_w(gspca_dev, 0x10, buf, 2);
if (sd->bridge == BRIDGE_103) {
gain = sd->gain >> 1;
buf[0] = gain; /* Red */
buf[1] = gain; /* Green */
buf[2] = gain; /* Blue */
reg_w(gspca_dev, 0x05, buf, 3);
} else {
gain = sd->gain >> 4;
buf[0] = gain << 4 | gain; /* Red and blue */
buf[1] = gain; /* Green */
reg_w(gspca_dev, 0x10, buf, 2);
}
}
static void setexposure(struct gspca_dev *gspca_dev)
@ -1049,7 +1041,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
desired_avg_lum = 5000;
} else {
deadzone = 1500;
desired_avg_lum = 18000;
desired_avg_lum = 13000;
}
if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
@ -1127,53 +1119,91 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam = &gspca_dev->cam;
int mode, l;
const __u8 *sn9c10x;
__u8 reg12_19[8];
int i, mode;
__u8 regs[0x31];
mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
/* Special cases where reg 17 and or 19 value depends on mode */
/* Copy registers 0x01 - 0x19 from the template */
memcpy(&regs[0x01], sensor_data[sd->sensor].bridge_init, 0x19);
/* Set the mode */
regs[0x18] |= mode << 4;
/* Set bridge gain to 1.0 */
if (sd->bridge == BRIDGE_103) {
regs[0x05] = 0x20; /* Red */
regs[0x06] = 0x20; /* Green */
regs[0x07] = 0x20; /* Blue */
} else {
regs[0x10] = 0x00; /* Red and blue */
regs[0x11] = 0x00; /* Green */
}
/* Setup pixel numbers and auto exposure window */
if (sensor_data[sd->sensor].flags & F_SIF) {
regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */
regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */
regs[0x1c] = 0x02; /* AE H-start 64 */
regs[0x1d] = 0x02; /* AE V-start 64 */
regs[0x1e] = 0x09; /* AE H-end 288 */
regs[0x1f] = 0x07; /* AE V-end 224 */
} else {
regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */
regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */
regs[0x1c] = 0x05; /* AE H-start 160 */
regs[0x1d] = 0x03; /* AE V-start 96 */
regs[0x1e] = 0x0f; /* AE H-end 480 */
regs[0x1f] = 0x0c; /* AE V-end 384 */
}
/* Setup the gamma table (only used with the sn9c103 bridge) */
for (i = 0; i < 16; i++)
regs[0x20 + i] = i * 16;
regs[0x20 + i] = 255;
/* Special cases where some regs depend on mode or bridge */
switch (sd->sensor) {
case SENSOR_TAS5130CXX:
/* probably not mode specific at all most likely the upper
/* FIXME / TESTME
probably not mode specific at all most likely the upper
nibble of 0x19 is exposure (clock divider) just as with
the tas5110, we need someone to test this. */
reg12_19[7] = mode ? 0x23 : 0x43;
regs[0x19] = mode ? 0x23 : 0x43;
break;
case SENSOR_OV7630:
/* FIXME / TESTME for some reason with the 101/102 bridge the
clock is set to 12 Mhz (reg1 == 0x04), rather then 24.
Also the hstart needs to go from 1 to 2 when using a 103,
which is likely related. This does not seem right. */
if (sd->bridge == BRIDGE_103) {
regs[0x01] = 0x44; /* Select 24 Mhz clock */
regs[0x12] = 0x02; /* Set hstart to 2 */
}
}
/* Disable compression when the raw bayer format has been selected */
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
reg12_19[6] &= ~0x80;
regs[0x18] &= ~0x80;
/* Vga mode emulation on SIF sensor? */
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
reg12_19[0] += 16; /* 0x12: hstart adjust */
reg12_19[1] += 24; /* 0x13: vstart adjust */
reg12_19[3] = 320 / 16; /* 0x15: hsize */
reg12_19[4] = 240 / 16; /* 0x16: vsize */
regs[0x12] += 16; /* hstart adjust */
regs[0x13] += 24; /* vstart adjust */
regs[0x15] = 320 / 16; /* hsize */
regs[0x16] = 240 / 16; /* vsize */
}
/* reg 0x01 bit 2 video transfert on */
reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
reg_w(gspca_dev, 0x01, &regs[0x01], 1);
/* reg 0x17 SensorClk enable inv Clk 0x60 */
reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
reg_w(gspca_dev, 0x17, &regs[0x17], 1);
/* Set the registers from the template */
reg_w(gspca_dev, 0x01, sn9c10x, l);
reg_w(gspca_dev, 0x01, &regs[0x01],
(sd->bridge == BRIDGE_103) ? 0x30 : 0x1f);
/* Init the sensor */
i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
sensor_data[sd->sensor].sensor_init_size);
if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
i2c_w_vector(gspca_dev,
sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
sensor_data[sd->sensor].sensor_bridge_init_size[
sd->bridge]);
/* Mode specific sensor setup */
/* Mode / bridge specific sensor setup */
switch (sd->sensor) {
case SENSOR_PAS202: {
const __u8 i2cpclockdiv[] =
@ -1181,27 +1211,37 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
if (mode)
i2c_w(gspca_dev, i2cpclockdiv);
break;
}
case SENSOR_OV7630:
/* FIXME / TESTME We should be able to handle this identical
for the 101/102 and the 103 case */
if (sd->bridge == BRIDGE_103) {
const __u8 i2c[] = { 0xa0, 0x21, 0x13,
0x80, 0x00, 0x00, 0x00, 0x10 };
i2c_w(gspca_dev, i2c);
}
break;
}
/* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
reg_w(gspca_dev, 0x15, &regs[0x15], 2);
/* compression register */
reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
reg_w(gspca_dev, 0x18, &regs[0x18], 1);
/* H_start */
reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
reg_w(gspca_dev, 0x12, &regs[0x12], 1);
/* V_START */
reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
reg_w(gspca_dev, 0x13, &regs[0x13], 1);
/* reset 0x17 SensorClk enable inv Clk 0x60 */
/*fixme: ov7630 [17]=68 8f (+20 if 102)*/
reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
reg_w(gspca_dev, 0x17, &regs[0x17], 1);
/*MCKSIZE ->3 */ /*fixme: not ov7630*/
reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
reg_w(gspca_dev, 0x19, &regs[0x19], 1);
/* AE_STRX AE_STRY AE_ENDX AE_ENDY */
reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
reg_w(gspca_dev, 0x1c, &regs[0x1c], 4);
/* Enable video transfert */
reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
reg_w(gspca_dev, 0x01, &regs[0x01], 1);
/* Compression */
reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
reg_w(gspca_dev, 0x18, &regs[0x18], 2);
msleep(20);
sd->reg11 = -1;
@ -1525,15 +1565,15 @@ static const struct sd_desc sd_desc = {
.driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
static const struct usb_device_id device_table[] __devinitconst = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
{USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
{USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
{USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
{USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
{USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
#endif
@ -1544,18 +1584,22 @@ static const struct usb_device_id device_table[] __devinitconst = {
{USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
{USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
/* {USB_DEVICE(0x0c45, 0x602b), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
/* {USB_DEVICE(0x0c45, 0x6030), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
/* {USB_DEVICE(0x0c45, 0x6082), SB(MI03XX, 103)}, */ /* MI0343 MI0360 */
{USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)},
{USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)},
/* {USB_DEVICE(0x0c45, 0x608e), SB(CISVF10, 103)}, */
{USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)},
{USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)},
{USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
#endif
{USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
static int __devinit sd_probe(struct usb_interface *intf,
static int sd_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),

View file

@ -25,12 +25,12 @@
#include "gspca.h"
#include "jpeg.h"
#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
MODULE_LICENSE("GPL");
static int starcam;
/* controls */
enum e_ctrl {
BRIGHTNESS,
@ -43,7 +43,7 @@ enum e_ctrl {
HFLIP,
VFLIP,
SHARPNESS,
INFRARED,
ILLUM,
FREQ,
NCTRLS /* number of controls */
};
@ -100,7 +100,8 @@ enum sensors {
};
/* device flags */
#define PDN_INV 1 /* inverse pin S_PWR_DN / sn_xxx tables */
#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */
#define F_ILLUM 0x02 /* presence of illuminator */
/* sn9c1xx definitions */
/* register 0x01 */
@ -124,7 +125,7 @@ static void setgamma(struct gspca_dev *gspca_dev);
static void setautogain(struct gspca_dev *gspca_dev);
static void sethvflip(struct gspca_dev *gspca_dev);
static void setsharpness(struct gspca_dev *gspca_dev);
static void setinfrared(struct gspca_dev *gspca_dev);
static void setillum(struct gspca_dev *gspca_dev);
static void setfreq(struct gspca_dev *gspca_dev);
static const struct ctrl sd_ctrls[NCTRLS] = {
@ -251,18 +252,17 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
},
.set_control = setsharpness
},
/* mt9v111 only */
[INFRARED] = {
[ILLUM] = {
{
.id = V4L2_CID_INFRARED,
.id = V4L2_CID_ILLUMINATORS_1,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Infrared",
.name = "Illuminator / infrared",
.minimum = 0,
.maximum = 1,
.step = 1,
.default_value = 0,
},
.set_control = setinfrared
.set_control = setillum
},
/* ov7630/ov7648/ov7660 only */
[FREQ] = {
@ -282,32 +282,26 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
/* table of the disabled controls */
static const __u32 ctrl_dis[] = {
[SENSOR_ADCM1700] = (1 << AUTOGAIN) |
(1 << INFRARED) |
(1 << HFLIP) |
(1 << VFLIP) |
(1 << FREQ),
[SENSOR_GC0307] = (1 << INFRARED) |
(1 << HFLIP) |
[SENSOR_GC0307] = (1 << HFLIP) |
(1 << VFLIP) |
(1 << FREQ),
[SENSOR_HV7131R] = (1 << INFRARED) |
(1 << HFLIP) |
[SENSOR_HV7131R] = (1 << HFLIP) |
(1 << FREQ),
[SENSOR_MI0360] = (1 << INFRARED) |
(1 << HFLIP) |
[SENSOR_MI0360] = (1 << HFLIP) |
(1 << VFLIP) |
(1 << FREQ),
[SENSOR_MI0360B] = (1 << INFRARED) |
(1 << HFLIP) |
[SENSOR_MI0360B] = (1 << HFLIP) |
(1 << VFLIP) |
(1 << FREQ),
[SENSOR_MO4000] = (1 << INFRARED) |
(1 << HFLIP) |
[SENSOR_MO4000] = (1 << HFLIP) |
(1 << VFLIP) |
(1 << FREQ),
@ -315,40 +309,32 @@ static const __u32 ctrl_dis[] = {
(1 << VFLIP) |
(1 << FREQ),
[SENSOR_OM6802] = (1 << INFRARED) |
(1 << HFLIP) |
[SENSOR_OM6802] = (1 << HFLIP) |
(1 << VFLIP) |
(1 << FREQ),
[SENSOR_OV7630] = (1 << INFRARED) |
(1 << HFLIP),
[SENSOR_OV7630] = (1 << HFLIP),
[SENSOR_OV7648] = (1 << INFRARED) |
(1 << HFLIP),
[SENSOR_OV7648] = (1 << HFLIP),
[SENSOR_OV7660] = (1 << AUTOGAIN) |
(1 << INFRARED) |
(1 << HFLIP) |
(1 << VFLIP),
[SENSOR_PO1030] = (1 << AUTOGAIN) |
(1 << INFRARED) |
(1 << HFLIP) |
(1 << VFLIP) |
(1 << FREQ),
[SENSOR_PO2030N] = (1 << AUTOGAIN) |
(1 << INFRARED) |
(1 << FREQ),
[SENSOR_SOI768] = (1 << AUTOGAIN) |
(1 << INFRARED) |
(1 << HFLIP) |
(1 << VFLIP) |
(1 << FREQ),
[SENSOR_SP80708] = (1 << AUTOGAIN) |
(1 << INFRARED) |
(1 << HFLIP) |
(1 << VFLIP) |
(1 << FREQ),
@ -1822,44 +1808,46 @@ static int sd_init(struct gspca_dev *gspca_dev)
PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
switch (sd->bridge) {
case BRIDGE_SN9C102P:
if (regF1 != 0x11)
return -ENODEV;
reg_w1(gspca_dev, 0x02, regGpio[1]);
break;
case BRIDGE_SN9C105:
if (regF1 != 0x11)
return -ENODEV;
if (sd->sensor == SENSOR_MI0360)
mi0360_probe(gspca_dev);
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
case BRIDGE_SN9C120:
if (regF1 != 0x12)
return -ENODEV;
switch (sd->sensor) {
case SENSOR_MI0360:
mi0360_probe(gspca_dev);
break;
case SENSOR_OV7630:
ov7630_probe(gspca_dev);
break;
case SENSOR_OV7648:
ov7648_probe(gspca_dev);
break;
case SENSOR_PO2030N:
po2030n_probe(gspca_dev);
break;
}
regGpio[1] = 0x70; /* no audio */
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
default:
/* case BRIDGE_SN9C110: */
/* case BRIDGE_SN9C325: */
/* case BRIDGE_SN9C120: */
if (regF1 != 0x12)
return -ENODEV;
}
switch (sd->sensor) {
case SENSOR_MI0360:
mi0360_probe(gspca_dev);
break;
case SENSOR_OV7630:
ov7630_probe(gspca_dev);
break;
case SENSOR_OV7648:
ov7648_probe(gspca_dev);
break;
case SENSOR_PO2030N:
po2030n_probe(gspca_dev);
break;
}
switch (sd->bridge) {
case BRIDGE_SN9C102P:
reg_w1(gspca_dev, 0x02, regGpio[1]);
break;
case BRIDGE_SN9C105:
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
case BRIDGE_SN9C110:
reg_w1(gspca_dev, 0x02, 0x62);
break;
case BRIDGE_SN9C120:
regGpio[1] = 0x70; /* no audio */
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
}
if (sd->sensor == SENSOR_OM6802)
@ -1874,6 +1862,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
sd->i2c_addr = sn9c1xx[9];
gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
if (!(sd->flags & F_ILLUM))
gspca_dev->ctrl_dis |= (1 << ILLUM);
return gspca_dev->usb_err;
}
@ -2197,16 +2187,28 @@ static void setsharpness(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
}
static void setinfrared(struct gspca_dev *gspca_dev)
static void setillum(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
if (gspca_dev->ctrl_dis & (1 << INFRARED))
if (gspca_dev->ctrl_dis & (1 << ILLUM))
return;
/*fixme: different sequence for StarCam Clip and StarCam 370i */
/* Clip */
i2c_w1(gspca_dev, 0x02, /* gpio */
sd->ctrls[INFRARED].val ? 0x66 : 0x64);
switch (sd->sensor) {
case SENSOR_ADCM1700:
reg_w1(gspca_dev, 0x02, /* gpio */
sd->ctrls[ILLUM].val ? 0x64 : 0x60);
break;
case SENSOR_MT9V111:
if (starcam)
reg_w1(gspca_dev, 0x02,
sd->ctrls[ILLUM].val ?
0x55 : 0x54); /* 370i */
else
reg_w1(gspca_dev, 0x02,
sd->ctrls[ILLUM].val ?
0x66 : 0x64); /* Clip */
break;
}
}
static void setfreq(struct gspca_dev *gspca_dev)
@ -2344,7 +2346,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* sensor clock already enabled in sd_init */
/* reg_w1(gspca_dev, 0xf1, 0x00); */
reg01 = sn9c1xx[1];
if (sd->flags & PDN_INV)
if (sd->flags & F_PDN_INV)
reg01 ^= S_PDN_INV; /* power down inverted */
reg_w1(gspca_dev, 0x01, reg01);
@ -2907,13 +2909,11 @@ static const struct sd_desc sd_desc = {
.driver_info = (BRIDGE_ ## bridge << 16) \
| (SENSOR_ ## sensor << 8) \
| (flags)
static const __devinitdata struct usb_device_id device_table[] = {
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
#endif
{USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, PDN_INV)},
{USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)},
{USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)},
{USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)},
{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
@ -2925,7 +2925,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
{USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
{USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
{USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)},
/* or MT9V111 */
/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
@ -2936,10 +2936,8 @@ static const __devinitdata struct usb_device_id device_table[] = {
/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
{USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
{USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
#endif
{USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
{USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/
/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
@ -2962,16 +2960,15 @@ static const __devinitdata struct usb_device_id device_table[] = {
/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
{USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
{USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
#endif
{USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
{USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
{USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
/* or GC0305 / GC0307 */
{USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
{USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
{USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/
{USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)},
/* {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */ /*sn9c120b*/
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@ -3007,3 +3004,7 @@ static void __exit sd_mod_exit(void)
module_init(sd_mod_init);
module_exit(sd_mod_exit);
module_param(starcam, int, 0644);
MODULE_PARM_DESC(starcam,
"StarCam model. 0: Clip, 1: 370i");

View file

@ -555,7 +555,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x04fc, 0x1528)},
{}
};

View file

@ -1051,7 +1051,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},

View file

@ -2155,7 +2155,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325},
{USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera},
{USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite},

View file

@ -786,7 +786,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra},
{USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro},
/*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */

View file

@ -1509,7 +1509,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
{USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
{USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},

View file

@ -1061,7 +1061,7 @@ static const struct sd_desc *sd_desc[2] = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},

View file

@ -396,7 +396,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
/* Table of supported USB devices */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x2770, 0x9120)},
{}
};

View file

@ -298,7 +298,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
/* Table of supported USB devices */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x2770, 0x905c)},
{USB_DEVICE(0x2770, 0x9050)},
{USB_DEVICE(0x2770, 0x9051)},

View file

@ -1163,7 +1163,7 @@ static const struct sd_desc sd_desc = {
#define ST(sensor, type) \
.driver_info = (SENSOR_ ## sensor << 8) \
| (type)
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)},
{USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)},
{USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)},

View file

@ -495,7 +495,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x05e1, 0x0893)},
{}
};

View file

@ -327,7 +327,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x0553, 0x0202)},
{USB_DEVICE(0x041e, 0x4007)},
{}

View file

@ -564,7 +564,7 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
/* QuickCam Express */
{USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 },
/* LEGO cam / QuickCam Web */

View file

@ -1162,7 +1162,7 @@ static const struct sd_desc sd_desc = {
#define BS(bridge, subtype) \
.driver_info = (BRIDGE_ ## bridge << 8) \
| (subtype)
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
{USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
{USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},

View file

@ -1416,7 +1416,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x17a1, 0x0128)},
{}
};

View file

@ -388,7 +388,7 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x046d, 0x0920)},
{USB_DEVICE(0x046d, 0x0921)},
{USB_DEVICE(0x0545, 0x808b)},

View file

@ -4192,7 +4192,7 @@ static const struct sd_desc sd_desc = {
#define BF(bridge, flags) \
.driver_info = (BRIDGE_ ## bridge << 8) \
| (flags)
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)},
{USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)},
{USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)},

View file

@ -3270,7 +3270,7 @@ static const struct sd_desc sd_desc_isoc_nego = {
};
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{ USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
{ USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
{ USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },

View file

@ -6909,7 +6909,7 @@ static const struct sd_desc sd_desc = {
#endif
};
static const __devinitdata struct usb_device_id device_table[] = {
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x041e)},
{USB_DEVICE(0x041e, 0x4017)},
{USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106},

View file

@ -1,6 +1,4 @@
hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o
hdpvr-$(CONFIG_I2C) += hdpvr-i2c.o
hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o hdpvr-i2c.o
obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o

View file

@ -378,19 +378,17 @@ static int hdpvr_probe(struct usb_interface *interface,
goto error;
}
#ifdef CONFIG_I2C
/* until i2c is working properly */
retval = 0; /* hdpvr_register_i2c_adapter(dev); */
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
retval = hdpvr_register_i2c_adapter(dev);
if (retval < 0) {
v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
goto error;
}
/* until i2c is working properly */
retval = 0; /* hdpvr_register_i2c_ir(dev); */
retval = hdpvr_register_i2c_ir(dev);
if (retval < 0)
v4l2_err(&dev->v4l2_dev, "registering i2c IR devices failed\n");
#endif /* CONFIG_I2C */
#endif
/* let the user know what node this device is now attached to */
v4l2_info(&dev->v4l2_dev, "device now attached to %s\n",

View file

@ -13,6 +13,8 @@
*
*/
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
#include <linux/i2c.h>
#include <linux/slab.h>
@ -28,106 +30,78 @@
#define Z8F0811_IR_TX_I2C_ADDR 0x70
#define Z8F0811_IR_RX_I2C_ADDR 0x71
static const u8 ir_i2c_addrs[] = {
Z8F0811_IR_TX_I2C_ADDR,
Z8F0811_IR_RX_I2C_ADDR,
static struct i2c_board_info hdpvr_i2c_board_info = {
I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
};
static const char * const ir_devicenames[] = {
"ir_tx_z8f0811_hdpvr",
"ir_rx_z8f0811_hdpvr",
};
static int hdpvr_new_i2c_ir(struct hdpvr_device *dev, struct i2c_adapter *adap,
const char *type, u8 addr)
{
struct i2c_board_info info;
struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, type, I2C_NAME_SIZE);
/* Our default information for ir-kbd-i2c.c to use */
switch (addr) {
case Z8F0811_IR_RX_I2C_ADDR:
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
init_data->type = RC_TYPE_RC5;
init_data->name = "HD PVR";
info.platform_data = init_data;
break;
}
return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
-1 : 0;
}
int hdpvr_register_i2c_ir(struct hdpvr_device *dev)
{
int i;
int ret = 0;
struct i2c_client *c;
struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
for (i = 0; i < ARRAY_SIZE(ir_i2c_addrs); i++)
ret += hdpvr_new_i2c_ir(dev, dev->i2c_adapter,
ir_devicenames[i], ir_i2c_addrs[i]);
/* Our default information for ir-kbd-i2c.c to use */
init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
init_data->type = RC_TYPE_RC5;
init_data->name = "HD PVR";
hdpvr_i2c_board_info.platform_data = init_data;
return ret;
c = i2c_new_device(&dev->i2c_adapter, &hdpvr_i2c_board_info);
return (c == NULL) ? -ENODEV : 0;
}
static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr,
char *data, int len)
static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
unsigned char addr, char *data, int len)
{
int ret;
char *buf = kmalloc(len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
if (len > sizeof(dev->i2c_buf))
return -EINVAL;
ret = usb_control_msg(dev->udev,
usb_rcvctrlpipe(dev->udev, 0),
REQTYPE_I2C_READ, CTRL_READ_REQUEST,
0x100|addr, 0, buf, len, 1000);
(bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
if (ret == len) {
memcpy(data, buf, len);
memcpy(data, &dev->i2c_buf, len);
ret = 0;
} else if (ret >= 0)
ret = -EIO;
kfree(buf);
return ret;
}
static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr,
char *data, int len)
static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus,
unsigned char addr, char *data, int len)
{
int ret;
char *buf = kmalloc(len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
memcpy(buf, data, len);
if (len > sizeof(dev->i2c_buf))
return -EINVAL;
memcpy(&dev->i2c_buf, data, len);
ret = usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, 0),
REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
0x100|addr, 0, buf, len, 1000);
(bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
if (ret < 0)
goto error;
return ret;
ret = usb_control_msg(dev->udev,
usb_rcvctrlpipe(dev->udev, 0),
REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
0, 0, buf, 2, 1000);
0, 0, &dev->i2c_buf, 2, 1000);
if (ret == 2)
if ((ret == 2) && (dev->i2c_buf[1] == (len - 1)))
ret = 0;
else if (ret >= 0)
ret = -EIO;
error:
kfree(buf);
return ret;
}
@ -146,10 +120,10 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
addr = msgs[i].addr << 1;
if (msgs[i].flags & I2C_M_RD)
retval = hdpvr_i2c_read(dev, addr, msgs[i].buf,
retval = hdpvr_i2c_read(dev, 1, addr, msgs[i].buf,
msgs[i].len);
else
retval = hdpvr_i2c_write(dev, addr, msgs[i].buf,
retval = hdpvr_i2c_write(dev, 1, addr, msgs[i].buf,
msgs[i].len);
}
@ -168,30 +142,47 @@ static struct i2c_algorithm hdpvr_algo = {
.functionality = hdpvr_functionality,
};
static struct i2c_adapter hdpvr_i2c_adapter_template = {
.name = "Hauppage HD PVR I2C",
.owner = THIS_MODULE,
.algo = &hdpvr_algo,
};
static int hdpvr_activate_ir(struct hdpvr_device *dev)
{
char buffer[8];
mutex_lock(&dev->i2c_mutex);
hdpvr_i2c_read(dev, 0, 0x54, buffer, 1);
buffer[0] = 0;
buffer[1] = 0x8;
hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
buffer[1] = 0x18;
hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
mutex_unlock(&dev->i2c_mutex);
return 0;
}
int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
{
struct i2c_adapter *i2c_adap;
int retval = -ENOMEM;
i2c_adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
if (i2c_adap == NULL)
goto error;
hdpvr_activate_ir(dev);
strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C",
sizeof(i2c_adap->name));
i2c_adap->algo = &hdpvr_algo;
i2c_adap->owner = THIS_MODULE;
i2c_adap->dev.parent = &dev->udev->dev;
memcpy(&dev->i2c_adapter, &hdpvr_i2c_adapter_template,
sizeof(struct i2c_adapter));
dev->i2c_adapter.dev.parent = &dev->udev->dev;
i2c_set_adapdata(i2c_adap, dev);
i2c_set_adapdata(&dev->i2c_adapter, dev);
retval = i2c_add_adapter(i2c_adap);
retval = i2c_add_adapter(&dev->i2c_adapter);
if (!retval)
dev->i2c_adapter = i2c_adap;
else
kfree(i2c_adap);
error:
return retval;
}
#endif

View file

@ -1220,12 +1220,9 @@ static void hdpvr_device_release(struct video_device *vdev)
v4l2_device_unregister(&dev->v4l2_dev);
/* deregister I2C adapter */
#ifdef CONFIG_I2C
#if defined(CONFIG_I2C) || (CONFIG_I2C_MODULE)
mutex_lock(&dev->i2c_mutex);
if (dev->i2c_adapter)
i2c_del_adapter(dev->i2c_adapter);
kfree(dev->i2c_adapter);
dev->i2c_adapter = NULL;
i2c_del_adapter(&dev->i2c_adapter);
mutex_unlock(&dev->i2c_mutex);
#endif /* CONFIG_I2C */

View file

@ -25,6 +25,7 @@
KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE)
#define HDPVR_MAX 8
#define HDPVR_I2C_MAX_SIZE 128
/* Define these values to match your devices */
#define HD_PVR_VENDOR_ID 0x2040
@ -106,9 +107,11 @@ struct hdpvr_device {
struct work_struct worker;
/* I2C adapter */
struct i2c_adapter *i2c_adapter;
struct i2c_adapter i2c_adapter;
/* I2C lock */
struct mutex i2c_mutex;
/* I2C message buffer space */
char i2c_buf[HDPVR_I2C_MAX_SIZE];
/* For passing data to ir-kbd-i2c */
struct IR_i2c_init_data ir_i2c_init_data;

View file

@ -244,15 +244,17 @@ static void ir_key_poll(struct IR_i2c *ir)
static u32 ir_key, ir_raw;
int rc;
dprintk(2,"ir_poll_key\n");
dprintk(3, "%s\n", __func__);
rc = ir->get_key(ir, &ir_key, &ir_raw);
if (rc < 0) {
dprintk(2,"error\n");
return;
}
if (rc)
if (rc) {
dprintk(1, "%s: keycode = 0x%04x\n", __func__, ir_key);
rc_keydown(ir->rc, ir_key, 0);
}
}
static void ir_work(struct work_struct *work)
@ -321,6 +323,12 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
rc_type = RC_TYPE_OTHER;
ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
break;
case 0x71:
name = "Hauppauge/Zilog Z8";
ir->get_key = get_key_haup_xvr;
rc_type = RC_TYPE_RC5;
ir_codes = hauppauge ? RC_MAP_HAUPPAUGE_NEW : RC_MAP_RC5_TV;
break;
}
/* Let the caller override settings */

View file

@ -300,10 +300,15 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
} else if (hw == IVTV_HW_CX25840) {
struct cx25840_platform_data pdata;
struct i2c_board_info cx25840_info = {
.type = "cx25840",
.addr = hw_addrs[idx],
.platform_data = &pdata,
};
pdata.pvr150_workaround = itv->pvr150_workaround;
sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev,
adap, type, 0, &pdata, hw_addrs[idx], NULL);
sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap,
&cx25840_info, NULL);
} else {
sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
adap, type, hw_addrs[idx], NULL);

Some files were not shown because too many files have changed in this diff Show more