forked from luck/tmp_suning_uos_patched
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:
commit
13a3cec844
|
@ -28,7 +28,7 @@
|
|||
<holder>Convergence GmbH</holder>
|
||||
</copyright>
|
||||
<copyright>
|
||||
<year>2009-2010</year>
|
||||
<year>2009-2011</year>
|
||||
<holder>Mauro Carvalho Chehab</holder>
|
||||
</copyright>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
=========================
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 = ® },
|
||||
{ .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 = ® },
|
||||
{ .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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) ?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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] = {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
|
|||
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);
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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), },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)},
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
|
|
|
@ -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 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
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);
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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)},
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)},
|
||||
|
|
|
@ -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(®s[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, ®s[0x01], 1);
|
||||
/* reg 0x17 SensorClk enable inv Clk 0x60 */
|
||||
reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
|
||||
reg_w(gspca_dev, 0x17, ®s[0x17], 1);
|
||||
/* Set the registers from the template */
|
||||
reg_w(gspca_dev, 0x01, sn9c10x, l);
|
||||
reg_w(gspca_dev, 0x01, ®s[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, ®12_19[3], 2);
|
||||
reg_w(gspca_dev, 0x15, ®s[0x15], 2);
|
||||
/* compression register */
|
||||
reg_w(gspca_dev, 0x18, ®12_19[6], 1);
|
||||
reg_w(gspca_dev, 0x18, ®s[0x18], 1);
|
||||
/* H_start */
|
||||
reg_w(gspca_dev, 0x12, ®12_19[0], 1);
|
||||
reg_w(gspca_dev, 0x12, ®s[0x12], 1);
|
||||
/* V_START */
|
||||
reg_w(gspca_dev, 0x13, ®12_19[1], 1);
|
||||
reg_w(gspca_dev, 0x13, ®s[0x13], 1);
|
||||
/* reset 0x17 SensorClk enable inv Clk 0x60 */
|
||||
/*fixme: ov7630 [17]=68 8f (+20 if 102)*/
|
||||
reg_w(gspca_dev, 0x17, ®12_19[5], 1);
|
||||
reg_w(gspca_dev, 0x17, ®s[0x17], 1);
|
||||
/*MCKSIZE ->3 */ /*fixme: not ov7630*/
|
||||
reg_w(gspca_dev, 0x19, ®12_19[7], 1);
|
||||
reg_w(gspca_dev, 0x19, ®s[0x19], 1);
|
||||
/* AE_STRX AE_STRY AE_ENDX AE_ENDY */
|
||||
reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
|
||||
reg_w(gspca_dev, 0x1c, ®s[0x1c], 4);
|
||||
/* Enable video transfert */
|
||||
reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
|
||||
reg_w(gspca_dev, 0x01, ®s[0x01], 1);
|
||||
/* Compression */
|
||||
reg_w(gspca_dev, 0x18, ®12_19[6], 2);
|
||||
reg_w(gspca_dev, 0x18, ®s[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),
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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)},
|
||||
|
|
|
@ -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)},
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)},
|
||||
|
|
|
@ -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)},
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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)},
|
||||
|
|
|
@ -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)},
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue
Block a user