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

* 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (87 commits)
  V4L/DVB: ivtv: Timing tweaks and code re-order to try and improve stability
  V4L/DVB: ivtv: Avoid accidental video standard change
  V4L/DVB: ivtvfb : Module load / unload fixes
  V4L/DVB: cx2341x: Report correct temporal setting for log-status
  V4L/DVB: cx18, cx23885, v4l2 doc, MAINTAINERS: Update Andy Walls' email address
  V4L/DVB: drivers/media: Eliminate a NULL pointer dereference
  V4L/DVB: dvb-core: Fix ULE decapsulation bug
  V4L/DVB: Bug fix: make IR work again for dm1105
  V4L/DVB: media/IR: nec-decoder needs to select BITREV
  V4L/DVB: video/saa7134: change dprintk() to i2cdprintk()
  V4L/DVB: video/saa7134: remove duplicate break
  V4L/DVB: IR/imon: add auto-config for 0xffdc rf device
  V4L/DVB: IR/imon: clean up usage of bools
  V4L/DVB: em28xx: remove unneeded null checks
  V4L/DVB: ngene: remove unused #include <linux/version.h>
  V4L/DVB: ak881x needs slab.h
  V4L/DVB: FusionHDTV: Use quick reads for I2C IR device probing
  V4L/DVB: Technotrend S2-3200 ships with a TT 1500 remote
  V4L/DVB: drivers/media: Use kzalloc
  V4L/DVB: m920x: Select simple tuner
  ...
This commit is contained in:
Linus Torvalds 2010-06-04 15:38:12 -07:00
Родитель d2dd328b7f 666092c679
Коммит e620d1e39a
139 изменённых файлов: 2131 добавлений и 1608 удалений

Просмотреть файл

@ -58,7 +58,7 @@ MPEG stream embedded, sliced VBI data format in this specification.
</contrib>
<affiliation>
<address>
<email>awalls@radix.net</email>
<email>awalls@md.metrocast.net</email>
</address>
</affiliation>
</author>

Просмотреть файл

@ -53,8 +53,10 @@ input</refpurpose>
automatically, similar to sensing the video standard. To do so, applications
call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a
&v4l2-dv-preset; type. Once the hardware detects a preset, that preset is
returned in the preset field of &v4l2-dv-preset;. When detection is not
possible or fails, the value V4L2_DV_INVALID is returned.</para>
returned in the preset field of &v4l2-dv-preset;. If the preset could not be
detected because there was no signal, or the signal was unreliable, or the
signal did not map to a supported preset, then the value V4L2_DV_INVALID is
returned.</para>
</refsect1>
<refsect1>

Просмотреть файл

@ -176,5 +176,6 @@
175 -> Leadtek Winfast DTV1000S [107d:6655]
176 -> Beholder BeholdTV 505 RDS [0000:5051]
177 -> Hawell HW-404M7
179 -> Beholder BeholdTV H7 [5ace:7190]
180 -> Beholder BeholdTV A7 [5ace:7090]
178 -> Beholder BeholdTV H7 [5ace:7190]
179 -> Beholder BeholdTV A7 [5ace:7090]
180 -> Avermedia M733A [1461:4155,1461:4255]

Просмотреть файл

@ -290,6 +290,7 @@ sonixb 0c45:602e Genius VideoCam Messenger
sonixj 0c45:6040 Speed NVC 350K
sonixj 0c45:607c Sonix sn9c102p Hv7131R
sonixj 0c45:60c0 Sangha Sn535
sonixj 0c45:60ce USB-PC-Camera-168 (TALK-5067)
sonixj 0c45:60ec SN9C105+MO4000
sonixj 0c45:60fb Surfer NoName
sonixj 0c45:60fc LG-LIC300

Просмотреть файл

@ -1731,7 +1731,7 @@ S: Maintained
F: sound/pci/cs5535audio/
CX18 VIDEO4LINUX DRIVER
M: Andy Walls <awalls@radix.net>
M: Andy Walls <awalls@md.metrocast.net>
L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
@ -3165,7 +3165,7 @@ F: Documentation/hwmon/it87
F: drivers/hwmon/it87.c
IVTV VIDEO4LINUX DRIVER
M: Andy Walls <awalls@radix.net>
M: Andy Walls <awalls@md.metrocast.net>
L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
L: linux-media@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git

Просмотреть файл

@ -13,6 +13,7 @@ source "drivers/media/IR/keymaps/Kconfig"
config IR_NEC_DECODER
tristate "Enable IR raw decoder for the NEC protocol"
depends on IR_CORE
select BITREVERSE
default y
---help---
@ -22,6 +23,7 @@ config IR_NEC_DECODER
config IR_RC5_DECODER
tristate "Enable IR raw decoder for the RC-5 protocol"
depends on IR_CORE
select BITREVERSE
default y
---help---

Просмотреть файл

@ -94,6 +94,7 @@ struct imon_context {
bool display_supported; /* not all controllers do */
bool display_isopen; /* display port has been opened */
bool rf_device; /* true if iMON 2.4G LT/DT RF device */
bool rf_isassociating; /* RF remote associating */
bool dev_present_intf0; /* USB device presence, interface 0 */
bool dev_present_intf1; /* USB device presence, interface 1 */
@ -385,7 +386,7 @@ static int display_open(struct inode *inode, struct file *file)
err("%s: display port is already open", __func__);
retval = -EBUSY;
} else {
ictx->display_isopen = 1;
ictx->display_isopen = true;
file->private_data = ictx;
dev_dbg(ictx->dev, "display port opened\n");
}
@ -422,7 +423,7 @@ static int display_close(struct inode *inode, struct file *file)
err("%s: display is not open", __func__);
retval = -EIO;
} else {
ictx->display_isopen = 0;
ictx->display_isopen = false;
dev_dbg(ictx->dev, "display port closed\n");
if (!ictx->dev_present_intf0) {
/*
@ -491,12 +492,12 @@ static int send_packet(struct imon_context *ictx)
}
init_completion(&ictx->tx.finished);
ictx->tx.busy = 1;
ictx->tx.busy = true;
smp_rmb(); /* ensure later readers know we're busy */
retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL);
if (retval) {
ictx->tx.busy = 0;
ictx->tx.busy = false;
smp_rmb(); /* ensure later readers know we're not busy */
err("%s: error submitting urb(%d)", __func__, retval);
} else {
@ -682,7 +683,7 @@ static ssize_t store_associate_remote(struct device *d,
return -ENODEV;
mutex_lock(&ictx->lock);
ictx->rf_isassociating = 1;
ictx->rf_isassociating = true;
send_associate_24g(ictx);
mutex_unlock(&ictx->lock);
@ -950,7 +951,7 @@ static void usb_tx_callback(struct urb *urb)
ictx->tx.status = urb->status;
/* notify waiters that write has finished */
ictx->tx.busy = 0;
ictx->tx.busy = false;
smp_rmb(); /* ensure later readers know we're not busy */
complete(&ictx->tx.finished);
}
@ -1215,7 +1216,7 @@ static bool imon_mouse_event(struct imon_context *ictx,
{
char rel_x = 0x00, rel_y = 0x00;
u8 right_shift = 1;
bool mouse_input = 1;
bool mouse_input = true;
int dir = 0;
/* newer iMON device PAD or mouse button */
@ -1246,7 +1247,7 @@ static bool imon_mouse_event(struct imon_context *ictx,
} else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) {
dir = -1;
} else
mouse_input = 0;
mouse_input = false;
if (mouse_input) {
dev_dbg(ictx->dev, "sending mouse data via input subsystem\n");
@ -1450,7 +1451,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
unsigned char *buf = urb->transfer_buffer;
struct device *dev = ictx->dev;
u32 kc;
bool norelease = 0;
bool norelease = false;
int i;
u64 temp_key;
u64 panel_key = 0;
@ -1465,7 +1466,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
idev = ictx->idev;
/* filter out junk data on the older 0xffdc imon devices */
if ((buf[0] == 0xff) && (buf[7] == 0xff))
if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff))
return;
/* Figure out what key was pressed */
@ -1517,7 +1518,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
!(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
len = 8;
imon_pad_to_keys(ictx, buf);
norelease = 1;
norelease = true;
}
if (debug) {
@ -1580,7 +1581,7 @@ not_input_data:
(buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */
dev_warn(dev, "%s: remote associated refid=%02X\n",
__func__, buf[1]);
ictx->rf_isassociating = 0;
ictx->rf_isassociating = false;
}
}
@ -1790,9 +1791,9 @@ static bool imon_find_endpoints(struct imon_context *ictx,
int ifnum = iface_desc->desc.bInterfaceNumber;
int num_endpts = iface_desc->desc.bNumEndpoints;
int i, ep_dir, ep_type;
bool ir_ep_found = 0;
bool display_ep_found = 0;
bool tx_control = 0;
bool ir_ep_found = false;
bool display_ep_found = false;
bool tx_control = false;
/*
* Scan the endpoint list and set:
@ -1808,13 +1809,13 @@ static bool imon_find_endpoints(struct imon_context *ictx,
ep_type == USB_ENDPOINT_XFER_INT) {
rx_endpoint = ep;
ir_ep_found = 1;
ir_ep_found = true;
dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__);
} else if (!display_ep_found && ep_dir == USB_DIR_OUT &&
ep_type == USB_ENDPOINT_XFER_INT) {
tx_endpoint = ep;
display_ep_found = 1;
display_ep_found = true;
dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__);
}
}
@ -1835,8 +1836,8 @@ static bool imon_find_endpoints(struct imon_context *ictx,
* newer iMON devices that use control urb instead of interrupt
*/
if (!display_ep_found) {
tx_control = 1;
display_ep_found = 1;
tx_control = true;
display_ep_found = true;
dev_dbg(ictx->dev, "%s: device uses control endpoint, not "
"interface OUT endpoint\n", __func__);
}
@ -1847,7 +1848,7 @@ static bool imon_find_endpoints(struct imon_context *ictx,
* and without... :\
*/
if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) {
display_ep_found = 0;
display_ep_found = false;
dev_dbg(ictx->dev, "%s: device has no display\n", __func__);
}
@ -1856,7 +1857,7 @@ static bool imon_find_endpoints(struct imon_context *ictx,
* that refers to e.g. /dev/lcd0 (a character device LCD or VFD).
*/
if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
display_ep_found = 0;
display_ep_found = false;
dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__);
}
@ -1905,9 +1906,10 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
ictx->dev = dev;
ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf));
ictx->dev_present_intf0 = 1;
ictx->dev_present_intf0 = true;
ictx->rx_urb_intf0 = rx_urb;
ictx->tx_urb = tx_urb;
ictx->rf_device = false;
ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor);
ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct);
@ -1979,7 +1981,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf,
}
ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf));
ictx->dev_present_intf1 = 1;
ictx->dev_present_intf1 = true;
ictx->rx_urb_intf1 = rx_urb;
ret = -ENODEV;
@ -2047,6 +2049,12 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR");
ictx->display_supported = false;
break;
/* iMON 2.4G LT (usb stick), no display, iMON RF */
case 0x4e:
dev_info(ictx->dev, "0xffdc iMON 2.4G LT, iMON RF");
ictx->display_supported = false;
ictx->rf_device = true;
break;
/* iMON VFD, no IR (does have vol knob tho) */
case 0x35:
dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR");
@ -2197,15 +2205,6 @@ static int __devinit imon_probe(struct usb_interface *interface,
goto fail;
}
if (product == 0xffdc) {
/* RF products *also* use 0xffdc... sigh... */
sysfs_err = sysfs_create_group(&interface->dev.kobj,
&imon_rf_attribute_group);
if (sysfs_err)
err("%s: Could not create RF sysfs entries(%d)",
__func__, sysfs_err);
}
} else {
/* this is the secondary interface on the device */
ictx = imon_init_intf1(interface, first_if_ctx);
@ -2233,6 +2232,14 @@ static int __devinit imon_probe(struct usb_interface *interface,
imon_set_display_type(ictx, interface);
if (product == 0xffdc && ictx->rf_device) {
sysfs_err = sysfs_create_group(&interface->dev.kobj,
&imon_rf_attribute_group);
if (sysfs_err)
err("%s: Could not create RF sysfs entries(%d)",
__func__, sysfs_err);
}
if (ictx->display_supported)
imon_init_display(ictx, interface);
}
@ -2297,7 +2304,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
}
if (ifnum == 0) {
ictx->dev_present_intf0 = 0;
ictx->dev_present_intf0 = false;
usb_kill_urb(ictx->rx_urb_intf0);
input_unregister_device(ictx->idev);
if (ictx->display_supported) {
@ -2307,7 +2314,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
usb_deregister_dev(interface, &imon_vfd_class);
}
} else {
ictx->dev_present_intf1 = 0;
ictx->dev_present_intf1 = false;
usb_kill_urb(ictx->rx_urb_intf1);
if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
input_unregister_device(ictx->touch);

Просмотреть файл

@ -490,11 +490,12 @@ int __ir_input_register(struct input_dev *input_dev,
if (rc < 0)
goto out_table;
if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) {
rc = ir_raw_event_register(input_dev);
if (rc < 0)
goto out_event;
}
if (ir_dev->props)
if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) {
rc = ir_raw_event_register(input_dev);
if (rc < 0)
goto out_event;
}
IR_dprintk(1, "Registered input device on %s for %s remote.\n",
driver_name, rc_tab->name);
@ -530,8 +531,10 @@ void ir_input_unregister(struct input_dev *input_dev)
IR_dprintk(1, "Freed keycode table\n");
del_timer_sync(&ir_dev->timer_keyup);
if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW)
ir_raw_event_unregister(input_dev);
if (ir_dev->props)
if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW)
ir_raw_event_unregister(input_dev);
rc_tab = &ir_dev->rc_tab;
rc_tab->size = 0;
kfree(rc_tab->scan);

Просмотреть файл

@ -221,9 +221,10 @@ int ir_register_class(struct input_dev *input_dev)
if (unlikely(devno < 0))
return devno;
if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
ir_dev->dev.type = &rc_dev_type;
else
if (ir_dev->props) {
if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
ir_dev->dev.type = &rc_dev_type;
} else
ir_dev->dev.type = &ir_raw_dev_type;
ir_dev->dev.class = &ir_input_class;

Просмотреть файл

@ -6,7 +6,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-avermedia.o \
rc-avermedia-cardbus.o \
rc-avermedia-dvbt.o \
rc-avermedia-m135a-rm-jx.o \
rc-avermedia-m135a.o \
rc-avermedia-m733a-rm-k6.o \
rc-avertv-303.o \
rc-behold.o \
rc-behold-columbus.o \

Просмотреть файл

@ -1,90 +0,0 @@
/* avermedia-m135a-rm-jx.h - Keytable for avermedia_m135a_rm_jx Remote Controller
*
* keymap imported from ir-keymaps.c
*
* Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
*
* 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.
*/
#include <media/rc-map.h>
/*
* Avermedia M135A with IR model RM-JX
* The same codes exist on both Positivo (BR) and original IR
* Mauro Carvalho Chehab <mchehab@infradead.org>
*/
static struct ir_scancode avermedia_m135a_rm_jx[] = {
{ 0x0200, KEY_POWER2 },
{ 0x022e, KEY_DOT }, /* '.' */
{ 0x0201, KEY_MODE }, /* TV/FM or SOURCE */
{ 0x0205, KEY_1 },
{ 0x0206, KEY_2 },
{ 0x0207, KEY_3 },
{ 0x0209, KEY_4 },
{ 0x020a, KEY_5 },
{ 0x020b, KEY_6 },
{ 0x020d, KEY_7 },
{ 0x020e, KEY_8 },
{ 0x020f, KEY_9 },
{ 0x0211, KEY_0 },
{ 0x0213, KEY_RIGHT }, /* -> or L */
{ 0x0212, KEY_LEFT }, /* <- or R */
{ 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */
{ 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */
{ 0x0303, KEY_CHANNELUP },
{ 0x0302, KEY_CHANNELDOWN },
{ 0x021f, KEY_VOLUMEUP },
{ 0x021e, KEY_VOLUMEDOWN },
{ 0x020c, KEY_ENTER }, /* Full Screen */
{ 0x0214, KEY_MUTE },
{ 0x0208, KEY_AUDIO },
{ 0x0203, KEY_TEXT }, /* Teletext */
{ 0x0204, KEY_EPG },
{ 0x022b, KEY_TV2 }, /* TV2 or PIP */
{ 0x021d, KEY_RED },
{ 0x021c, KEY_YELLOW },
{ 0x0301, KEY_GREEN },
{ 0x0300, KEY_BLUE },
{ 0x021a, KEY_PLAYPAUSE },
{ 0x0219, KEY_RECORD },
{ 0x0218, KEY_PLAY },
{ 0x021b, KEY_STOP },
};
static struct rc_keymap avermedia_m135a_rm_jx_map = {
.map = {
.scan = avermedia_m135a_rm_jx,
.size = ARRAY_SIZE(avermedia_m135a_rm_jx),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_M135A_RM_JX,
}
};
static int __init init_rc_map_avermedia_m135a_rm_jx(void)
{
return ir_register_map(&avermedia_m135a_rm_jx_map);
}
static void __exit exit_rc_map_avermedia_m135a_rm_jx(void)
{
ir_unregister_map(&avermedia_m135a_rm_jx_map);
}
module_init(init_rc_map_avermedia_m135a_rm_jx)
module_exit(exit_rc_map_avermedia_m135a_rm_jx)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");

Просмотреть файл

@ -0,0 +1,147 @@
/* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers
*
* Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
* Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
*
* 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.
*/
#include <media/rc-map.h>
/*
* Avermedia M135A with RM-JX and RM-K6 remote controls
*
* On Avermedia M135A with IR model RM-JX, the same codes exist on both
* Positivo (BR) and original IR, initial version and remote control codes
* added by Mauro Carvalho Chehab <mchehab@infradead.org>
*
* Positivo also ships Avermedia M135A with model RM-K6, extra control
* codes added by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
*/
static struct ir_scancode avermedia_m135a[] = {
/* RM-JX */
{ 0x0200, KEY_POWER2 },
{ 0x022e, KEY_DOT }, /* '.' */
{ 0x0201, KEY_MODE }, /* TV/FM or SOURCE */
{ 0x0205, KEY_1 },
{ 0x0206, KEY_2 },
{ 0x0207, KEY_3 },
{ 0x0209, KEY_4 },
{ 0x020a, KEY_5 },
{ 0x020b, KEY_6 },
{ 0x020d, KEY_7 },
{ 0x020e, KEY_8 },
{ 0x020f, KEY_9 },
{ 0x0211, KEY_0 },
{ 0x0213, KEY_RIGHT }, /* -> or L */
{ 0x0212, KEY_LEFT }, /* <- or R */
{ 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */
{ 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */
{ 0x0303, KEY_CHANNELUP },
{ 0x0302, KEY_CHANNELDOWN },
{ 0x021f, KEY_VOLUMEUP },
{ 0x021e, KEY_VOLUMEDOWN },
{ 0x020c, KEY_ENTER }, /* Full Screen */
{ 0x0214, KEY_MUTE },
{ 0x0208, KEY_AUDIO },
{ 0x0203, KEY_TEXT }, /* Teletext */
{ 0x0204, KEY_EPG },
{ 0x022b, KEY_TV2 }, /* TV2 or PIP */
{ 0x021d, KEY_RED },
{ 0x021c, KEY_YELLOW },
{ 0x0301, KEY_GREEN },
{ 0x0300, KEY_BLUE },
{ 0x021a, KEY_PLAYPAUSE },
{ 0x0219, KEY_RECORD },
{ 0x0218, KEY_PLAY },
{ 0x021b, KEY_STOP },
/* RM-K6 */
{ 0x0401, KEY_POWER2 },
{ 0x0406, KEY_MUTE },
{ 0x0408, KEY_MODE }, /* TV/FM */
{ 0x0409, KEY_1 },
{ 0x040a, KEY_2 },
{ 0x040b, KEY_3 },
{ 0x040c, KEY_4 },
{ 0x040d, KEY_5 },
{ 0x040e, KEY_6 },
{ 0x040f, KEY_7 },
{ 0x0410, KEY_8 },
{ 0x0411, KEY_9 },
{ 0x044c, KEY_DOT }, /* '.' */
{ 0x0412, KEY_0 },
{ 0x0407, KEY_REFRESH }, /* Refresh/Reload */
{ 0x0413, KEY_AUDIO },
{ 0x0440, KEY_SCREEN }, /* Full Screen toggle */
{ 0x0441, KEY_HOME },
{ 0x0442, KEY_BACK },
{ 0x0447, KEY_UP },
{ 0x0448, KEY_DOWN },
{ 0x0449, KEY_LEFT },
{ 0x044a, KEY_RIGHT },
{ 0x044b, KEY_OK },
{ 0x0404, KEY_VOLUMEUP },
{ 0x0405, KEY_VOLUMEDOWN },
{ 0x0402, KEY_CHANNELUP },
{ 0x0403, KEY_CHANNELDOWN },
{ 0x0443, KEY_RED },
{ 0x0444, KEY_GREEN },
{ 0x0445, KEY_YELLOW },
{ 0x0446, KEY_BLUE },
{ 0x0414, KEY_TEXT },
{ 0x0415, KEY_EPG },
{ 0x041a, KEY_TV2 }, /* PIP */
{ 0x041b, KEY_MHP }, /* Snapshot */
{ 0x0417, KEY_RECORD },
{ 0x0416, KEY_PLAYPAUSE },
{ 0x0418, KEY_STOP },
{ 0x0419, KEY_PAUSE },
{ 0x041f, KEY_PREVIOUS },
{ 0x041c, KEY_REWIND },
{ 0x041d, KEY_FORWARD },
{ 0x041e, KEY_NEXT },
};
static struct rc_keymap avermedia_m135a_map = {
.map = {
.scan = avermedia_m135a,
.size = ARRAY_SIZE(avermedia_m135a),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_M135A,
}
};
static int __init init_rc_map_avermedia_m135a(void)
{
return ir_register_map(&avermedia_m135a_map);
}
static void __exit exit_rc_map_avermedia_m135a(void)
{
ir_unregister_map(&avermedia_m135a_map);
}
module_init(init_rc_map_avermedia_m135a)
module_exit(exit_rc_map_avermedia_m135a)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");

Просмотреть файл

@ -0,0 +1,95 @@
/* avermedia-m733a-rm-k6.h - Keytable for avermedia_m733a_rm_k6 Remote Controller
*
* Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
*
* 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.
*/
#include <media/rc-map.h>
/*
* Avermedia M733A with IR model RM-K6
* This is the stock remote controller used with Positivo machines with M733A
* Herton Ronaldo Krzesinski <herton@mandriva.com.br>
*/
static struct ir_scancode avermedia_m733a_rm_k6[] = {
{ 0x0401, KEY_POWER2 },
{ 0x0406, KEY_MUTE },
{ 0x0408, KEY_MODE }, /* TV/FM */
{ 0x0409, KEY_1 },
{ 0x040a, KEY_2 },
{ 0x040b, KEY_3 },
{ 0x040c, KEY_4 },
{ 0x040d, KEY_5 },
{ 0x040e, KEY_6 },
{ 0x040f, KEY_7 },
{ 0x0410, KEY_8 },
{ 0x0411, KEY_9 },
{ 0x044c, KEY_DOT }, /* '.' */
{ 0x0412, KEY_0 },
{ 0x0407, KEY_REFRESH }, /* Refresh/Reload */
{ 0x0413, KEY_AUDIO },
{ 0x0440, KEY_SCREEN }, /* Full Screen toggle */
{ 0x0441, KEY_HOME },
{ 0x0442, KEY_BACK },
{ 0x0447, KEY_UP },
{ 0x0448, KEY_DOWN },
{ 0x0449, KEY_LEFT },
{ 0x044a, KEY_RIGHT },
{ 0x044b, KEY_OK },
{ 0x0404, KEY_VOLUMEUP },
{ 0x0405, KEY_VOLUMEDOWN },
{ 0x0402, KEY_CHANNELUP },
{ 0x0403, KEY_CHANNELDOWN },
{ 0x0443, KEY_RED },
{ 0x0444, KEY_GREEN },
{ 0x0445, KEY_YELLOW },
{ 0x0446, KEY_BLUE },
{ 0x0414, KEY_TEXT },
{ 0x0415, KEY_EPG },
{ 0x041a, KEY_TV2 }, /* PIP */
{ 0x041b, KEY_MHP }, /* Snapshot */
{ 0x0417, KEY_RECORD },
{ 0x0416, KEY_PLAYPAUSE },
{ 0x0418, KEY_STOP },
{ 0x0419, KEY_PAUSE },
{ 0x041f, KEY_PREVIOUS },
{ 0x041c, KEY_REWIND },
{ 0x041d, KEY_FORWARD },
{ 0x041e, KEY_NEXT },
};
static struct rc_keymap avermedia_m733a_rm_k6_map = {
.map = {
.scan = avermedia_m733a_rm_k6,
.size = ARRAY_SIZE(avermedia_m733a_rm_k6),
.ir_type = IR_TYPE_NEC,
.name = RC_MAP_AVERMEDIA_M733A_RM_K6,
}
};
static int __init init_rc_map_avermedia_m733a_rm_k6(void)
{
return ir_register_map(&avermedia_m733a_rm_k6_map);
}
static void __exit exit_rc_map_avermedia_m733a_rm_k6(void)
{
ir_unregister_map(&avermedia_m733a_rm_k6_map);
}
module_init(init_rc_map_avermedia_m733a_rm_k6)
module_exit(exit_rc_map_avermedia_m733a_rm_k6)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");

Просмотреть файл

@ -594,7 +594,7 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id)
int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
{
struct input_dev *input_dev;
char *ir_codes = NULL;
char *ir_codes = RC_MAP_DM1105_NEC;
int err = -ENOMEM;
input_dev = input_allocate_device();

Просмотреть файл

@ -351,6 +351,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
const u8 *ts, *ts_end, *from_where = NULL;
u8 ts_remain = 0, how_much = 0, new_ts = 1;
struct ethhdr *ethh = NULL;
bool error = false;
#ifdef ULE_DEBUG
/* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
@ -460,10 +461,16 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
/* Drop partly decoded SNDU, reset state, resync on PUSI. */
if (priv->ule_skb) {
dev_kfree_skb( priv->ule_skb );
error = true;
dev_kfree_skb(priv->ule_skb);
}
if (error || priv->ule_sndu_remain) {
dev->stats.rx_errors++;
dev->stats.rx_frame_errors++;
error = false;
}
reset_ule(priv);
priv->need_pusi = 1;
continue;
@ -535,6 +542,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
from_where += 2;
}
priv->ule_sndu_remain = priv->ule_sndu_len + 2;
/*
* State of current TS:
* ts_remain (remaining bytes in the current TS cell)
@ -544,6 +552,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
*/
switch (ts_remain) {
case 1:
priv->ule_sndu_remain--;
priv->ule_sndu_type = from_where[0] << 8;
priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */
ts_remain -= 1; from_where += 1;
@ -557,6 +566,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
default: /* complete ULE header is present in current TS. */
/* Extract ULE type field. */
if (priv->ule_sndu_type_1) {
priv->ule_sndu_type_1 = 0;
priv->ule_sndu_type |= from_where[0];
from_where += 1; /* points to payload start. */
ts_remain -= 1;

Просмотреть файл

@ -76,6 +76,7 @@ config DVB_USB_DIB0700
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
select DVB_TUNER_DIB0090 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
@ -134,6 +135,7 @@ config DVB_USB_M920X
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
Currently, only devices with a product id of
@ -264,7 +266,7 @@ config DVB_USB_DW2102
select DVB_STB6000 if !DVB_FE_CUSTOMISE
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_SI21XX if !DVB_FE_CUSTOMISE
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select DVB_MT312 if !DVB_FE_CUSTOMISE
select DVB_ZL10039 if !DVB_FE_CUSTOMISE
select DVB_DS3000 if !DVB_FE_CUSTOMISE

Просмотреть файл

@ -1026,8 +1026,10 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
&cxusb_dualdig4_rev2_config) < 0)
&cxusb_dualdig4_rev2_config) < 0) {
printk(KERN_WARNING "Unable to enumerate dib7000p\n");
return -ENODEV;
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&cxusb_dualdig4_rev2_config);

Просмотреть файл

@ -198,6 +198,7 @@
#define USB_PID_AVERMEDIA_A850 0x850a
#define USB_PID_AVERMEDIA_A805 0xa805
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058

Просмотреть файл

@ -29,6 +29,8 @@
#include "tda826x.h"
#include "tda10086.h"
#include "tda1002x.h"
#include "tda827x.h"
#include "lnbp21.h"
/* debug */
@ -150,7 +152,17 @@ static struct tda10086_config tda10086_config = {
.xtal_freq = TDA10086_XTAL_16M,
};
static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)
static struct tda10023_config tda10023_config = {
.demod_address = 0x0c,
.invert = 0,
.xtal = 16000000,
.pll_m = 11,
.pll_p = 3,
.pll_n = 1,
.deltaf = 0xa511,
};
static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
{
if (usb_set_interface(adap->dev->udev,0,3) < 0)
err("set interface to alts=3 failed");
@ -163,7 +175,27 @@ static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)
return 0;
}
static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap)
static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
{
if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
err("set interface to alts=3 failed");
if ((adap->fe = dvb_attach(tda10023_attach, &tda10023_config, &adap->dev->i2c_adap, 0x48)) == NULL) {
deb_info("TDA10023 attach failed\n");
return -ENODEV;
}
return 0;
}
static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
{
if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) {
printk(KERN_ERR "%s: No tda827x found!\n", __func__);
return -ENODEV;
}
return 0;
}
static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap)
{
if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
deb_info("TDA8263 attach failed\n");
@ -180,6 +212,7 @@ static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap)
/* DVB USB Driver stuff */
static struct dvb_usb_device_properties ttusb2_properties;
static struct dvb_usb_device_properties ttusb2_properties_s2400;
static struct dvb_usb_device_properties ttusb2_properties_ct3650;
static int ttusb2_probe(struct usb_interface *intf,
const struct usb_device_id *id)
@ -187,6 +220,8 @@ static int ttusb2_probe(struct usb_interface *intf,
if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
THIS_MODULE, NULL, adapter_nr) ||
0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
THIS_MODULE, NULL, adapter_nr) ||
0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650,
THIS_MODULE, NULL, adapter_nr))
return 0;
return -ENODEV;
@ -197,6 +232,8 @@ static struct usb_device_id ttusb2_table [] = {
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
{ USB_DEVICE(USB_VID_TECHNOTREND,
USB_PID_TECHNOTREND_CONNECT_S2400) },
{ USB_DEVICE(USB_VID_TECHNOTREND,
USB_PID_TECHNOTREND_CONNECT_CT3650) },
{} /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, ttusb2_table);
@ -214,8 +251,8 @@ static struct dvb_usb_device_properties ttusb2_properties = {
{
.streaming_ctrl = NULL, // ttusb2_streaming_ctrl,
.frontend_attach = ttusb2_frontend_attach,
.tuner_attach = ttusb2_tuner_attach,
.frontend_attach = ttusb2_frontend_tda10086_attach,
.tuner_attach = ttusb2_tuner_tda826x_attach,
/* parameter for the MPEG2-data transfer */
.stream = {
@ -266,8 +303,8 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
{
.streaming_ctrl = NULL,
.frontend_attach = ttusb2_frontend_attach,
.tuner_attach = ttusb2_tuner_attach,
.frontend_attach = ttusb2_frontend_tda10086_attach,
.tuner_attach = ttusb2_tuner_tda826x_attach,
/* parameter for the MPEG2-data transfer */
.stream = {
@ -301,6 +338,52 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
}
};
static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
.usb_ctrl = CYPRESS_FX2,
.size_of_priv = sizeof(struct ttusb2_state),
.num_adapters = 1,
.adapter = {
{
.streaming_ctrl = NULL,
.frontend_attach = ttusb2_frontend_tda10023_attach,
.tuner_attach = ttusb2_tuner_tda827x_attach,
/* parameter for the MPEG2-data transfer */
.stream = {
.type = USB_ISOC,
.count = 5,
.endpoint = 0x02,
.u = {
.isoc = {
.framesperurb = 4,
.framesize = 940,
.interval = 1,
}
}
}
},
},
.power_ctrl = ttusb2_power_ctrl,
.identify_state = ttusb2_identify_state,
.i2c_algo = &ttusb2_i2c_algo,
.generic_bulk_ctrl_endpoint = 0x01,
.num_device_descs = 1,
.devices = {
{ "Technotrend TT-connect CT-3650",
.warm_ids = { &ttusb2_table[3], NULL },
},
}
};
static struct usb_driver ttusb2_driver = {
.name = "dvb_usb_ttusb2",
.probe = ttusb2_probe,

Просмотреть файл

@ -58,7 +58,7 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
num = hpsb_iso_n_ready(iso);
if (!fdtv) {
dev_err(fdtv->device, "received at unknown iso channel\n");
pr_err("received at unknown iso channel\n");
goto out;
}

Просмотреть файл

@ -567,30 +567,6 @@ static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
/* ----------------------------------------------------------------------- */
static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
switch (fmt->type) {
default:
return -EINVAL;
}
return 0;
}
static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
switch (fmt->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
/* Not yet implemented */
break;
default:
return -EINVAL;
}
return 0;
}
/* ----------------------------------------------------------------------- */
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int au8522_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
@ -772,8 +748,6 @@ static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
static const struct v4l2_subdev_video_ops au8522_video_ops = {
.s_routing = au8522_s_video_routing,
.g_fmt = au8522_g_fmt,
.s_fmt = au8522_s_fmt,
.s_stream = au8522_s_stream,
};

Просмотреть файл

@ -969,15 +969,12 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
dprintk("%s\n", __func__);
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct ds3000_state), GFP_KERNEL);
state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
if (state == NULL) {
printk(KERN_ERR "Unable to kmalloc\n");
goto error2;
}
/* setup the state */
memset(state, 0, sizeof(struct ds3000_state));
state->config = config;
state->i2c = i2c;
state->prevUCBS2 = 0;

Просмотреть файл

@ -303,7 +303,10 @@ static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
static int stv6110x_sleep(struct dvb_frontend *fe)
{
return stv6110x_set_mode(fe, TUNER_SLEEP);
if (fe->tuner_priv)
return stv6110x_set_mode(fe, TUNER_SLEEP);
return 0;
}
static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)

Просмотреть файл

@ -217,6 +217,19 @@ static struct ngene_info ngene_info_cineS2v5 = {
.fw_version = 15,
};
static struct ngene_info ngene_info_duoFlexS2 = {
.type = NGENE_SIDEWINDER,
.name = "Digital Devices DuoFlex S2 miniPCIe",
.io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
.demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
.tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
.fe_config = {&fe_cineS2, &fe_cineS2},
.tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
.lnb = {0x0a, 0x08},
.tsf = {3, 3},
.fw_version = 15,
};
static struct ngene_info ngene_info_m780 = {
.type = NGENE_APP,
.name = "Aver M780 ATSC/QAM-B",
@ -256,6 +269,8 @@ static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2),
NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2),
NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5),
NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlexS2),
NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlexS2),
NGENE_ID(0x1461, 0x062e, ngene_info_m780),
{0}
};

Просмотреть файл

@ -53,8 +53,6 @@ MODULE_PARM_DESC(debug, "Print debugging information.");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define COMMAND_TIMEOUT_WORKAROUND
#define dprintk if (debug) printk
#define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr)))
@ -147,24 +145,24 @@ static void demux_tasklet(unsigned long data)
} else {
if (chan->HWState == HWSTATE_RUN) {
u32 Flags = 0;
IBufferExchange *exch1 = chan->pBufferExchange;
IBufferExchange *exch2 = chan->pBufferExchange2;
if (Cur->ngeneBuffer.SR.Flags & 0x01)
Flags |= BEF_EVEN_FIELD;
if (Cur->ngeneBuffer.SR.Flags & 0x20)
Flags |= BEF_OVERFLOW;
if (chan->pBufferExchange)
chan->pBufferExchange(chan,
Cur->Buffer1,
chan->
Capture1Length,
Cur->ngeneBuffer.
SR.Clock, Flags);
if (chan->pBufferExchange2)
chan->pBufferExchange2(chan,
Cur->Buffer2,
chan->
Capture2Length,
Cur->ngeneBuffer.
SR.Clock, Flags);
spin_unlock_irq(&chan->state_lock);
if (exch1)
exch1(chan, Cur->Buffer1,
chan->Capture1Length,
Cur->ngeneBuffer.SR.Clock,
Flags);
if (exch2)
exch2(chan, Cur->Buffer2,
chan->Capture2Length,
Cur->ngeneBuffer.SR.Clock,
Flags);
spin_lock_irq(&chan->state_lock);
} else if (chan->HWState != HWSTATE_STOP)
chan->HWState = HWSTATE_RUN;
}
@ -572,11 +570,7 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream,
u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700);
u16 BsSDO = 0x9B00;
/* down(&dev->stream_mutex); */
while (down_trylock(&dev->stream_mutex)) {
printk(KERN_INFO DEVICE_NAME ": SC locked\n");
msleep(1);
}
down(&dev->stream_mutex);
memset(&com, 0, sizeof(com));
com.cmd.hdr.Opcode = CMD_CONTROL;
com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2;
@ -1252,14 +1246,17 @@ static int ngene_load_firm(struct ngene *dev)
version = 15;
size = 23466;
fw_name = "ngene_15.fw";
dev->cmd_timeout_workaround = true;
break;
case 16:
size = 23498;
fw_name = "ngene_16.fw";
dev->cmd_timeout_workaround = true;
break;
case 17:
size = 24446;
fw_name = "ngene_17.fw";
dev->cmd_timeout_workaround = true;
break;
}
@ -1299,11 +1296,16 @@ static void ngene_stop(struct ngene *dev)
ngwritel(0, NGENE_EVENT);
ngwritel(0, NGENE_EVENT_HI);
free_irq(dev->pci_dev->irq, dev);
#ifdef CONFIG_PCI_MSI
if (dev->msi_enabled)
pci_disable_msi(dev->pci_dev);
#endif
}
static int ngene_start(struct ngene *dev)
{
int stat;
unsigned long flags;
int i;
pci_set_master(dev->pci_dev);
@ -1333,6 +1335,28 @@ static int ngene_start(struct ngene *dev)
if (stat < 0)
goto fail;
#ifdef CONFIG_PCI_MSI
/* enable MSI if kernel and card support it */
if (pci_msi_enabled() && dev->card_info->msi_supported) {
ngwritel(0, NGENE_INT_ENABLE);
free_irq(dev->pci_dev->irq, dev);
stat = pci_enable_msi(dev->pci_dev);
if (stat) {
printk(KERN_INFO DEVICE_NAME
": MSI not available\n");
flags = IRQF_SHARED;
} else {
flags = 0;
dev->msi_enabled = true;
}
stat = request_irq(dev->pci_dev->irq, irq_handler,
flags, "nGene", dev);
if (stat < 0)
goto fail2;
ngwritel(1, NGENE_INT_ENABLE);
}
#endif
stat = ngene_i2c_init(dev, 0);
if (stat < 0)
goto fail;
@ -1358,10 +1382,18 @@ static int ngene_start(struct ngene *dev)
bconf = BUFFER_CONFIG_3333;
stat = ngene_command_config_buf(dev, bconf);
}
return stat;
if (!stat)
return stat;
/* otherwise error: fall through */
fail:
ngwritel(0, NGENE_INT_ENABLE);
free_irq(dev->pci_dev->irq, dev);
#ifdef CONFIG_PCI_MSI
fail2:
if (dev->msi_enabled)
pci_disable_msi(dev->pci_dev);
#endif
return stat;
}
@ -1379,10 +1411,8 @@ static void release_channel(struct ngene_channel *chan)
struct ngene_info *ni = dev->card_info;
int io = ni->io_type[chan->number];
#ifdef COMMAND_TIMEOUT_WORKAROUND
if (chan->running)
if (chan->dev->cmd_timeout_workaround && chan->running)
set_transfer(chan, 0);
#endif
tasklet_kill(&chan->demux_tasklet);

Просмотреть файл

@ -37,15 +37,12 @@
#include <linux/pci.h>
#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/version.h>
#include <linux/byteorder/generic.h>
#include <linux/firmware.h>
#include <linux/vmalloc.h>
#include "ngene.h"
#define COMMAND_TIMEOUT_WORKAROUND
/****************************************************************************/
/* COMMAND API interface ****************************************************/
@ -69,9 +66,7 @@ void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
struct ngene_channel *chan = priv;
#ifdef COMMAND_TIMEOUT_WORKAROUND
if (chan->users > 0)
#endif
dvb_dmx_swfilter(&chan->demux, buf, len);
return NULL;
}
@ -106,11 +101,8 @@ int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
struct ngene_channel *chan = dvbdmx->priv;
if (chan->users == 0) {
#ifdef COMMAND_TIMEOUT_WORKAROUND
if (!chan->running)
#endif
if (!chan->dev->cmd_timeout_workaround || !chan->running)
set_transfer(chan, 1);
/* msleep(10); */
}
return ++chan->users;
@ -124,9 +116,8 @@ int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
if (--chan->users)
return chan->users;
#ifndef COMMAND_TIMEOUT_WORKAROUND
set_transfer(chan, 0);
#endif
if (!chan->dev->cmd_timeout_workaround)
set_transfer(chan, 0);
return 0;
}

Просмотреть файл

@ -39,7 +39,6 @@
#include <linux/pci_ids.h>
#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/version.h>
#include <linux/byteorder/generic.h>
#include <linux/firmware.h>
#include <linux/vmalloc.h>

Просмотреть файл

@ -725,6 +725,8 @@ struct ngene {
u32 device_version;
u32 fw_interface_version;
u32 icounts;
bool msi_enabled;
bool cmd_timeout_workaround;
u8 *CmdDoneByte;
int BootFirmware;
@ -797,6 +799,7 @@ struct ngene_info {
#define NGENE_VBOX_V2 7
int fw_version;
bool msi_supported;
char *name;
int io_type[MAX_STREAM];

Просмотреть файл

@ -68,13 +68,14 @@ config DVB_BUDGET
select DVB_VES1820 if !DVB_FE_CUSTOMISE
select DVB_L64781 if !DVB_FE_CUSTOMISE
select DVB_TDA8083 if !DVB_FE_CUSTOMISE
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select DVB_S5H1420 if !DVB_FE_CUSTOMISE
select DVB_TDA10086 if !DVB_FE_CUSTOMISE
select DVB_TDA826X if !DVB_FE_CUSTOMISE
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select DVB_ISL6423 if !DVB_FE_CUSTOMISE
select DVB_STV090x if !DVB_FE_CUSTOMISE
select DVB_STV6110x if !DVB_FE_CUSTOMISE
help
Support for simple SAA7146 based DVB cards (so called Budget-
or Nova-PCI cards) without onboard MPEG2 decoder, and without

Просмотреть файл

@ -215,6 +215,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
break;
case 0x1010:
case 0x1017:
case 0x1019:
case 0x101a:
/* for the Technotrend 1500 bundled remote */
ir_codes = RC_MAP_TT_1500;

Просмотреть файл

@ -646,7 +646,7 @@ config VIDEO_PMS
config VIDEO_BWQCAM
tristate "Quickcam BW Video For Linux"
depends on PARPORT && VIDEO_V4L1
depends on PARPORT && VIDEO_V4L2
help
Say Y have if you the black and white version of the QuickCam
camera. See the next option for the color version.
@ -656,7 +656,7 @@ config VIDEO_BWQCAM
config VIDEO_CQCAM
tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)"
depends on EXPERIMENTAL && PARPORT && VIDEO_V4L1
depends on EXPERIMENTAL && PARPORT && VIDEO_V4L2
help
This is the video4linux driver for the colour version of the
Connectix QuickCam. If you have one of these cameras, say Y here,

Просмотреть файл

@ -11,6 +11,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/ak881x.h>
@ -141,7 +142,7 @@ static int ak881x_s_mbus_fmt(struct v4l2_subdev *sd,
return ak881x_try_g_mbus_fmt(sd, mf);
}
static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, int index,
static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code)
{
if (index)

Просмотреть файл

@ -66,19 +66,58 @@ OTHER DEALINGS IN THE SOFTWARE.
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/parport.h>
#include <linux/sched.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <linux/version.h>
#include <linux/videodev2.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
#include "bw-qcam.h"
/* One from column A... */
#define QC_NOTSET 0
#define QC_UNIDIR 1
#define QC_BIDIR 2
#define QC_SERIAL 3
/* ... and one from column B */
#define QC_ANY 0x00
#define QC_FORCE_UNIDIR 0x10
#define QC_FORCE_BIDIR 0x20
#define QC_FORCE_SERIAL 0x30
/* in the port_mode member */
#define QC_MODE_MASK 0x07
#define QC_FORCE_MASK 0x70
#define MAX_HEIGHT 243
#define MAX_WIDTH 336
/* Bit fields for status flags */
#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
struct qcam {
struct v4l2_device v4l2_dev;
struct video_device vdev;
struct pardevice *pdev;
struct parport *pport;
struct mutex lock;
int width, height;
int bpp;
int mode;
int contrast, brightness, whitebal;
int port_mode;
int transfer_scale;
int top, left;
int status;
unsigned int saved_bits;
unsigned long in_use;
};
static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
static unsigned int yieldlines = 4; /* Yield after this many during capture */
@ -93,22 +132,26 @@ module_param(video_nr, int, 0);
* immediately attempt to initialize qcam */
module_param(force_init, int, 0);
static inline int read_lpstatus(struct qcam_device *q)
#define MAX_CAMS 4
static struct qcam *qcams[MAX_CAMS];
static unsigned int num_cams;
static inline int read_lpstatus(struct qcam *q)
{
return parport_read_status(q->pport);
}
static inline int read_lpdata(struct qcam_device *q)
static inline int read_lpdata(struct qcam *q)
{
return parport_read_data(q->pport);
}
static inline void write_lpdata(struct qcam_device *q, int d)
static inline void write_lpdata(struct qcam *q, int d)
{
parport_write_data(q->pport, d);
}
static inline void write_lpcontrol(struct qcam_device *q, int d)
static void write_lpcontrol(struct qcam *q, int d)
{
if (d & 0x20) {
/* Set bidirectional mode to reverse (data in) */
@ -124,126 +167,11 @@ static inline void write_lpcontrol(struct qcam_device *q, int d)
parport_write_control(q->pport, d);
}
static int qc_waithand(struct qcam_device *q, int val);
static int qc_command(struct qcam_device *q, int command);
static int qc_readparam(struct qcam_device *q);
static int qc_setscanmode(struct qcam_device *q);
static int qc_readbytes(struct qcam_device *q, char buffer[]);
static struct video_device qcam_template;
static int qc_calibrate(struct qcam_device *q)
{
/*
* Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
* The white balance is an individiual value for each
* quickcam.
*/
int value;
int count = 0;
qc_command(q, 27); /* AutoAdjustOffset */
qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
/* GetOffset (33) will read 255 until autocalibration */
/* is finished. After that, a value of 1-254 will be */
/* returned. */
do {
qc_command(q, 33);
value = qc_readparam(q);
mdelay(1);
schedule();
count++;
} while (value == 0xff && count < 2048);
q->whitebal = value;
return value;
}
/* Initialize the QuickCam driver control structure. This is where
* defaults are set for people who don't have a config file.*/
static struct qcam_device *qcam_init(struct parport *port)
{
struct qcam_device *q;
q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
if (q == NULL)
return NULL;
q->pport = port;
q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
NULL, 0, NULL);
if (q->pdev == NULL) {
printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
port->name);
kfree(q);
return NULL;
}
memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
mutex_init(&q->lock);
q->port_mode = (QC_ANY | QC_NOTSET);
q->width = 320;
q->height = 240;
q->bpp = 4;
q->transfer_scale = 2;
q->contrast = 192;
q->brightness = 180;
q->whitebal = 105;
q->top = 1;
q->left = 14;
q->mode = -1;
q->status = QC_PARAM_CHANGE;
return q;
}
/* qc_command is probably a bit of a misnomer -- it's used to send
* bytes *to* the camera. Generally, these bytes are either commands
* or arguments to commands, so the name fits, but it still bugs me a
* bit. See the documentation for a list of commands. */
static int qc_command(struct qcam_device *q, int command)
{
int n1, n2;
int cmd;
write_lpdata(q, command);
write_lpcontrol(q, 6);
n1 = qc_waithand(q, 1);
write_lpcontrol(q, 0xe);
n2 = qc_waithand(q, 0);
cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
return cmd;
}
static int qc_readparam(struct qcam_device *q)
{
int n1, n2;
int cmd;
write_lpcontrol(q, 6);
n1 = qc_waithand(q, 1);
write_lpcontrol(q, 0xe);
n2 = qc_waithand(q, 0);
cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
return cmd;
}
/* qc_waithand busy-waits for a handshake signal from the QuickCam.
* Almost all communication with the camera requires handshaking. */
static int qc_waithand(struct qcam_device *q, int val)
static int qc_waithand(struct qcam *q, int val)
{
int status;
int runs = 0;
@ -286,7 +214,7 @@ static int qc_waithand(struct qcam_device *q, int val)
* (bit 3 of status register). It also returns the last value read,
* since this data is useful. */
static unsigned int qc_waithand2(struct qcam_device *q, int val)
static unsigned int qc_waithand2(struct qcam *q, int val)
{
unsigned int status;
int runs = 0;
@ -309,6 +237,43 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val)
return status;
}
/* qc_command is probably a bit of a misnomer -- it's used to send
* bytes *to* the camera. Generally, these bytes are either commands
* or arguments to commands, so the name fits, but it still bugs me a
* bit. See the documentation for a list of commands. */
static int qc_command(struct qcam *q, int command)
{
int n1, n2;
int cmd;
write_lpdata(q, command);
write_lpcontrol(q, 6);
n1 = qc_waithand(q, 1);
write_lpcontrol(q, 0xe);
n2 = qc_waithand(q, 0);
cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
return cmd;
}
static int qc_readparam(struct qcam *q)
{
int n1, n2;
int cmd;
write_lpcontrol(q, 6);
n1 = qc_waithand(q, 1);
write_lpcontrol(q, 0xe);
n2 = qc_waithand(q, 0);
cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
return cmd;
}
/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
the status register at 5-10 Hz. This is only used in the autoprobe
@ -317,7 +282,7 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val)
almost completely safe, while their method screws up my printer if
I plug it in before the camera. */
static int qc_detect(struct qcam_device *q)
static int qc_detect(struct qcam *q)
{
int reg, lastreg;
int count = 0;
@ -358,41 +323,6 @@ static int qc_detect(struct qcam_device *q)
}
}
/* Reset the QuickCam. This uses the same sequence the Windows
* QuickPic program uses. Someone with a bi-directional port should
* check that bi-directional mode is detected right, and then
* implement bi-directional mode in qc_readbyte(). */
static void qc_reset(struct qcam_device *q)
{
switch (q->port_mode & QC_FORCE_MASK) {
case QC_FORCE_UNIDIR:
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
break;
case QC_FORCE_BIDIR:
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
break;
case QC_ANY:
write_lpcontrol(q, 0x20);
write_lpdata(q, 0x75);
if (read_lpdata(q) != 0x75)
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
else
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
break;
}
write_lpcontrol(q, 0xb);
udelay(250);
write_lpcontrol(q, 0xe);
qc_setscanmode(q); /* in case port_mode changed */
}
/* Decide which scan mode to use. There's no real requirement that
* the scanmode match the resolution in q->height and q-> width -- the
* camera takes the picture at the resolution specified in the
@ -402,7 +332,7 @@ static void qc_reset(struct qcam_device *q)
* returned. If the scan is smaller, then the rest of the image
* returned contains garbage. */
static int qc_setscanmode(struct qcam_device *q)
static int qc_setscanmode(struct qcam *q)
{
int old_mode = q->mode;
@ -442,10 +372,45 @@ static int qc_setscanmode(struct qcam_device *q)
}
/* Reset the QuickCam. This uses the same sequence the Windows
* QuickPic program uses. Someone with a bi-directional port should
* check that bi-directional mode is detected right, and then
* implement bi-directional mode in qc_readbyte(). */
static void qc_reset(struct qcam *q)
{
switch (q->port_mode & QC_FORCE_MASK) {
case QC_FORCE_UNIDIR:
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
break;
case QC_FORCE_BIDIR:
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
break;
case QC_ANY:
write_lpcontrol(q, 0x20);
write_lpdata(q, 0x75);
if (read_lpdata(q) != 0x75)
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
else
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
break;
}
write_lpcontrol(q, 0xb);
udelay(250);
write_lpcontrol(q, 0xe);
qc_setscanmode(q); /* in case port_mode changed */
}
/* Reset the QuickCam and program for brightness, contrast,
* white-balance, and resolution. */
static void qc_set(struct qcam_device *q)
static void qc_set(struct qcam *q)
{
int val;
int val2;
@ -499,7 +464,7 @@ static void qc_set(struct qcam_device *q)
the supplied buffer. It returns the number of bytes read,
or -1 on error. */
static inline int qc_readbytes(struct qcam_device *q, char buffer[])
static inline int qc_readbytes(struct qcam *q, char buffer[])
{
int ret = 1;
unsigned int hi, lo;
@ -590,7 +555,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
* n=2^(bit depth)-1. Ask me for more details if you don't understand
* this. */
static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len)
static long qc_capture(struct qcam *q, char __user *buf, unsigned long len)
{
int i, j, k, yield;
int bytes;
@ -674,171 +639,206 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
* Video4linux interfacing
*/
static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
static int qcam_querycap(struct file *file, void *priv,
struct v4l2_capability *vcap)
{
struct video_device *dev = video_devdata(file);
struct qcam_device *qcam = (struct qcam_device *)dev;
struct qcam *qcam = video_drvdata(file);
switch (cmd) {
case VIDIOCGCAP:
{
struct video_capability *b = arg;
strcpy(b->name, "Quickcam");
b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
b->channels = 1;
b->audios = 0;
b->maxwidth = 320;
b->maxheight = 240;
b->minwidth = 80;
b->minheight = 60;
return 0;
}
case VIDIOCGCHAN:
{
struct video_channel *v = arg;
if (v->channel != 0)
return -EINVAL;
v->flags = 0;
v->tuners = 0;
/* Good question.. its composite or SVHS so.. */
v->type = VIDEO_TYPE_CAMERA;
strcpy(v->name, "Camera");
return 0;
}
case VIDIOCSCHAN:
{
struct video_channel *v = arg;
if (v->channel != 0)
return -EINVAL;
return 0;
}
case VIDIOCGTUNER:
{
struct video_tuner *v = arg;
if (v->tuner)
return -EINVAL;
strcpy(v->name, "Format");
v->rangelow = 0;
v->rangehigh = 0;
v->flags = 0;
v->mode = VIDEO_MODE_AUTO;
return 0;
}
case VIDIOCSTUNER:
{
struct video_tuner *v = arg;
if (v->tuner)
return -EINVAL;
if (v->mode != VIDEO_MODE_AUTO)
return -EINVAL;
return 0;
}
case VIDIOCGPICT:
{
struct video_picture *p = arg;
p->colour = 0x8000;
p->hue = 0x8000;
p->brightness = qcam->brightness << 8;
p->contrast = qcam->contrast << 8;
p->whiteness = qcam->whitebal << 8;
p->depth = qcam->bpp;
p->palette = VIDEO_PALETTE_GREY;
return 0;
}
case VIDIOCSPICT:
{
struct video_picture *p = arg;
if (p->palette != VIDEO_PALETTE_GREY)
return -EINVAL;
if (p->depth != 4 && p->depth != 6)
return -EINVAL;
/*
* Now load the camera.
*/
qcam->brightness = p->brightness >> 8;
qcam->contrast = p->contrast >> 8;
qcam->whitebal = p->whiteness >> 8;
qcam->bpp = p->depth;
mutex_lock(&qcam->lock);
qc_setscanmode(qcam);
mutex_unlock(&qcam->lock);
qcam->status |= QC_PARAM_CHANGE;
return 0;
}
case VIDIOCSWIN:
{
struct video_window *vw = arg;
if (vw->flags)
return -EINVAL;
if (vw->clipcount)
return -EINVAL;
if (vw->height < 60 || vw->height > 240)
return -EINVAL;
if (vw->width < 80 || vw->width > 320)
return -EINVAL;
qcam->width = 320;
qcam->height = 240;
qcam->transfer_scale = 4;
if (vw->width >= 160 && vw->height >= 120)
qcam->transfer_scale = 2;
if (vw->width >= 320 && vw->height >= 240) {
qcam->width = 320;
qcam->height = 240;
qcam->transfer_scale = 1;
}
mutex_lock(&qcam->lock);
qc_setscanmode(qcam);
mutex_unlock(&qcam->lock);
/* We must update the camera before we grab. We could
just have changed the grab size */
qcam->status |= QC_PARAM_CHANGE;
/* Ok we figured out what to use from our wide choice */
return 0;
}
case VIDIOCGWIN:
{
struct video_window *vw = arg;
memset(vw, 0, sizeof(*vw));
vw->width = qcam->width / qcam->transfer_scale;
vw->height = qcam->height / qcam->transfer_scale;
return 0;
}
case VIDIOCKEY:
return 0;
case VIDIOCCAPTURE:
case VIDIOCGFBUF:
case VIDIOCSFBUF:
case VIDIOCGFREQ:
case VIDIOCSFREQ:
case VIDIOCGAUDIO:
case VIDIOCSAUDIO:
return -EINVAL;
default:
return -ENOIOCTLCMD;
}
strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card));
strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
vcap->version = KERNEL_VERSION(0, 0, 2);
vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
return 0;
}
static long qcam_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
{
return video_usercopy(file, cmd, arg, qcam_do_ioctl);
if (vin->index > 0)
return -EINVAL;
strlcpy(vin->name, "Camera", sizeof(vin->name));
vin->type = V4L2_INPUT_TYPE_CAMERA;
vin->audioset = 0;
vin->tuner = 0;
vin->std = 0;
vin->status = 0;
return 0;
}
static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
{
*inp = 0;
return 0;
}
static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
{
return (inp > 0) ? -EINVAL : 0;
}
static int qcam_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180);
case V4L2_CID_CONTRAST:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
case V4L2_CID_GAMMA:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105);
}
return -EINVAL;
}
static int qcam_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct qcam *qcam = video_drvdata(file);
int ret = 0;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->value = qcam->brightness;
break;
case V4L2_CID_CONTRAST:
ctrl->value = qcam->contrast;
break;
case V4L2_CID_GAMMA:
ctrl->value = qcam->whitebal;
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static int qcam_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct qcam *qcam = video_drvdata(file);
int ret = 0;
mutex_lock(&qcam->lock);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
qcam->brightness = ctrl->value;
break;
case V4L2_CID_CONTRAST:
qcam->contrast = ctrl->value;
break;
case V4L2_CID_GAMMA:
qcam->whitebal = ctrl->value;
break;
default:
ret = -EINVAL;
break;
}
if (ret == 0) {
qc_setscanmode(qcam);
qcam->status |= QC_PARAM_CHANGE;
}
mutex_unlock(&qcam->lock);
return ret;
}
static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct qcam *qcam = video_drvdata(file);
struct v4l2_pix_format *pix = &fmt->fmt.pix;
pix->width = qcam->width / qcam->transfer_scale;
pix->height = qcam->height / qcam->transfer_scale;
pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6;
pix->field = V4L2_FIELD_NONE;
pix->bytesperline = qcam->width;
pix->sizeimage = qcam->width * qcam->height;
/* Just a guess */
pix->colorspace = V4L2_COLORSPACE_SRGB;
return 0;
}
static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct v4l2_pix_format *pix = &fmt->fmt.pix;
if (pix->height <= 60 || pix->width <= 80) {
pix->height = 60;
pix->width = 80;
} else if (pix->height <= 120 || pix->width <= 160) {
pix->height = 120;
pix->width = 160;
} else {
pix->height = 240;
pix->width = 320;
}
if (pix->pixelformat != V4L2_PIX_FMT_Y4 &&
pix->pixelformat != V4L2_PIX_FMT_Y6)
pix->pixelformat = V4L2_PIX_FMT_Y4;
pix->field = V4L2_FIELD_NONE;
pix->bytesperline = pix->width;
pix->sizeimage = pix->width * pix->height;
/* Just a guess */
pix->colorspace = V4L2_COLORSPACE_SRGB;
return 0;
}
static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct qcam *qcam = video_drvdata(file);
struct v4l2_pix_format *pix = &fmt->fmt.pix;
int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
if (ret)
return ret;
qcam->width = 320;
qcam->height = 240;
if (pix->height == 60)
qcam->transfer_scale = 4;
else if (pix->height == 120)
qcam->transfer_scale = 2;
else
qcam->transfer_scale = 1;
if (pix->pixelformat == V4L2_PIX_FMT_Y6)
qcam->bpp = 6;
else
qcam->bpp = 4;
mutex_lock(&qcam->lock);
qc_setscanmode(qcam);
/* We must update the camera before we grab. We could
just have changed the grab size */
qcam->status |= QC_PARAM_CHANGE;
mutex_unlock(&qcam->lock);
return 0;
}
static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
{
static struct v4l2_fmtdesc formats[] = {
{ 0, 0, 0,
"4-Bit Monochrome", V4L2_PIX_FMT_Y4,
{ 0, 0, 0, 0 }
},
{ 0, 0, 0,
"6-Bit Monochrome", V4L2_PIX_FMT_Y6,
{ 0, 0, 0, 0 }
},
};
enum v4l2_buf_type type = fmt->type;
if (fmt->index > 1)
return -EINVAL;
*fmt = formats[fmt->index];
fmt->type = type;
return 0;
}
static ssize_t qcam_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct video_device *v = video_devdata(file);
struct qcam_device *qcam = (struct qcam_device *)v;
struct qcam *qcam = video_drvdata(file);
int len;
parport_claim_or_block(qcam->pdev);
@ -858,43 +858,112 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
return len;
}
static int qcam_exclusive_open(struct file *file)
{
struct video_device *dev = video_devdata(file);
struct qcam_device *qcam = (struct qcam_device *)dev;
return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0;
}
static int qcam_exclusive_release(struct file *file)
{
struct video_device *dev = video_devdata(file);
struct qcam_device *qcam = (struct qcam_device *)dev;
clear_bit(0, &qcam->in_use);
return 0;
}
static const struct v4l2_file_operations qcam_fops = {
.owner = THIS_MODULE,
.open = qcam_exclusive_open,
.release = qcam_exclusive_release,
.ioctl = qcam_ioctl,
.ioctl = video_ioctl2,
.read = qcam_read,
};
static struct video_device qcam_template = {
.name = "Connectix Quickcam",
.fops = &qcam_fops,
.release = video_device_release_empty,
static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
.vidioc_querycap = qcam_querycap,
.vidioc_g_input = qcam_g_input,
.vidioc_s_input = qcam_s_input,
.vidioc_enum_input = qcam_enum_input,
.vidioc_queryctrl = qcam_queryctrl,
.vidioc_g_ctrl = qcam_g_ctrl,
.vidioc_s_ctrl = qcam_s_ctrl,
.vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
};
#define MAX_CAMS 4
static struct qcam_device *qcams[MAX_CAMS];
static unsigned int num_cams;
/* Initialize the QuickCam driver control structure. This is where
* defaults are set for people who don't have a config file.*/
static struct qcam *qcam_init(struct parport *port)
{
struct qcam *qcam;
struct v4l2_device *v4l2_dev;
qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL);
if (qcam == NULL)
return NULL;
v4l2_dev = &qcam->v4l2_dev;
strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name));
if (v4l2_device_register(NULL, v4l2_dev) < 0) {
v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
return NULL;
}
qcam->pport = port;
qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
NULL, 0, NULL);
if (qcam->pdev == NULL) {
v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
kfree(qcam);
return NULL;
}
strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
qcam->vdev.v4l2_dev = v4l2_dev;
qcam->vdev.fops = &qcam_fops;
qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
qcam->vdev.release = video_device_release_empty;
video_set_drvdata(&qcam->vdev, qcam);
mutex_init(&qcam->lock);
qcam->port_mode = (QC_ANY | QC_NOTSET);
qcam->width = 320;
qcam->height = 240;
qcam->bpp = 4;
qcam->transfer_scale = 2;
qcam->contrast = 192;
qcam->brightness = 180;
qcam->whitebal = 105;
qcam->top = 1;
qcam->left = 14;
qcam->mode = -1;
qcam->status = QC_PARAM_CHANGE;
return qcam;
}
static int qc_calibrate(struct qcam *q)
{
/*
* Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
* The white balance is an individual value for each
* quickcam.
*/
int value;
int count = 0;
qc_command(q, 27); /* AutoAdjustOffset */
qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
/* GetOffset (33) will read 255 until autocalibration */
/* is finished. After that, a value of 1-254 will be */
/* returned. */
do {
qc_command(q, 33);
value = qc_readparam(q);
mdelay(1);
schedule();
count++;
} while (value == 0xff && count < 2048);
q->whitebal = value;
return value;
}
static int init_bwqcam(struct parport *port)
{
struct qcam_device *qcam;
struct qcam *qcam;
if (num_cams == MAX_CAMS) {
printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
@ -919,7 +988,7 @@ static int init_bwqcam(struct parport *port)
parport_release(qcam->pdev);
printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name);
if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
parport_unregister_device(qcam->pdev);
@ -932,7 +1001,7 @@ static int init_bwqcam(struct parport *port)
return 0;
}
static void close_bwqcam(struct qcam_device *qcam)
static void close_bwqcam(struct qcam *qcam)
{
video_unregister_device(&qcam->vdev);
parport_unregister_device(qcam->pdev);
@ -983,7 +1052,7 @@ static void bwqcam_detach(struct parport *port)
{
int i;
for (i = 0; i < num_cams; i++) {
struct qcam_device *qcam = qcams[i];
struct qcam *qcam = qcams[i];
if (qcam && qcam->pdev->port == port) {
qcams[i] = NULL;
close_bwqcam(qcam);

Просмотреть файл

@ -1,69 +0,0 @@
/*
* Video4Linux bw-qcam driver
*
* Derived from code..
*/
/******************************************************************
Copyright (C) 1996 by Scott Laird
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
******************************************************************/
/* One from column A... */
#define QC_NOTSET 0
#define QC_UNIDIR 1
#define QC_BIDIR 2
#define QC_SERIAL 3
/* ... and one from column B */
#define QC_ANY 0x00
#define QC_FORCE_UNIDIR 0x10
#define QC_FORCE_BIDIR 0x20
#define QC_FORCE_SERIAL 0x30
/* in the port_mode member */
#define QC_MODE_MASK 0x07
#define QC_FORCE_MASK 0x70
#define MAX_HEIGHT 243
#define MAX_WIDTH 336
/* Bit fields for status flags */
#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
struct qcam_device {
struct video_device vdev;
struct pardevice *pdev;
struct parport *pport;
struct mutex lock;
int width, height;
int bpp;
int mode;
int contrast, brightness, whitebal;
int port_mode;
int transfer_scale;
int top, left;
int status;
unsigned int saved_bits;
unsigned long in_use;
};

Просмотреть файл

@ -33,15 +33,17 @@
#include <linux/mm.h>
#include <linux/parport.h>
#include <linux/sched.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
#include <linux/jiffies.h>
#include <linux/version.h>
#include <linux/videodev2.h>
#include <asm/uaccess.h>
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
struct qcam_device {
struct qcam {
struct v4l2_device v4l2_dev;
struct video_device vdev;
struct pardevice *pdev;
struct parport *pport;
@ -51,7 +53,6 @@ struct qcam_device {
int contrast, brightness, whitebal;
int top, left;
unsigned int bidirectional;
unsigned long in_use;
struct mutex lock;
};
@ -68,33 +69,45 @@ struct qcam_device {
#define QC_DECIMATION_2 2
#define QC_DECIMATION_4 4
#define BANNER "Colour QuickCam for Video4Linux v0.05"
#define BANNER "Colour QuickCam for Video4Linux v0.06"
static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
static int probe = 2;
static int force_rgb;
static int video_nr = -1;
static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
/* FIXME: parport=auto would never have worked, surely? --RR */
MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n"
"probe=<0|1|2> for camera detection method\n"
"force_rgb=<0|1> for RGB data format (default BGR)");
module_param_array(parport, int, NULL, 0);
module_param(probe, int, 0);
module_param(force_rgb, bool, 0);
module_param(video_nr, int, 0);
static struct qcam *qcams[MAX_CAMS];
static unsigned int num_cams;
static inline void qcam_set_ack(struct qcam *qcam, unsigned int i)
{
/* note: the QC specs refer to the PCAck pin by voltage, not
software level. PC ports have builtin inverters. */
parport_frob_control(qcam->pport, 8, i ? 8 : 0);
}
static inline unsigned int qcam_ready1(struct qcam_device *qcam)
static inline unsigned int qcam_ready1(struct qcam *qcam)
{
return (parport_read_status(qcam->pport) & 0x8) ? 1 : 0;
}
static inline unsigned int qcam_ready2(struct qcam_device *qcam)
static inline unsigned int qcam_ready2(struct qcam *qcam)
{
return (parport_read_data(qcam->pport) & 0x1) ? 1 : 0;
}
static unsigned int qcam_await_ready1(struct qcam_device *qcam,
int value)
static unsigned int qcam_await_ready1(struct qcam *qcam, int value)
{
struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
unsigned long oldjiffies = jiffies;
unsigned int i;
@ -112,14 +125,15 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam,
}
/* Probably somebody pulled the plug out. Not much we can do. */
printk(KERN_ERR "c-qcam: ready1 timeout (%d) %x %x\n", value,
v4l2_err(v4l2_dev, "ready1 timeout (%d) %x %x\n", value,
parport_read_status(qcam->pport),
parport_read_control(qcam->pport));
return 1;
}
static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
static unsigned int qcam_await_ready2(struct qcam *qcam, int value)
{
struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
unsigned long oldjiffies = jiffies;
unsigned int i;
@ -137,14 +151,14 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
}
/* Probably somebody pulled the plug out. Not much we can do. */
printk(KERN_ERR "c-qcam: ready2 timeout (%d) %x %x %x\n", value,
v4l2_err(v4l2_dev, "ready2 timeout (%d) %x %x %x\n", value,
parport_read_status(qcam->pport),
parport_read_control(qcam->pport),
parport_read_data(qcam->pport));
return 1;
}
static int qcam_read_data(struct qcam_device *qcam)
static int qcam_read_data(struct qcam *qcam)
{
unsigned int idata;
@ -159,21 +173,22 @@ static int qcam_read_data(struct qcam_device *qcam)
return idata;
}
static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
static int qcam_write_data(struct qcam *qcam, unsigned int data)
{
struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
unsigned int idata;
parport_write_data(qcam->pport, data);
idata = qcam_read_data(qcam);
if (data != idata) {
printk(KERN_WARNING "cqcam: sent %x but received %x\n", data,
v4l2_warn(v4l2_dev, "sent %x but received %x\n", data,
idata);
return 1;
}
return 0;
}
static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data)
static inline int qcam_set(struct qcam *qcam, unsigned int cmd, unsigned int data)
{
if (qcam_write_data(qcam, cmd))
return -1;
@ -182,14 +197,14 @@ static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned
return 0;
}
static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd)
static inline int qcam_get(struct qcam *qcam, unsigned int cmd)
{
if (qcam_write_data(qcam, cmd))
return -1;
return qcam_read_data(qcam);
}
static int qc_detect(struct qcam_device *qcam)
static int qc_detect(struct qcam *qcam)
{
unsigned int stat, ostat, i, count = 0;
@ -246,7 +261,7 @@ static int qc_detect(struct qcam_device *qcam)
return 0;
}
static void qc_reset(struct qcam_device *qcam)
static void qc_reset(struct qcam *qcam)
{
parport_write_control(qcam->pport, 0xc);
parport_write_control(qcam->pport, 0x8);
@ -258,55 +273,55 @@ static void qc_reset(struct qcam_device *qcam)
/* Reset the QuickCam and program for brightness, contrast,
* white-balance, and resolution. */
static void qc_setup(struct qcam_device *q)
static void qc_setup(struct qcam *qcam)
{
qc_reset(q);
qc_reset(qcam);
/* Set the brightness. */
qcam_set(q, 11, q->brightness);
qcam_set(qcam, 11, qcam->brightness);
/* Set the height and width. These refer to the actual
CCD area *before* applying the selected decimation. */
qcam_set(q, 17, q->ccd_height);
qcam_set(q, 19, q->ccd_width / 2);
qcam_set(qcam, 17, qcam->ccd_height);
qcam_set(qcam, 19, qcam->ccd_width / 2);
/* Set top and left. */
qcam_set(q, 0xd, q->top);
qcam_set(q, 0xf, q->left);
qcam_set(qcam, 0xd, qcam->top);
qcam_set(qcam, 0xf, qcam->left);
/* Set contrast and white balance. */
qcam_set(q, 0x19, q->contrast);
qcam_set(q, 0x1f, q->whitebal);
qcam_set(qcam, 0x19, qcam->contrast);
qcam_set(qcam, 0x1f, qcam->whitebal);
/* Set the speed. */
qcam_set(q, 45, 2);
qcam_set(qcam, 45, 2);
}
/* Read some bytes from the camera and put them in the buffer.
nbytes should be a multiple of 3, because bidirectional mode gives
us three bytes at a time. */
static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes)
static unsigned int qcam_read_bytes(struct qcam *qcam, unsigned char *buf, unsigned int nbytes)
{
unsigned int bytes = 0;
qcam_set_ack(q, 0);
if (q->bidirectional) {
qcam_set_ack(qcam, 0);
if (qcam->bidirectional) {
/* It's a bidirectional port */
while (bytes < nbytes) {
unsigned int lo1, hi1, lo2, hi2;
unsigned char r, g, b;
if (qcam_await_ready2(q, 1))
if (qcam_await_ready2(qcam, 1))
return bytes;
lo1 = parport_read_data(q->pport) >> 1;
hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
qcam_set_ack(q, 1);
if (qcam_await_ready2(q, 0))
lo1 = parport_read_data(qcam->pport) >> 1;
hi1 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
qcam_set_ack(qcam, 1);
if (qcam_await_ready2(qcam, 0))
return bytes;
lo2 = parport_read_data(q->pport) >> 1;
hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
qcam_set_ack(q, 0);
lo2 = parport_read_data(qcam->pport) >> 1;
hi2 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
qcam_set_ack(qcam, 0);
r = lo1 | ((hi1 & 1) << 7);
g = ((hi1 & 0x1e) << 3) | ((hi2 & 0x1e) >> 1);
b = lo2 | ((hi2 & 1) << 7);
@ -328,14 +343,14 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, u
while (bytes < nbytes) {
unsigned int hi, lo;
if (qcam_await_ready1(q, 1))
if (qcam_await_ready1(qcam, 1))
return bytes;
hi = (parport_read_status(q->pport) & 0xf0);
qcam_set_ack(q, 1);
if (qcam_await_ready1(q, 0))
hi = (parport_read_status(qcam->pport) & 0xf0);
qcam_set_ack(qcam, 1);
if (qcam_await_ready1(qcam, 0))
return bytes;
lo = (parport_read_status(q->pport) & 0xf0);
qcam_set_ack(q, 0);
lo = (parport_read_status(qcam->pport) & 0xf0);
qcam_set_ack(qcam, 0);
/* flip some bits */
rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
if (i >= 2) {
@ -361,10 +376,11 @@ get_fragment:
#define BUFSZ 150
static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len)
static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len)
{
struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
unsigned lines, pixelsperline, bitsperxfer;
unsigned int is_bi_dir = q->bidirectional;
unsigned int is_bi_dir = qcam->bidirectional;
size_t wantlen, outptr = 0;
char tmpbuf[BUFSZ];
@ -373,10 +389,10 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
/* Wait for camera to become ready */
for (;;) {
int i = qcam_get(q, 41);
int i = qcam_get(qcam, 41);
if (i == -1) {
qc_setup(q);
qc_setup(qcam);
return -EIO;
}
if ((i & 0x80) == 0)
@ -384,25 +400,25 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
schedule();
}
if (qcam_set(q, 7, (q->mode | (is_bi_dir ? 1 : 0)) + 1))
if (qcam_set(qcam, 7, (qcam->mode | (is_bi_dir ? 1 : 0)) + 1))
return -EIO;
lines = q->height;
pixelsperline = q->width;
lines = qcam->height;
pixelsperline = qcam->width;
bitsperxfer = (is_bi_dir) ? 24 : 8;
if (is_bi_dir) {
/* Turn the port around */
parport_data_reverse(q->pport);
parport_data_reverse(qcam->pport);
mdelay(3);
qcam_set_ack(q, 0);
if (qcam_await_ready1(q, 1)) {
qc_setup(q);
qcam_set_ack(qcam, 0);
if (qcam_await_ready1(qcam, 1)) {
qc_setup(qcam);
return -EIO;
}
qcam_set_ack(q, 1);
if (qcam_await_ready1(q, 0)) {
qc_setup(q);
qcam_set_ack(qcam, 1);
if (qcam_await_ready1(qcam, 0)) {
qc_setup(qcam);
return -EIO;
}
}
@ -413,7 +429,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
size_t t, s;
s = (wantlen > BUFSZ) ? BUFSZ : wantlen;
t = qcam_read_bytes(q, tmpbuf, s);
t = qcam_read_bytes(qcam, tmpbuf, s);
if (outptr < len) {
size_t sz = len - outptr;
@ -432,10 +448,10 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
len = outptr;
if (wantlen) {
printk(KERN_ERR "qcam: short read.\n");
v4l2_err(v4l2_dev, "short read.\n");
if (is_bi_dir)
parport_data_forward(q->pport);
qc_setup(q);
parport_data_forward(qcam->pport);
qc_setup(qcam);
return len;
}
@ -443,49 +459,49 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
int l;
do {
l = qcam_read_bytes(q, tmpbuf, 3);
l = qcam_read_bytes(qcam, tmpbuf, 3);
cond_resched();
} while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
if (force_rgb) {
if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
printk(KERN_ERR "qcam: bad EOF\n");
v4l2_err(v4l2_dev, "bad EOF\n");
} else {
if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
printk(KERN_ERR "qcam: bad EOF\n");
v4l2_err(v4l2_dev, "bad EOF\n");
}
qcam_set_ack(q, 0);
if (qcam_await_ready1(q, 1)) {
printk(KERN_ERR "qcam: no ack after EOF\n");
parport_data_forward(q->pport);
qc_setup(q);
qcam_set_ack(qcam, 0);
if (qcam_await_ready1(qcam, 1)) {
v4l2_err(v4l2_dev, "no ack after EOF\n");
parport_data_forward(qcam->pport);
qc_setup(qcam);
return len;
}
parport_data_forward(q->pport);
parport_data_forward(qcam->pport);
mdelay(3);
qcam_set_ack(q, 1);
if (qcam_await_ready1(q, 0)) {
printk(KERN_ERR "qcam: no ack to port turnaround\n");
qc_setup(q);
qcam_set_ack(qcam, 1);
if (qcam_await_ready1(qcam, 0)) {
v4l2_err(v4l2_dev, "no ack to port turnaround\n");
qc_setup(qcam);
return len;
}
} else {
int l;
do {
l = qcam_read_bytes(q, tmpbuf, 1);
l = qcam_read_bytes(qcam, tmpbuf, 1);
cond_resched();
} while (l && tmpbuf[0] == 0x7e);
l = qcam_read_bytes(q, tmpbuf + 1, 2);
l = qcam_read_bytes(qcam, tmpbuf + 1, 2);
if (force_rgb) {
if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
printk(KERN_ERR "qcam: bad EOF\n");
v4l2_err(v4l2_dev, "bad EOF\n");
} else {
if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
printk(KERN_ERR "qcam: bad EOF\n");
v4l2_err(v4l2_dev, "bad EOF\n");
}
}
qcam_write_data(q, 0);
qcam_write_data(qcam, 0);
return len;
}
@ -493,184 +509,202 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
* Video4linux interfacing
*/
static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
static int qcam_querycap(struct file *file, void *priv,
struct v4l2_capability *vcap)
{
struct video_device *dev = video_devdata(file);
struct qcam_device *qcam = (struct qcam_device *)dev;
struct qcam *qcam = video_drvdata(file);
switch (cmd) {
case VIDIOCGCAP:
{
struct video_capability *b = arg;
strcpy(b->name, "Quickcam");
b->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
b->channels = 1;
b->audios = 0;
b->maxwidth = 320;
b->maxheight = 240;
b->minwidth = 80;
b->minheight = 60;
return 0;
}
case VIDIOCGCHAN:
{
struct video_channel *v = arg;
if (v->channel != 0)
return -EINVAL;
v->flags = 0;
v->tuners = 0;
/* Good question.. its composite or SVHS so.. */
v->type = VIDEO_TYPE_CAMERA;
strcpy(v->name, "Camera");
return 0;
}
case VIDIOCSCHAN:
{
struct video_channel *v = arg;
if (v->channel != 0)
return -EINVAL;
return 0;
}
case VIDIOCGTUNER:
{
struct video_tuner *v = arg;
if (v->tuner)
return -EINVAL;
memset(v, 0, sizeof(*v));
strcpy(v->name, "Format");
v->mode = VIDEO_MODE_AUTO;
return 0;
}
case VIDIOCSTUNER:
{
struct video_tuner *v = arg;
if (v->tuner)
return -EINVAL;
if (v->mode != VIDEO_MODE_AUTO)
return -EINVAL;
return 0;
}
case VIDIOCGPICT:
{
struct video_picture *p = arg;
p->colour = 0x8000;
p->hue = 0x8000;
p->brightness = qcam->brightness << 8;
p->contrast = qcam->contrast << 8;
p->whiteness = qcam->whitebal << 8;
p->depth = 24;
p->palette = VIDEO_PALETTE_RGB24;
return 0;
}
case VIDIOCSPICT:
{
struct video_picture *p = arg;
/*
* Sanity check args
*/
if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
return -EINVAL;
/*
* Now load the camera.
*/
qcam->brightness = p->brightness >> 8;
qcam->contrast = p->contrast >> 8;
qcam->whitebal = p->whiteness >> 8;
mutex_lock(&qcam->lock);
parport_claim_or_block(qcam->pdev);
qc_setup(qcam);
parport_release(qcam->pdev);
mutex_unlock(&qcam->lock);
return 0;
}
case VIDIOCSWIN:
{
struct video_window *vw = arg;
if (vw->flags)
return -EINVAL;
if (vw->clipcount)
return -EINVAL;
if (vw->height < 60 || vw->height > 240)
return -EINVAL;
if (vw->width < 80 || vw->width > 320)
return -EINVAL;
qcam->width = 80;
qcam->height = 60;
qcam->mode = QC_DECIMATION_4;
if (vw->width >= 160 && vw->height >= 120) {
qcam->width = 160;
qcam->height = 120;
qcam->mode = QC_DECIMATION_2;
}
if (vw->width >= 320 && vw->height >= 240) {
qcam->width = 320;
qcam->height = 240;
qcam->mode = QC_DECIMATION_1;
}
qcam->mode |= QC_MILLIONS;
#if 0
if (vw->width >= 640 && vw->height >= 480) {
qcam->width = 640;
qcam->height = 480;
qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
}
#endif
/* Ok we figured out what to use from our
wide choice */
mutex_lock(&qcam->lock);
parport_claim_or_block(qcam->pdev);
qc_setup(qcam);
parport_release(qcam->pdev);
mutex_unlock(&qcam->lock);
return 0;
}
case VIDIOCGWIN:
{
struct video_window *vw = arg;
memset(vw, 0, sizeof(*vw));
vw->width = qcam->width;
vw->height = qcam->height;
return 0;
}
case VIDIOCKEY:
return 0;
case VIDIOCCAPTURE:
case VIDIOCGFBUF:
case VIDIOCSFBUF:
case VIDIOCGFREQ:
case VIDIOCSFREQ:
case VIDIOCGAUDIO:
case VIDIOCSAUDIO:
return -EINVAL;
default:
return -ENOIOCTLCMD;
}
strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
strlcpy(vcap->card, "Color Quickcam", sizeof(vcap->card));
strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
vcap->version = KERNEL_VERSION(0, 0, 3);
vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
return 0;
}
static long qcam_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
{
return video_usercopy(file, cmd, arg, qcam_do_ioctl);
if (vin->index > 0)
return -EINVAL;
strlcpy(vin->name, "Camera", sizeof(vin->name));
vin->type = V4L2_INPUT_TYPE_CAMERA;
vin->audioset = 0;
vin->tuner = 0;
vin->std = 0;
vin->status = 0;
return 0;
}
static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
{
*inp = 0;
return 0;
}
static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
{
return (inp > 0) ? -EINVAL : 0;
}
static int qcam_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 240);
case V4L2_CID_CONTRAST:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
case V4L2_CID_GAMMA:
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
}
return -EINVAL;
}
static int qcam_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct qcam *qcam = video_drvdata(file);
int ret = 0;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->value = qcam->brightness;
break;
case V4L2_CID_CONTRAST:
ctrl->value = qcam->contrast;
break;
case V4L2_CID_GAMMA:
ctrl->value = qcam->whitebal;
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static int qcam_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct qcam *qcam = video_drvdata(file);
int ret = 0;
mutex_lock(&qcam->lock);
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
qcam->brightness = ctrl->value;
break;
case V4L2_CID_CONTRAST:
qcam->contrast = ctrl->value;
break;
case V4L2_CID_GAMMA:
qcam->whitebal = ctrl->value;
break;
default:
ret = -EINVAL;
break;
}
if (ret == 0) {
parport_claim_or_block(qcam->pdev);
qc_setup(qcam);
parport_release(qcam->pdev);
}
mutex_unlock(&qcam->lock);
return ret;
}
static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct qcam *qcam = video_drvdata(file);
struct v4l2_pix_format *pix = &fmt->fmt.pix;
pix->width = qcam->width;
pix->height = qcam->height;
pix->pixelformat = V4L2_PIX_FMT_RGB24;
pix->field = V4L2_FIELD_NONE;
pix->bytesperline = 3 * qcam->width;
pix->sizeimage = 3 * qcam->width * qcam->height;
/* Just a guess */
pix->colorspace = V4L2_COLORSPACE_SRGB;
return 0;
}
static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct v4l2_pix_format *pix = &fmt->fmt.pix;
if (pix->height < 60 || pix->width < 80) {
pix->height = 60;
pix->width = 80;
} else if (pix->height < 120 || pix->width < 160) {
pix->height = 120;
pix->width = 160;
} else {
pix->height = 240;
pix->width = 320;
}
pix->pixelformat = V4L2_PIX_FMT_RGB24;
pix->field = V4L2_FIELD_NONE;
pix->bytesperline = 3 * pix->width;
pix->sizeimage = 3 * pix->width * pix->height;
/* Just a guess */
pix->colorspace = V4L2_COLORSPACE_SRGB;
return 0;
}
static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct qcam *qcam = video_drvdata(file);
struct v4l2_pix_format *pix = &fmt->fmt.pix;
int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
if (ret)
return ret;
switch (pix->height) {
case 60:
qcam->mode = QC_DECIMATION_4;
break;
case 120:
qcam->mode = QC_DECIMATION_2;
break;
default:
qcam->mode = QC_DECIMATION_1;
break;
}
mutex_lock(&qcam->lock);
qcam->mode |= QC_MILLIONS;
qcam->height = pix->height;
qcam->width = pix->width;
parport_claim_or_block(qcam->pdev);
qc_setup(qcam);
parport_release(qcam->pdev);
mutex_unlock(&qcam->lock);
return 0;
}
static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
{
static struct v4l2_fmtdesc formats[] = {
{ 0, 0, 0,
"RGB 8:8:8", V4L2_PIX_FMT_RGB24,
{ 0, 0, 0, 0 }
},
};
enum v4l2_buf_type type = fmt->type;
if (fmt->index > 0)
return -EINVAL;
*fmt = formats[fmt->index];
fmt->type = type;
return 0;
}
static ssize_t qcam_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct video_device *v = video_devdata(file);
struct qcam_device *qcam = (struct qcam_device *)v;
struct qcam *qcam = video_drvdata(file);
int len;
mutex_lock(&qcam->lock);
@ -682,81 +716,80 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
return len;
}
static int qcam_exclusive_open(struct file *file)
{
struct video_device *dev = video_devdata(file);
struct qcam_device *qcam = (struct qcam_device *)dev;
return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0;
}
static int qcam_exclusive_release(struct file *file)
{
struct video_device *dev = video_devdata(file);
struct qcam_device *qcam = (struct qcam_device *)dev;
clear_bit(0, &qcam->in_use);
return 0;
}
/* video device template */
static const struct v4l2_file_operations qcam_fops = {
.owner = THIS_MODULE,
.open = qcam_exclusive_open,
.release = qcam_exclusive_release,
.ioctl = qcam_ioctl,
.ioctl = video_ioctl2,
.read = qcam_read,
};
static struct video_device qcam_template = {
.name = "Colour QuickCam",
.fops = &qcam_fops,
.release = video_device_release_empty,
static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
.vidioc_querycap = qcam_querycap,
.vidioc_g_input = qcam_g_input,
.vidioc_s_input = qcam_s_input,
.vidioc_enum_input = qcam_enum_input,
.vidioc_queryctrl = qcam_queryctrl,
.vidioc_g_ctrl = qcam_g_ctrl,
.vidioc_s_ctrl = qcam_s_ctrl,
.vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
};
/* Initialize the QuickCam driver control structure. */
static struct qcam_device *qcam_init(struct parport *port)
static struct qcam *qcam_init(struct parport *port)
{
struct qcam_device *q;
struct qcam *qcam;
struct v4l2_device *v4l2_dev;
q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
if (q == NULL)
qcam = kzalloc(sizeof(*qcam), GFP_KERNEL);
if (qcam == NULL)
return NULL;
q->pport = port;
q->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
NULL, 0, NULL);
v4l2_dev = &qcam->v4l2_dev;
strlcpy(v4l2_dev->name, "c-qcam", sizeof(v4l2_dev->name));
q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0;
if (q->pdev == NULL) {
printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
port->name);
kfree(q);
if (v4l2_device_register(NULL, v4l2_dev) < 0) {
v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
return NULL;
}
memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
qcam->pport = port;
qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
NULL, 0, NULL);
mutex_init(&q->lock);
q->width = q->ccd_width = 320;
q->height = q->ccd_height = 240;
q->mode = QC_MILLIONS | QC_DECIMATION_1;
q->contrast = 192;
q->brightness = 240;
q->whitebal = 128;
q->top = 1;
q->left = 14;
return q;
qcam->bidirectional = (qcam->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0;
if (qcam->pdev == NULL) {
v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
kfree(qcam);
return NULL;
}
strlcpy(qcam->vdev.name, "Colour QuickCam", sizeof(qcam->vdev.name));
qcam->vdev.v4l2_dev = v4l2_dev;
qcam->vdev.fops = &qcam_fops;
qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
qcam->vdev.release = video_device_release_empty;
video_set_drvdata(&qcam->vdev, qcam);
mutex_init(&qcam->lock);
qcam->width = qcam->ccd_width = 320;
qcam->height = qcam->ccd_height = 240;
qcam->mode = QC_MILLIONS | QC_DECIMATION_1;
qcam->contrast = 192;
qcam->brightness = 240;
qcam->whitebal = 128;
qcam->top = 1;
qcam->left = 14;
return qcam;
}
static struct qcam_device *qcams[MAX_CAMS];
static unsigned int num_cams;
static int init_cqcam(struct parport *port)
{
struct qcam_device *qcam;
struct qcam *qcam;
struct v4l2_device *v4l2_dev;
if (parport[0] != -1) {
/* The user gave specific instructions */
@ -777,6 +810,8 @@ static int init_cqcam(struct parport *port)
if (qcam == NULL)
return -ENODEV;
v4l2_dev = &qcam->v4l2_dev;
parport_claim_or_block(qcam->pdev);
qc_reset(qcam);
@ -793,14 +828,14 @@ static int init_cqcam(struct parport *port)
parport_release(qcam->pdev);
if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
v4l2_err(v4l2_dev, "Unable to register Colour QuickCam on %s\n",
qcam->pport->name);
parport_unregister_device(qcam->pdev);
kfree(qcam);
return -ENODEV;
}
printk(KERN_INFO "%s: Colour QuickCam found on %s\n",
v4l2_info(v4l2_dev, "%s: Colour QuickCam found on %s\n",
video_device_node_name(&qcam->vdev), qcam->pport->name);
qcams[num_cams++] = qcam;
@ -808,7 +843,7 @@ static int init_cqcam(struct parport *port)
return 0;
}
static void close_cqcam(struct qcam_device *qcam)
static void close_cqcam(struct qcam *qcam)
{
video_unregister_device(&qcam->vdev);
parport_unregister_device(qcam->pdev);
@ -833,7 +868,7 @@ static struct parport_driver cqcam_driver = {
static int __init cqcam_init(void)
{
printk(BANNER "\n");
printk(KERN_INFO BANNER "\n");
return parport_register_driver(&cqcam_driver);
}
@ -852,14 +887,5 @@ MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
MODULE_DESCRIPTION(BANNER);
MODULE_LICENSE("GPL");
/* FIXME: parport=auto would never have worked, surely? --RR */
MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n"
"probe=<0|1|2> for camera detection method\n"
"force_rgb=<0|1> for RGB data format (default BGR)");
module_param_array(parport, int, NULL, 0);
module_param(probe, int, 0);
module_param(force_rgb, bool, 0);
module_param(video_nr, int, 0);
module_init(cqcam_init);
module_exit(cqcam_cleanup);

Просмотреть файл

@ -1,7 +1,7 @@
/*
* ALSA interface to cx18 PCM capture streams
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
* Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
*
* Portions of this work were sponsored by ONELAN Limited.

Просмотреть файл

@ -2,7 +2,7 @@
* ALSA mixer controls for the
* ALSA interface to cx18 PCM capture streams
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* ALSA mixer controls for the
* ALSA interface to cx18 PCM capture streams
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* ALSA PCM device for the
* ALSA interface to cx18 PCM capture streams
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
* Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
*
* Portions of this work were sponsored by ONELAN Limited.

Просмотреть файл

@ -2,7 +2,7 @@
* ALSA PCM device for the
* ALSA interface to cx18 PCM capture streams
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -1,7 +1,7 @@
/*
* ALSA interface to cx18 PCM capture streams
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from cx25840-audio.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from cx25840-core.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -1021,86 +1021,74 @@ static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return -EINVAL;
}
static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
return -EINVAL;
return cx18_av_g_sliced_fmt(sd, &fmt->fmt.sliced);
}
static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
{
struct cx18_av_state *state = to_cx18_av_state(sd);
struct cx18 *cx = v4l2_get_subdevdata(sd);
struct v4l2_pix_format *pix;
int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
int is_50Hz = !(state->std & V4L2_STD_525_60);
switch (fmt->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
pix = &(fmt->fmt.pix);
Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
/*
* This adjustment reflects the excess of vactive, set in
* cx18_av_std_setup(), above standard values:
*
* 480 + 1 for 60 Hz systems
* 576 + 3 for 50 Hz systems
*/
Vlines = pix->height + (is_50Hz ? 3 : 1);
/*
* Invalid height and width scaling requests are:
* 1. width less than 1/16 of the source width
* 2. width greater than the source width
* 3. height less than 1/8 of the source height
* 4. height greater than the source height
*/
if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
pix->width, pix->height);
return -ERANGE;
}
HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
VSC &= 0x1fff;
if (pix->width >= 385)
filter = 0;
else if (pix->width > 192)
filter = 1;
else if (pix->width > 96)
filter = 2;
else
filter = 3;
CX18_DEBUG_INFO_DEV(sd,
"decoder set size %dx%d -> scale %ux%u\n",
pix->width, pix->height, HSC, VSC);
/* HSCALE=HSC */
cx18_av_write(cx, 0x418, HSC & 0xff);
cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
cx18_av_write(cx, 0x41a, HSC >> 16);
/* VSCALE=VSC */
cx18_av_write(cx, 0x41c, VSC & 0xff);
cx18_av_write(cx, 0x41d, VSC >> 8);
/* VS_INTRLACE=1 VFILT=filter */
cx18_av_write(cx, 0x41e, 0x8 | filter);
break;
default:
if (fmt->code != V4L2_MBUS_FMT_FIXED)
return -EINVAL;
fmt->field = V4L2_FIELD_INTERLACED;
fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
/*
* This adjustment reflects the excess of vactive, set in
* cx18_av_std_setup(), above standard values:
*
* 480 + 1 for 60 Hz systems
* 576 + 3 for 50 Hz systems
*/
Vlines = fmt->height + (is_50Hz ? 3 : 1);
/*
* Invalid height and width scaling requests are:
* 1. width less than 1/16 of the source width
* 2. width greater than the source width
* 3. height less than 1/8 of the source height
* 4. height greater than the source height
*/
if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
fmt->width, fmt->height);
return -ERANGE;
}
HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20);
VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
VSC &= 0x1fff;
if (fmt->width >= 385)
filter = 0;
else if (fmt->width > 192)
filter = 1;
else if (fmt->width > 96)
filter = 2;
else
filter = 3;
CX18_DEBUG_INFO_DEV(sd,
"decoder set size %dx%d -> scale %ux%u\n",
fmt->width, fmt->height, HSC, VSC);
/* HSCALE=HSC */
cx18_av_write(cx, 0x418, HSC & 0xff);
cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
cx18_av_write(cx, 0x41a, HSC >> 16);
/* VSCALE=VSC */
cx18_av_write(cx, 0x41c, VSC & 0xff);
cx18_av_write(cx, 0x41d, VSC >> 8);
/* VS_INTRLACE=1 VFILT=filter */
cx18_av_write(cx, 0x41e, 0x8 | filter);
return 0;
}
@ -1398,8 +1386,7 @@ static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
.s_routing = cx18_av_s_video_routing,
.s_stream = cx18_av_s_stream,
.g_fmt = cx18_av_g_fmt,
.s_fmt = cx18_av_s_fmt,
.s_mbus_fmt = cx18_av_s_mbus_fmt,
};
static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = {

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from cx25840-core.h
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 ADEC firmware functions
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-cards.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-cards.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -297,14 +297,13 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
if (p.video_encoding != cx->params.video_encoding) {
int is_mpeg1 = p.video_encoding ==
V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
struct v4l2_format fmt;
struct v4l2_mbus_framefmt fmt;
/* fix videodecoder resolution */
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = cx->params.width
/ (is_mpeg1 ? 2 : 1);
fmt.fmt.pix.height = cx->params.height;
v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt);
fmt.width = cx->params.width / (is_mpeg1 ? 2 : 1);
fmt.height = cx->params.height;
fmt.code = V4L2_MBUS_FMT_FIXED;
v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt);
}
priv.cx = cx;
priv.s = &cx->streams[id->type];

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-driver.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-driver.h
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 functions for DVB support
*
* Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-fileops.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 firmware functions
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-gpio.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-gpio.h
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-i2c.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 driver PCI memory mapped IO access routines
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 driver PCI memory mapped IO access routines
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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
@ -28,7 +28,7 @@
/*
* Readback and retry of MMIO access for reliability:
* The concept was suggested by Steve Toth <stoth@linuxtv.org>.
* The implmentation is the fault of Andy Walls <awalls@radix.net>.
* The implmentation is the fault of Andy Walls <awalls@md.metrocast.net>.
*
* *write* functions are implied to retry the mmio unless suffixed with _noretry
* *read* functions never retry the mmio (it never helps to do so)

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-ioctl.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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
@ -274,6 +274,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
{
struct cx18_open_id *id = fh;
struct cx18 *cx = id->cx;
struct v4l2_mbus_framefmt mbus_fmt;
int ret;
int w, h;
@ -293,9 +294,10 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
if (atomic_read(&cx->ana_capturing) > 0)
return -EBUSY;
cx->params.width = w;
cx->params.height = h;
v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
mbus_fmt.width = cx->params.width = w;
mbus_fmt.height = cx->params.height = h;
mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
return cx18_g_fmt_vid_cap(file, fh, fmt);
}

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-ioctl.h
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 interrupt handling
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 interrupt handling
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 mailbox functions
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 mailbox functions
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-queue.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-queue.h
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 System Control Block initialization
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -2,7 +2,7 @@
* cx18 System Control Block initialization
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-streams.c
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -4,7 +4,7 @@
* Derived from ivtv-streams.h
*
* Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
* Copyright (C) 2008 Andy Walls <awalls@radix.net>
* Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -993,6 +993,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct cx231xx *dev = fh->dev;
int rc;
struct cx231xx_fmt *fmt;
struct v4l2_mbus_framefmt mbus_fmt;
rc = check_dev(dev);
if (rc < 0)
@ -1026,7 +1027,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
dev->format = fmt;
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
call_all(dev, video, s_fmt, f);
v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
call_all(dev, video, s_mbus_fmt, &mbus_fmt);
v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
/* Set the correct alternate setting for this resolution */
cx231xx_resolution_set(dev);

Просмотреть файл

@ -1113,7 +1113,6 @@ invalid:
void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
{
int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
int temporal = p->video_temporal_filter;
/* Stream */
printk(KERN_INFO "%s: Stream: %s",
@ -1179,14 +1178,11 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
p->video_spatial_filter);
if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480))
temporal = 0;
printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
prefix,
cx2341x_menu_item(p,
V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
temporal);
p->video_temporal_filter);
printk(KERN_INFO
"%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
prefix,

Просмотреть файл

@ -991,6 +991,8 @@ static int dvb_register(struct cx23885_tsport *port)
ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
&dev->pci->dev, adapter_nr, 0,
cx23885_dvb_fe_ioctl_override);
if (!ret)
return ret;
/* init CI & MAC */
switch (dev->board) {

Просмотреть файл

@ -365,7 +365,17 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
i2c_new_probed_device(&bus->i2c_adap, &info, addr_list);
/*
* We can't call i2c_new_probed_device() because it uses
* quick writes for probing and the IR receiver device only
* replies to reads.
*/
if (i2c_smbus_xfer(&bus->i2c_adap, addr_list[0], 0,
I2C_SMBUS_READ, 0, I2C_SMBUS_QUICK,
NULL) >= 0) {
info.addr = addr_list[0];
i2c_new_device(&bus->i2c_adap, &info);
}
}
return bus->i2c_rc;

Просмотреть файл

@ -5,7 +5,7 @@
*
* Most of this file is
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* However, the cx23885_input_{init,fini} functions contained herein are
* derived from Linux kernel files linux/media/video/.../...-input.c marked as:

Просмотреть файл

@ -3,7 +3,7 @@
*
* Infrared remote control input device
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

Просмотреть файл

@ -3,7 +3,7 @@
*
* Various common ioctl() support functions
*
* Copyright (c) 2009 Andy Walls <awalls@radix.net>
* Copyright (c) 2009 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -3,7 +3,7 @@
*
* Various common ioctl() support functions
*
* Copyright (c) 2009 Andy Walls <awalls@radix.net>
* Copyright (c) 2009 Andy Walls <awalls@md.metrocast.net>
*
* 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

Просмотреть файл

@ -3,7 +3,7 @@
*
* Infrared device support routines - non-input, non-vl42_subdev routines
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

Просмотреть файл

@ -3,7 +3,7 @@
*
* Infrared device support routines - non-input, non-vl42_subdev routines
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

Просмотреть файл

@ -976,6 +976,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
{
struct cx23885_fh *fh = priv;
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
struct v4l2_mbus_framefmt mbus_fmt;
int err;
dprintk(2, "%s()\n", __func__);
@ -989,7 +990,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
fh->vidq.field = f->fmt.pix.field;
dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
fh->width, fh->height, fh->vidq.field);
call_all(dev, video, s_fmt, f);
v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
call_all(dev, video, s_mbus_fmt, &mbus_fmt);
v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
return 0;
}

Просмотреть файл

@ -3,7 +3,7 @@
*
* CX23888 Integrated Consumer Infrared Controller
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

Просмотреть файл

@ -3,7 +3,7 @@
*
* CX23888 Integrated Consumer Infrared Controller
*
* Copyright (C) 2009 Andy Walls <awalls@radix.net>
* Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

Просмотреть файл

@ -1014,75 +1014,59 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
/* ----------------------------------------------------------------------- */
static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
switch (fmt->type) {
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
return cx25840_g_sliced_fmt(sd, &fmt->fmt.sliced);
default:
return -EINVAL;
}
return 0;
}
static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
{
struct cx25840_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct v4l2_pix_format *pix;
int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
int is_50Hz = !(state->std & V4L2_STD_525_60);
switch (fmt->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
pix = &(fmt->fmt.pix);
Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
Vlines = pix->height + (is_50Hz ? 4 : 7);
if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
v4l_err(client, "%dx%d is not a valid size!\n",
pix->width, pix->height);
return -ERANGE;
}
HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
VSC &= 0x1fff;
if (pix->width >= 385)
filter = 0;
else if (pix->width > 192)
filter = 1;
else if (pix->width > 96)
filter = 2;
else
filter = 3;
v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n",
pix->width, pix->height, HSC, VSC);
/* HSCALE=HSC */
cx25840_write(client, 0x418, HSC & 0xff);
cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
cx25840_write(client, 0x41a, HSC >> 16);
/* VSCALE=VSC */
cx25840_write(client, 0x41c, VSC & 0xff);
cx25840_write(client, 0x41d, VSC >> 8);
/* VS_INTRLACE=1 VFILT=filter */
cx25840_write(client, 0x41e, 0x8 | filter);
break;
default:
if (fmt->code != V4L2_MBUS_FMT_FIXED)
return -EINVAL;
fmt->field = V4L2_FIELD_INTERLACED;
fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
Vlines = fmt->height + (is_50Hz ? 4 : 7);
if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
v4l_err(client, "%dx%d is not a valid size!\n",
fmt->width, fmt->height);
return -ERANGE;
}
HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20);
VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
VSC &= 0x1fff;
if (fmt->width >= 385)
filter = 0;
else if (fmt->width > 192)
filter = 1;
else if (fmt->width > 96)
filter = 2;
else
filter = 3;
v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n",
fmt->width, fmt->height, HSC, VSC);
/* HSCALE=HSC */
cx25840_write(client, 0x418, HSC & 0xff);
cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
cx25840_write(client, 0x41a, HSC >> 16);
/* VSCALE=VSC */
cx25840_write(client, 0x41c, VSC & 0xff);
cx25840_write(client, 0x41d, VSC >> 8);
/* VS_INTRLACE=1 VFILT=filter */
cx25840_write(client, 0x41e, 0x8 | filter);
return 0;
}
@ -1627,8 +1611,7 @@ static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
static const struct v4l2_subdev_video_ops cx25840_video_ops = {
.s_routing = cx25840_s_video_routing,
.g_fmt = cx25840_g_fmt,
.s_fmt = cx25840_s_fmt,
.s_mbus_fmt = cx25840_s_mbus_fmt,
.s_stream = cx25840_s_stream,
};

Просмотреть файл

@ -188,10 +188,24 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
0x18, 0x6b, 0x71,
I2C_CLIENT_END
};
const unsigned short *addrp;
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
i2c_new_probed_device(&core->i2c_adap, &info, addr_list);
/*
* We can't call i2c_new_probed_device() because it uses
* quick writes for probing and at least some R receiver
* devices only reply to reads.
*/
for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) {
if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0,
I2C_SMBUS_READ, 0,
I2C_SMBUS_QUICK, NULL) >= 0) {
info.addr = *addrp;
i2c_new_device(&core->i2c_adap, &info);
break;
}
}
}
return core->i2c_rc;
}

Просмотреть файл

@ -1186,8 +1186,7 @@ int em28xx_register_extension(struct em28xx_ops *ops)
mutex_lock(&em28xx_devlist_mutex);
list_add_tail(&ops->next, &em28xx_extension_devlist);
list_for_each_entry(dev, &em28xx_devlist, devlist) {
if (dev)
ops->init(dev);
ops->init(dev);
}
printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
mutex_unlock(&em28xx_devlist_mutex);
@ -1201,10 +1200,8 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
mutex_lock(&em28xx_devlist_mutex);
list_for_each_entry(dev, &em28xx_devlist, devlist) {
if (dev)
ops->fini(dev);
ops->fini(dev);
}
printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
list_del(&ops->next);
mutex_unlock(&em28xx_devlist_mutex);

Просмотреть файл

@ -1453,9 +1453,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
{USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
{USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
#endif
{USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},

Просмотреть файл

@ -3022,16 +3022,18 @@ static const __devinitdata struct usb_device_id device_table[] = {
/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
{USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
{USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
/* {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, P1030xC)}, */
/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, * / GC0305*/
/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
{USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
{USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
@ -3058,6 +3060,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{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*/

Просмотреть файл

@ -366,7 +366,7 @@ static int hdpvr_open(struct file *file)
dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
if (!dev) {
v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n");
pr_err("open failing with with ENODEV\n");
retval = -ENODEV;
goto err;
}

Просмотреть файл

@ -267,13 +267,13 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
if (p.video_encoding != itv->params.video_encoding) {
int is_mpeg1 = p.video_encoding ==
V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
struct v4l2_format fmt;
struct v4l2_mbus_framefmt fmt;
/* fix videodecoder resolution */
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
fmt.fmt.pix.height = itv->params.height;
v4l2_subdev_call(itv->sd_video, video, s_fmt, &fmt);
fmt.width = itv->params.width / (is_mpeg1 ? 2 : 1);
fmt.height = itv->params.height;
fmt.code = V4L2_MBUS_FMT_FIXED;
v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt);
}
err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)

Просмотреть файл

@ -823,6 +823,12 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
IVTV_DEBUG_FILE("close() of %s\n", s->name);
if (id->type == IVTV_DEC_STREAM_TYPE_YUV &&
test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) {
/* Restore registers we've changed & clean up any mess */
ivtv_yuv_close(itv);
}
/* Stop decoding */
if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
IVTV_DEBUG_INFO("close stopping decode\n");
@ -832,10 +838,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
}
clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
if (id->type == IVTV_DEC_STREAM_TYPE_YUV && test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) {
/* Restore registers we've changed & clean up any mess we've made */
ivtv_yuv_close(itv);
}
if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames)
itv->output_mode = OUT_NONE;

Просмотреть файл

@ -569,6 +569,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
struct ivtv_open_id *id = fh;
struct ivtv *itv = id->itv;
struct cx2341x_mpeg_params *p = &itv->params;
struct v4l2_mbus_framefmt mbus_fmt;
int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
@ -586,7 +587,10 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
p->height = h;
if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
fmt->fmt.pix.width /= 2;
v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
mbus_fmt.width = fmt->fmt.pix.width;
mbus_fmt.height = h;
mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
return ivtv_g_fmt_vid_cap(file, fh, fmt);
}

Просмотреть файл

@ -618,12 +618,17 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
struct ivtv *itv = s->itv;
struct cx2341x_mpeg_params *p = &itv->params;
int datatype;
u16 width;
u16 height;
if (s->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
width = p->width;
height = p->height;
/* set audio mode to left/stereo for dual/stereo mode. */
ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
@ -646,7 +651,14 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
2 = yuv_from_host */
switch (s->type) {
case IVTV_DEC_STREAM_TYPE_YUV:
datatype = itv->output_mode == OUT_PASSTHROUGH ? 1 : 2;
if (itv->output_mode == OUT_PASSTHROUGH) {
datatype = 1;
} else {
/* Fake size to avoid switching video standard */
datatype = 2;
width = 720;
height = itv->is_out_50hz ? 576 : 480;
}
IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype);
break;
case IVTV_DEC_STREAM_TYPE_MPG:
@ -655,9 +667,13 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
break;
}
if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
p->width, p->height, p->audio_properties)) {
width, height, p->audio_properties)) {
IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
}
/* Decoder sometimes dies here, so wait a moment */
ivtv_msleep_timeout(10, 0);
return 0;
}
@ -697,6 +713,9 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
/* start playback */
ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0);
/* Let things settle before we actually start */
ivtv_msleep_timeout(10, 0);
/* Clear the following Interrupt mask bits for decoding */
ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask);

Просмотреть файл

@ -1066,7 +1066,11 @@ static int ivtvfb_init_io(struct ivtv *itv)
}
mutex_unlock(&itv->serialize_lock);
ivtvfb_get_framebuffer(itv, &oi->video_rbase, &oi->video_buffer_size);
if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
&oi->video_buffer_size) < 0) {
IVTVFB_ERR("Firmware failed to respond\n");
return -EIO;
}
/* The osd buffer size depends on the number of video buffers allocated
on the PVR350 itself. For now we'll hardcode the smallest osd buffer
@ -1158,8 +1162,11 @@ static int ivtvfb_init_card(struct ivtv *itv)
}
/* Find & setup the OSD buffer */
if ((rc = ivtvfb_init_io(itv)))
rc = ivtvfb_init_io(itv);
if (rc) {
ivtvfb_release_buffers(itv);
return rc;
}
/* Set the startup video mode information */
if ((rc = ivtvfb_init_vidmode(itv))) {
@ -1210,6 +1217,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p)
{
struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
struct osd_info *oi = itv->osd_info;
if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
@ -1218,7 +1226,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p)
return 0;
}
IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info);
ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
ivtvfb_release_buffers(itv);
itv->osd_video_pbase = 0;
}

Просмотреть файл

@ -701,13 +701,13 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
#endif
};
static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index,
static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code)
{
struct i2c_client *client = sd->priv;
struct mt9m001 *mt9m001 = to_mt9m001(client);
if ((unsigned int)index >= mt9m001->num_fmts)
if (index >= mt9m001->num_fmts)
return -EINVAL;
*code = mt9m001->fmts[index].code;

Просмотреть файл

@ -999,10 +999,10 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
#endif
};
static int mt9m111_enum_fmt(struct v4l2_subdev *sd, int index,
static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code)
{
if ((unsigned int)index >= ARRAY_SIZE(mt9m111_colour_fmts))
if (index >= ARRAY_SIZE(mt9m111_colour_fmts))
return -EINVAL;
*code = mt9m111_colour_fmts[index].code;

Просмотреть файл

@ -798,7 +798,7 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
#endif
};
static int mt9t031_enum_fmt(struct v4l2_subdev *sd, int index,
static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code)
{
if (index)

Просмотреть файл

@ -1017,10 +1017,10 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd,
return 0;
}
static int mt9t112_enum_fmt(struct v4l2_subdev *sd, int index,
static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code)
{
if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts))
if (index >= ARRAY_SIZE(mt9t112_cfmts))
return -EINVAL;
*code = mt9t112_cfmts[index].code;

Просмотреть файл

@ -392,27 +392,25 @@ static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
return 0;
}
static int mt9v011_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
enum v4l2_mbus_pixelcode *code)
{
if (fmt->index > 0)
if (index > 0)
return -EINVAL;
fmt->flags = 0;
strcpy(fmt->description, "8 bpp Bayer GRGR..BGBG");
fmt->pixelformat = V4L2_PIX_FMT_SGRBG8;
*code = V4L2_MBUS_FMT_SGRBG8_1X8;
return 0;
}
static int mt9v011_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
{
struct v4l2_pix_format *pix = &fmt->fmt.pix;
if (pix->pixelformat != V4L2_PIX_FMT_SGRBG8)
if (fmt->code != V4L2_MBUS_FMT_SGRBG8_1X8)
return -EINVAL;
v4l_bound_align_image(&pix->width, 48, 639, 1,
&pix->height, 32, 480, 1, 0);
v4l_bound_align_image(&fmt->width, 48, 639, 1,
&fmt->height, 32, 480, 1, 0);
fmt->field = V4L2_FIELD_NONE;
fmt->colorspace = V4L2_COLORSPACE_SRGB;
return 0;
}
@ -455,18 +453,17 @@ static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
return 0;
}
static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
static int mt9v011_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
{
struct v4l2_pix_format *pix = &fmt->fmt.pix;
struct mt9v011 *core = to_mt9v011(sd);
int rc;
rc = mt9v011_try_fmt(sd, fmt);
rc = mt9v011_try_mbus_fmt(sd, fmt);
if (rc < 0)
return -EINVAL;
core->width = pix->width;
core->height = pix->height;
core->width = fmt->width;
core->height = fmt->height;
set_res(sd);
@ -549,9 +546,9 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
};
static const struct v4l2_subdev_video_ops mt9v011_video_ops = {
.enum_fmt = mt9v011_enum_fmt,
.try_fmt = mt9v011_try_fmt,
.s_fmt = mt9v011_s_fmt,
.enum_mbus_fmt = mt9v011_enum_mbus_fmt,
.try_mbus_fmt = mt9v011_try_mbus_fmt,
.s_mbus_fmt = mt9v011_s_mbus_fmt,
.g_parm = mt9v011_g_parm,
.s_parm = mt9v011_s_parm,
};

Просмотреть файл

@ -838,13 +838,13 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
#endif
};
static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index,
static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
enum v4l2_mbus_pixelcode *code)
{
struct i2c_client *client = sd->priv;
struct mt9v022 *mt9v022 = to_mt9v022(client);
if ((unsigned int)index >= mt9v022->num_fmts)
if (index >= mt9v022->num_fmts)
return -EINVAL;
*code = mt9v022->fmts[index].code;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше