* '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 ...
Unified · Split
| @@ -58,7 +58,7 @@ MPEG stream embedded, sliced VBI data format in this specification. · 57 unmodified lines | ||
| 58 | 58 | </contrib> |
| 59 | 59 | <affiliation> |
| 60 | 60 | <address> |
| 61 | − <email>awalls@radix.net</email> | |
| 61 | + <email>awalls@md.metrocast.net</email> | |
| 62 | 62 | </address> |
| 63 | 63 | </affiliation> |
| 64 | 64 | </author> |
| @@ -53,8 +53,10 @@ input</refpurpose> · 52 unmodified lines | ||
| 53 | 53 | automatically, similar to sensing the video standard. To do so, applications |
| 54 | 54 | call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a |
| 55 | 55 | &v4l2-dv-preset; type. Once the hardware detects a preset, that preset is |
| 56 | −returned in the preset field of &v4l2-dv-preset;. When detection is not | |
| 57 | −possible or fails, the value V4L2_DV_INVALID is returned.</para> | |
| 56 | +returned in the preset field of &v4l2-dv-preset;. If the preset could not be | |
| 57 | +detected because there was no signal, or the signal was unreliable, or the | |
| 58 | +signal did not map to a supported preset, then the value V4L2_DV_INVALID is | |
| 59 | +returned.</para> | |
| 58 | 60 | </refsect1> |
| 59 | 61 | |
| 60 | 62 | <refsect1> |
| @@ -176,5 +176,6 @@ · 175 unmodified lines | ||
| 176 | 176 | 175 -> Leadtek Winfast DTV1000S [107d:6655] |
| 177 | 177 | 176 -> Beholder BeholdTV 505 RDS [0000:5051] |
| 178 | 178 | 177 -> Hawell HW-404M7 |
| 179 | −179 -> Beholder BeholdTV H7 [5ace:7190] | |
| 180 | −180 -> Beholder BeholdTV A7 [5ace:7090] | |
| 179 | +178 -> Beholder BeholdTV H7 [5ace:7190] | |
| 180 | +179 -> Beholder BeholdTV A7 [5ace:7090] | |
| 181 | +180 -> Avermedia M733A [1461:4155,1461:4255] | |
| @@ -290,6 +290,7 @@ sonixb 0c45:602e Genius VideoCam Messenger · 289 unmodified lines | ||
| 290 | 290 | sonixj 0c45:6040 Speed NVC 350K |
| 291 | 291 | sonixj 0c45:607c Sonix sn9c102p Hv7131R |
| 292 | 292 | sonixj 0c45:60c0 Sangha Sn535 |
| 293 | +sonixj 0c45:60ce USB-PC-Camera-168 (TALK-5067) | |
| 293 | 294 | sonixj 0c45:60ec SN9C105+MO4000 |
| 294 | 295 | sonixj 0c45:60fb Surfer NoName |
| 295 | 296 | sonixj 0c45:60fc LG-LIC300 |
| @@ -1731,7 +1731,7 @@ S: Maintained · 1730 unmodified lines | ||
| 1731 | 1731 | F: sound/pci/cs5535audio/ |
| 1732 | 1732 | |
| 1733 | 1733 | CX18 VIDEO4LINUX DRIVER |
| 1734 | −M: Andy Walls <awalls@radix.net> | |
| 1734 | +M: Andy Walls <awalls@md.metrocast.net> | |
| 1735 | 1735 | L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) |
| 1736 | 1736 | L: linux-media@vger.kernel.org |
| 1737 | 1737 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git |
| @@ -3165,7 +3165,7 @@ F: Documentation/hwmon/it87 · 1427 unmodified lines | ||
| 3165 | 3165 | F: drivers/hwmon/it87.c |
| 3166 | 3166 | |
| 3167 | 3167 | IVTV VIDEO4LINUX DRIVER |
| 3168 | −M: Andy Walls <awalls@radix.net> | |
| 3168 | +M: Andy Walls <awalls@md.metrocast.net> | |
| 3169 | 3169 | L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) |
| 3170 | 3170 | L: linux-media@vger.kernel.org |
| 3171 | 3171 | 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" · 12 unmodified lines | ||
| 13 | 13 | config IR_NEC_DECODER |
| 14 | 14 | tristate "Enable IR raw decoder for the NEC protocol" |
| 15 | 15 | depends on IR_CORE |
| 16 | + select BITREVERSE | |
| 16 | 17 | default y |
| 17 | 18 | |
| 18 | 19 | ---help--- |
| @@ -22,6 +23,7 @@ config IR_NEC_DECODER · 3 unmodified lines | ||
| 22 | 23 | config IR_RC5_DECODER |
| 23 | 24 | tristate "Enable IR raw decoder for the RC-5 protocol" |
| 24 | 25 | depends on IR_CORE |
| 26 | + select BITREVERSE | |
| 25 | 27 | default y |
| 26 | 28 | |
| 27 | 29 | ---help--- |
| @@ -94,6 +94,7 @@ struct imon_context { · 93 unmodified lines | ||
| 94 | 94 | |
| 95 | 95 | bool display_supported; /* not all controllers do */ |
| 96 | 96 | bool display_isopen; /* display port has been opened */ |
| 97 | + bool rf_device; /* true if iMON 2.4G LT/DT RF device */ | |
| 97 | 98 | bool rf_isassociating; /* RF remote associating */ |
| 98 | 99 | bool dev_present_intf0; /* USB device presence, interface 0 */ |
| 99 | 100 | bool dev_present_intf1; /* USB device presence, interface 1 */ |
| @@ -385,7 +386,7 @@ static int display_open(struct inode *inode, struct file *file) · 285 unmodified lines | ||
| 385 | 386 | err("%s: display port is already open", __func__); |
| 386 | 387 | retval = -EBUSY; |
| 387 | 388 | } else { |
| 388 | − ictx->display_isopen = 1; | |
| 389 | + ictx->display_isopen = true; | |
| 389 | 390 | file->private_data = ictx; |
| 390 | 391 | dev_dbg(ictx->dev, "display port opened\n"); |
| 391 | 392 | } |
| @@ -422,7 +423,7 @@ static int display_close(struct inode *inode, struct file *file) · 30 unmodified lines | ||
| 422 | 423 | err("%s: display is not open", __func__); |
| 423 | 424 | retval = -EIO; |
| 424 | 425 | } else { |
| 425 | − ictx->display_isopen = 0; | |
| 426 | + ictx->display_isopen = false; | |
| 426 | 427 | dev_dbg(ictx->dev, "display port closed\n"); |
| 427 | 428 | if (!ictx->dev_present_intf0) { |
| 428 | 429 | /* |
| @@ -491,12 +492,12 @@ static int send_packet(struct imon_context *ictx) · 62 unmodified lines | ||
| 491 | 492 | } |
| 492 | 493 | |
| 493 | 494 | init_completion(&ictx->tx.finished); |
| 494 | − ictx->tx.busy = 1; | |
| 495 | + ictx->tx.busy = true; | |
| 495 | 496 | smp_rmb(); /* ensure later readers know we're busy */ |
| 496 | 497 | |
| 497 | 498 | retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL); |
| 498 | 499 | if (retval) { |
| 499 | − ictx->tx.busy = 0; | |
| 500 | + ictx->tx.busy = false; | |
| 500 | 501 | smp_rmb(); /* ensure later readers know we're not busy */ |
| 501 | 502 | err("%s: error submitting urb(%d)", __func__, retval); |
| 502 | 503 | } else { |
| @@ -682,7 +683,7 @@ static ssize_t store_associate_remote(struct device *d, · 179 unmodified lines | ||
| 682 | 683 | return -ENODEV; |
| 683 | 684 | |
| 684 | 685 | mutex_lock(&ictx->lock); |
| 685 | − ictx->rf_isassociating = 1; | |
| 686 | + ictx->rf_isassociating = true; | |
| 686 | 687 | send_associate_24g(ictx); |
| 687 | 688 | mutex_unlock(&ictx->lock); |
| 688 | 689 | |
| @@ -950,7 +951,7 @@ static void usb_tx_callback(struct urb *urb) · 261 unmodified lines | ||
| 950 | 951 | ictx->tx.status = urb->status; |
| 951 | 952 | |
| 952 | 953 | /* notify waiters that write has finished */ |
| 953 | − ictx->tx.busy = 0; | |
| 954 | + ictx->tx.busy = false; | |
| 954 | 955 | smp_rmb(); /* ensure later readers know we're not busy */ |
| 955 | 956 | complete(&ictx->tx.finished); |
| 956 | 957 | } |
| @@ -1215,7 +1216,7 @@ static bool imon_mouse_event(struct imon_context *ictx, · 258 unmodified lines | ||
| 1215 | 1216 | { |
| 1216 | 1217 | char rel_x = 0x00, rel_y = 0x00; |
| 1217 | 1218 | u8 right_shift = 1; |
| 1218 | − bool mouse_input = 1; | |
| 1219 | + bool mouse_input = true; | |
| 1219 | 1220 | int dir = 0; |
| 1220 | 1221 | |
| 1221 | 1222 | /* newer iMON device PAD or mouse button */ |
| @@ -1246,7 +1247,7 @@ static bool imon_mouse_event(struct imon_context *ictx, · 24 unmodified lines | ||
| 1246 | 1247 | } else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) { |
| 1247 | 1248 | dir = -1; |
| 1248 | 1249 | } else |
| 1249 | − mouse_input = 0; | |
| 1250 | + mouse_input = false; | |
| 1250 | 1251 | |
| 1251 | 1252 | if (mouse_input) { |
| 1252 | 1253 | dev_dbg(ictx->dev, "sending mouse data via input subsystem\n"); |
| @@ -1450,7 +1451,7 @@ static void imon_incoming_packet(struct imon_context *ictx, · 197 unmodified lines | ||
| 1450 | 1451 | unsigned char *buf = urb->transfer_buffer; |
| 1451 | 1452 | struct device *dev = ictx->dev; |
| 1452 | 1453 | u32 kc; |
| 1453 | − bool norelease = 0; | |
| 1454 | + bool norelease = false; | |
| 1454 | 1455 | int i; |
| 1455 | 1456 | u64 temp_key; |
| 1456 | 1457 | u64 panel_key = 0; |
| @@ -1465,7 +1466,7 @@ static void imon_incoming_packet(struct imon_context *ictx, · 8 unmodified lines | ||
| 1465 | 1466 | idev = ictx->idev; |
| 1466 | 1467 | |
| 1467 | 1468 | /* filter out junk data on the older 0xffdc imon devices */ |
| 1468 | − if ((buf[0] == 0xff) && (buf[7] == 0xff)) | |
| 1469 | + if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff)) | |
| 1469 | 1470 | return; |
| 1470 | 1471 | |
| 1471 | 1472 | /* Figure out what key was pressed */ |
| @@ -1517,7 +1518,7 @@ static void imon_incoming_packet(struct imon_context *ictx, · 45 unmodified lines | ||
| 1517 | 1518 | !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) { |
| 1518 | 1519 | len = 8; |
| 1519 | 1520 | imon_pad_to_keys(ictx, buf); |
| 1520 | − norelease = 1; | |
| 1521 | + norelease = true; | |
| 1521 | 1522 | } |
| 1522 | 1523 | |
| 1523 | 1524 | if (debug) { |
| @@ -1580,7 +1581,7 @@ not_input_data: · 56 unmodified lines | ||
| 1580 | 1581 | (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */ |
| 1581 | 1582 | dev_warn(dev, "%s: remote associated refid=%02X\n", |
| 1582 | 1583 | __func__, buf[1]); |
| 1583 | − ictx->rf_isassociating = 0; | |
| 1584 | + ictx->rf_isassociating = false; | |
| 1584 | 1585 | } |
| 1585 | 1586 | } |
| 1586 | 1587 | |
| @@ -1790,9 +1791,9 @@ static bool imon_find_endpoints(struct imon_context *ictx, · 203 unmodified lines | ||
| 1790 | 1791 | int ifnum = iface_desc->desc.bInterfaceNumber; |
| 1791 | 1792 | int num_endpts = iface_desc->desc.bNumEndpoints; |
| 1792 | 1793 | int i, ep_dir, ep_type; |
| 1793 | − bool ir_ep_found = 0; | |
| 1794 | − bool display_ep_found = 0; | |
| 1795 | − bool tx_control = 0; | |
| 1794 | + bool ir_ep_found = false; | |
| 1795 | + bool display_ep_found = false; | |
| 1796 | + bool tx_control = false; | |
| 1796 | 1797 | |
| 1797 | 1798 | /* |
| 1798 | 1799 | * Scan the endpoint list and set: |
| @@ -1808,13 +1809,13 @@ static bool imon_find_endpoints(struct imon_context *ictx, · 9 unmodified lines | ||
| 1808 | 1809 | ep_type == USB_ENDPOINT_XFER_INT) { |
| 1809 | 1810 | |
| 1810 | 1811 | rx_endpoint = ep; |
| 1811 | − ir_ep_found = 1; | |
| 1812 | + ir_ep_found = true; | |
| 1812 | 1813 | dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__); |
| 1813 | 1814 | |
| 1814 | 1815 | } else if (!display_ep_found && ep_dir == USB_DIR_OUT && |
| 1815 | 1816 | ep_type == USB_ENDPOINT_XFER_INT) { |
| 1816 | 1817 | tx_endpoint = ep; |
| 1817 | − display_ep_found = 1; | |
| 1818 | + display_ep_found = true; | |
| 1818 | 1819 | dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__); |
| 1819 | 1820 | } |
| 1820 | 1821 | } |
| @@ -1835,8 +1836,8 @@ static bool imon_find_endpoints(struct imon_context *ictx, · 14 unmodified lines | ||
| 1835 | 1836 | * newer iMON devices that use control urb instead of interrupt |
| 1836 | 1837 | */ |
| 1837 | 1838 | if (!display_ep_found) { |
| 1838 | − tx_control = 1; | |
| 1839 | − display_ep_found = 1; | |
| 1839 | + tx_control = true; | |
| 1840 | + display_ep_found = true; | |
| 1840 | 1841 | dev_dbg(ictx->dev, "%s: device uses control endpoint, not " |
| 1841 | 1842 | "interface OUT endpoint\n", __func__); |
| 1842 | 1843 | } |
| @@ -1847,7 +1848,7 @@ static bool imon_find_endpoints(struct imon_context *ictx, · 4 unmodified lines | ||
| 1847 | 1848 | * and without... :\ |
| 1848 | 1849 | */ |
| 1849 | 1850 | if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) { |
| 1850 | − display_ep_found = 0; | |
| 1851 | + display_ep_found = false; | |
| 1851 | 1852 | dev_dbg(ictx->dev, "%s: device has no display\n", __func__); |
| 1852 | 1853 | } |
| 1853 | 1854 | |
| @@ -1856,7 +1857,7 @@ static bool imon_find_endpoints(struct imon_context *ictx, · 2 unmodified lines | ||
| 1856 | 1857 | * that refers to e.g. /dev/lcd0 (a character device LCD or VFD). |
| 1857 | 1858 | */ |
| 1858 | 1859 | if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { |
| 1859 | − display_ep_found = 0; | |
| 1860 | + display_ep_found = false; | |
| 1860 | 1861 | dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__); |
| 1861 | 1862 | } |
| 1862 | 1863 | |
| @@ -1905,9 +1906,10 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) · 42 unmodified lines | ||
| 1905 | 1906 | |
| 1906 | 1907 | ictx->dev = dev; |
| 1907 | 1908 | ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf)); |
| 1908 | − ictx->dev_present_intf0 = 1; | |
| 1909 | + ictx->dev_present_intf0 = true; | |
| 1909 | 1910 | ictx->rx_urb_intf0 = rx_urb; |
| 1910 | 1911 | ictx->tx_urb = tx_urb; |
| 1912 | + ictx->rf_device = false; | |
| 1911 | 1913 | |
| 1912 | 1914 | ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor); |
| 1913 | 1915 | 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, · 65 unmodified lines | ||
| 1979 | 1981 | } |
| 1980 | 1982 | |
| 1981 | 1983 | ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf)); |
| 1982 | − ictx->dev_present_intf1 = 1; | |
| 1984 | + ictx->dev_present_intf1 = true; | |
| 1983 | 1985 | ictx->rx_urb_intf1 = rx_urb; |
| 1984 | 1986 | |
| 1985 | 1987 | ret = -ENODEV; |
| @@ -2047,6 +2049,12 @@ static void imon_get_ffdc_type(struct imon_context *ictx) · 61 unmodified lines | ||
| 2047 | 2049 | dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR"); |
| 2048 | 2050 | ictx->display_supported = false; |
| 2049 | 2051 | break; |
| 2052 | + /* iMON 2.4G LT (usb stick), no display, iMON RF */ | |
| 2053 | + case 0x4e: | |
| 2054 | + dev_info(ictx->dev, "0xffdc iMON 2.4G LT, iMON RF"); | |
| 2055 | + ictx->display_supported = false; | |
| 2056 | + ictx->rf_device = true; | |
| 2057 | + break; | |
| 2050 | 2058 | /* iMON VFD, no IR (does have vol knob tho) */ |
| 2051 | 2059 | case 0x35: |
| 2052 | 2060 | dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR"); |
| @@ -2197,15 +2205,6 @@ static int __devinit imon_probe(struct usb_interface *interface, · 144 unmodified lines | ||
| 2197 | 2205 | goto fail; |
| 2198 | 2206 | } |
| 2199 | 2207 | |
| 2200 | − if (product == 0xffdc) { | |
| 2201 | − /* RF products *also* use 0xffdc... sigh... */ | |
| 2202 | − sysfs_err = sysfs_create_group(&interface->dev.kobj, | |
| 2203 | − &imon_rf_attribute_group); | |
| 2204 | − if (sysfs_err) | |
| 2205 | − err("%s: Could not create RF sysfs entries(%d)", | |
| 2206 | − __func__, sysfs_err); | |
| 2207 | − } | |
| 2208 | − | |
| 2209 | 2208 | } else { |
| 2210 | 2209 | /* this is the secondary interface on the device */ |
| 2211 | 2210 | ictx = imon_init_intf1(interface, first_if_ctx); |
| @@ -2233,6 +2232,14 @@ static int __devinit imon_probe(struct usb_interface *interface, · 21 unmodified lines | ||
| 2233 | 2232 | |
| 2234 | 2233 | imon_set_display_type(ictx, interface); |
| 2235 | 2234 | |
| 2235 | + if (product == 0xffdc && ictx->rf_device) { | |
| 2236 | + sysfs_err = sysfs_create_group(&interface->dev.kobj, | |
| 2237 | + &imon_rf_attribute_group); | |
| 2238 | + if (sysfs_err) | |
| 2239 | + err("%s: Could not create RF sysfs entries(%d)", | |
| 2240 | + __func__, sysfs_err); | |
| 2241 | + } | |
| 2242 | + | |
| 2236 | 2243 | if (ictx->display_supported) |
| 2237 | 2244 | imon_init_display(ictx, interface); |
| 2238 | 2245 | } |
| @@ -2297,7 +2304,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface) · 58 unmodified lines | ||
| 2297 | 2304 | } |
| 2298 | 2305 | |
| 2299 | 2306 | if (ifnum == 0) { |
| 2300 | − ictx->dev_present_intf0 = 0; | |
| 2307 | + ictx->dev_present_intf0 = false; | |
| 2301 | 2308 | usb_kill_urb(ictx->rx_urb_intf0); |
| 2302 | 2309 | input_unregister_device(ictx->idev); |
| 2303 | 2310 | if (ictx->display_supported) { |
| @@ -2307,7 +2314,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface) · 3 unmodified lines | ||
| 2307 | 2314 | usb_deregister_dev(interface, &imon_vfd_class); |
| 2308 | 2315 | } |
| 2309 | 2316 | } else { |
| 2310 | − ictx->dev_present_intf1 = 0; | |
| 2317 | + ictx->dev_present_intf1 = false; | |
| 2311 | 2318 | usb_kill_urb(ictx->rx_urb_intf1); |
| 2312 | 2319 | if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) |
| 2313 | 2320 | input_unregister_device(ictx->touch); |
| @@ -490,11 +490,12 @@ int __ir_input_register(struct input_dev *input_dev, · 489 unmodified lines | ||
| 490 | 490 | if (rc < 0) |
| 491 | 491 | goto out_table; |
| 492 | 492 | |
| 493 | − if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { | |
| 494 | − rc = ir_raw_event_register(input_dev); | |
| 495 | − if (rc < 0) | |
| 496 | − goto out_event; | |
| 497 | − } | |
| 493 | + if (ir_dev->props) | |
| 494 | + if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { | |
| 495 | + rc = ir_raw_event_register(input_dev); | |
| 496 | + if (rc < 0) | |
| 497 | + goto out_event; | |
| 498 | + } | |
| 498 | 499 | |
| 499 | 500 | IR_dprintk(1, "Registered input device on %s for %s remote.\n", |
| 500 | 501 | driver_name, rc_tab->name); |
| @@ -530,8 +531,10 @@ void ir_input_unregister(struct input_dev *input_dev) · 29 unmodified lines | ||
| 530 | 531 | IR_dprintk(1, "Freed keycode table\n"); |
| 531 | 532 | |
| 532 | 533 | del_timer_sync(&ir_dev->timer_keyup); |
| 533 | − if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) | |
| 534 | − ir_raw_event_unregister(input_dev); | |
| 534 | + if (ir_dev->props) | |
| 535 | + if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) | |
| 536 | + ir_raw_event_unregister(input_dev); | |
| 537 | + | |
| 535 | 538 | rc_tab = &ir_dev->rc_tab; |
| 536 | 539 | rc_tab->size = 0; |
| 537 | 540 | kfree(rc_tab->scan); |
| @@ -221,9 +221,10 @@ int ir_register_class(struct input_dev *input_dev) · 220 unmodified lines | ||
| 221 | 221 | if (unlikely(devno < 0)) |
| 222 | 222 | return devno; |
| 223 | 223 | |
| 224 | − if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) | |
| 225 | − ir_dev->dev.type = &rc_dev_type; | |
| 226 | − else | |
| 224 | + if (ir_dev->props) { | |
| 225 | + if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) | |
| 226 | + ir_dev->dev.type = &rc_dev_type; | |
| 227 | + } else | |
| 227 | 228 | ir_dev->dev.type = &ir_raw_dev_type; |
| 228 | 229 | |
| 229 | 230 | ir_dev->dev.class = &ir_input_class; |
| @@ -6,7 +6,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ · 5 unmodified lines | ||
| 6 | 6 | rc-avermedia.o \ |
| 7 | 7 | rc-avermedia-cardbus.o \ |
| 8 | 8 | rc-avermedia-dvbt.o \ |
| 9 | − rc-avermedia-m135a-rm-jx.o \ | |
| 9 | + rc-avermedia-m135a.o \ | |
| 10 | + rc-avermedia-m733a-rm-k6.o \ | |
| 10 | 11 | rc-avertv-303.o \ |
| 11 | 12 | rc-behold.o \ |
| 12 | 13 | rc-behold-columbus.o \ |
| @@ -1,90 +0,0 @@ | ||
| 1 | −/* avermedia-m135a-rm-jx.h - Keytable for avermedia_m135a_rm_jx Remote Controller | |
| 2 | − * | |
| 3 | − * keymap imported from ir-keymaps.c | |
| 4 | − * | |
| 5 | − * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> | |
| 6 | − * | |
| 7 | − * This program is free software; you can redistribute it and/or modify | |
| 8 | − * it under the terms of the GNU General Public License as published by | |
| 9 | − * the Free Software Foundation; either version 2 of the License, or | |
| 10 | − * (at your option) any later version. | |
| 11 | − */ | |
| 12 | − | |
| 13 | −#include <media/rc-map.h> | |
| 14 | − | |
| 15 | −/* | |
| 16 | − * Avermedia M135A with IR model RM-JX | |
| 17 | − * The same codes exist on both Positivo (BR) and original IR | |
| 18 | − * Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 19 | − */ | |
| 20 | − | |
| 21 | −static struct ir_scancode avermedia_m135a_rm_jx[] = { | |
| 22 | − { 0x0200, KEY_POWER2 }, | |
| 23 | − { 0x022e, KEY_DOT }, /* '.' */ | |
| 24 | − { 0x0201, KEY_MODE }, /* TV/FM or SOURCE */ | |
| 25 | − | |
| 26 | − { 0x0205, KEY_1 }, | |
| 27 | − { 0x0206, KEY_2 }, | |
| 28 | − { 0x0207, KEY_3 }, | |
| 29 | − { 0x0209, KEY_4 }, | |
| 30 | − { 0x020a, KEY_5 }, | |
| 31 | − { 0x020b, KEY_6 }, | |
| 32 | − { 0x020d, KEY_7 }, | |
| 33 | − { 0x020e, KEY_8 }, | |
| 34 | − { 0x020f, KEY_9 }, | |
| 35 | − { 0x0211, KEY_0 }, | |
| 36 | − | |
| 37 | − { 0x0213, KEY_RIGHT }, /* -> or L */ | |
| 38 | − { 0x0212, KEY_LEFT }, /* <- or R */ | |
| 39 | − | |
| 40 | − { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */ | |
| 41 | − { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */ | |
| 42 | − | |
| 43 | − { 0x0303, KEY_CHANNELUP }, | |
| 44 | − { 0x0302, KEY_CHANNELDOWN }, | |
| 45 | − { 0x021f, KEY_VOLUMEUP }, | |
| 46 | − { 0x021e, KEY_VOLUMEDOWN }, | |
| 47 | − { 0x020c, KEY_ENTER }, /* Full Screen */ | |
| 48 | − | |
| 49 | − { 0x0214, KEY_MUTE }, | |
| 50 | − { 0x0208, KEY_AUDIO }, | |
| 51 | − | |
| 52 | − { 0x0203, KEY_TEXT }, /* Teletext */ | |
| 53 | − { 0x0204, KEY_EPG }, | |
| 54 | − { 0x022b, KEY_TV2 }, /* TV2 or PIP */ | |
| 55 | − | |
| 56 | − { 0x021d, KEY_RED }, | |
| 57 | − { 0x021c, KEY_YELLOW }, | |
| 58 | − { 0x0301, KEY_GREEN }, | |
| 59 | − { 0x0300, KEY_BLUE }, | |
| 60 | − | |
| 61 | − { 0x021a, KEY_PLAYPAUSE }, | |
| 62 | − { 0x0219, KEY_RECORD }, | |
| 63 | − { 0x0218, KEY_PLAY }, | |
| 64 | − { 0x021b, KEY_STOP }, | |
| 65 | −}; | |
| 66 | − | |
| 67 | −static struct rc_keymap avermedia_m135a_rm_jx_map = { | |
| 68 | − .map = { | |
| 69 | − .scan = avermedia_m135a_rm_jx, | |
| 70 | − .size = ARRAY_SIZE(avermedia_m135a_rm_jx), | |
| 71 | − .ir_type = IR_TYPE_NEC, | |
| 72 | − .name = RC_MAP_AVERMEDIA_M135A_RM_JX, | |
| 73 | − } | |
| 74 | −}; | |
| 75 | − | |
| 76 | −static int __init init_rc_map_avermedia_m135a_rm_jx(void) | |
| 77 | −{ | |
| 78 | − return ir_register_map(&avermedia_m135a_rm_jx_map); | |
| 79 | −} | |
| 80 | − | |
| 81 | −static void __exit exit_rc_map_avermedia_m135a_rm_jx(void) | |
| 82 | −{ | |
| 83 | − ir_unregister_map(&avermedia_m135a_rm_jx_map); | |
| 84 | −} | |
| 85 | − | |
| 86 | −module_init(init_rc_map_avermedia_m135a_rm_jx) | |
| 87 | −module_exit(exit_rc_map_avermedia_m135a_rm_jx) | |
| 88 | − | |
| 89 | −MODULE_LICENSE("GPL"); | |
| 90 | −MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | |
| @@ -0,0 +1,147 @@ | ||
| 1 | +/* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers | |
| 2 | + * | |
| 3 | + * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> | |
| 4 | + * Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br> | |
| 5 | + * | |
| 6 | + * This program is free software; you can redistribute it and/or modify | |
| 7 | + * it under the terms of the GNU General Public License as published by | |
| 8 | + * the Free Software Foundation; either version 2 of the License, or | |
| 9 | + * (at your option) any later version. | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <media/rc-map.h> | |
| 13 | + | |
| 14 | +/* | |
| 15 | + * Avermedia M135A with RM-JX and RM-K6 remote controls | |
| 16 | + * | |
| 17 | + * On Avermedia M135A with IR model RM-JX, the same codes exist on both | |
| 18 | + * Positivo (BR) and original IR, initial version and remote control codes | |
| 19 | + * added by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 20 | + * | |
| 21 | + * Positivo also ships Avermedia M135A with model RM-K6, extra control | |
| 22 | + * codes added by Herton Ronaldo Krzesinski <herton@mandriva.com.br> | |
| 23 | + */ | |
| 24 | + | |
| 25 | +static struct ir_scancode avermedia_m135a[] = { | |
| 26 | + /* RM-JX */ | |
| 27 | + { 0x0200, KEY_POWER2 }, | |
| 28 | + { 0x022e, KEY_DOT }, /* '.' */ | |
| 29 | + { 0x0201, KEY_MODE }, /* TV/FM or SOURCE */ | |
| 30 | + | |
| 31 | + { 0x0205, KEY_1 }, | |
| 32 | + { 0x0206, KEY_2 }, | |
| 33 | + { 0x0207, KEY_3 }, | |
| 34 | + { 0x0209, KEY_4 }, | |
| 35 | + { 0x020a, KEY_5 }, | |
| 36 | + { 0x020b, KEY_6 }, | |
| 37 | + { 0x020d, KEY_7 }, | |
| 38 | + { 0x020e, KEY_8 }, | |
| 39 | + { 0x020f, KEY_9 }, | |
| 40 | + { 0x0211, KEY_0 }, | |
| 41 | + | |
| 42 | + { 0x0213, KEY_RIGHT }, /* -> or L */ | |
| 43 | + { 0x0212, KEY_LEFT }, /* <- or R */ | |
| 44 | + | |
| 45 | + { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */ | |
| 46 | + { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */ | |
| 47 | + | |
| 48 | + { 0x0303, KEY_CHANNELUP }, | |
| 49 | + { 0x0302, KEY_CHANNELDOWN }, | |
| 50 | + { 0x021f, KEY_VOLUMEUP }, | |
| 51 | + { 0x021e, KEY_VOLUMEDOWN }, | |
| 52 | + { 0x020c, KEY_ENTER }, /* Full Screen */ | |
| 53 | + | |
| 54 | + { 0x0214, KEY_MUTE }, | |
| 55 | + { 0x0208, KEY_AUDIO }, | |
| 56 | + | |
| 57 | + { 0x0203, KEY_TEXT }, /* Teletext */ | |
| 58 | + { 0x0204, KEY_EPG }, | |
| 59 | + { 0x022b, KEY_TV2 }, /* TV2 or PIP */ | |
| 60 | + | |
| 61 | + { 0x021d, KEY_RED }, | |
| 62 | + { 0x021c, KEY_YELLOW }, | |
| 63 | + { 0x0301, KEY_GREEN }, | |
| 64 | + { 0x0300, KEY_BLUE }, | |
| 65 | + | |
| 66 | + { 0x021a, KEY_PLAYPAUSE }, | |
| 67 | + { 0x0219, KEY_RECORD }, | |
| 68 | + { 0x0218, KEY_PLAY }, | |
| 69 | + { 0x021b, KEY_STOP }, | |
| 70 | + | |
| 71 | + /* RM-K6 */ | |
| 72 | + { 0x0401, KEY_POWER2 }, | |
| 73 | + { 0x0406, KEY_MUTE }, | |
| 74 | + { 0x0408, KEY_MODE }, /* TV/FM */ | |
| 75 | + | |
| 76 | + { 0x0409, KEY_1 }, | |
| 77 | + { 0x040a, KEY_2 }, | |
| 78 | + { 0x040b, KEY_3 }, | |
| 79 | + { 0x040c, KEY_4 }, | |
| 80 | + { 0x040d, KEY_5 }, | |
| 81 | + { 0x040e, KEY_6 }, | |
| 82 | + { 0x040f, KEY_7 }, | |
| 83 | + { 0x0410, KEY_8 }, | |
| 84 | + { 0x0411, KEY_9 }, | |
| 85 | + { 0x044c, KEY_DOT }, /* '.' */ | |
| 86 | + { 0x0412, KEY_0 }, | |
| 87 | + { 0x0407, KEY_REFRESH }, /* Refresh/Reload */ | |
| 88 | + | |
| 89 | + { 0x0413, KEY_AUDIO }, | |
| 90 | + { 0x0440, KEY_SCREEN }, /* Full Screen toggle */ | |
| 91 | + { 0x0441, KEY_HOME }, | |
| 92 | + { 0x0442, KEY_BACK }, | |
| 93 | + { 0x0447, KEY_UP }, | |
| 94 | + { 0x0448, KEY_DOWN }, | |
| 95 | + { 0x0449, KEY_LEFT }, | |
| 96 | + { 0x044a, KEY_RIGHT }, | |
| 97 | + { 0x044b, KEY_OK }, | |
| 98 | + { 0x0404, KEY_VOLUMEUP }, | |
| 99 | + { 0x0405, KEY_VOLUMEDOWN }, | |
| 100 | + { 0x0402, KEY_CHANNELUP }, | |
| 101 | + { 0x0403, KEY_CHANNELDOWN }, | |
| 102 | + | |
| 103 | + { 0x0443, KEY_RED }, | |
| 104 | + { 0x0444, KEY_GREEN }, | |
| 105 | + { 0x0445, KEY_YELLOW }, | |
| 106 | + { 0x0446, KEY_BLUE }, | |
| 107 | + | |
| 108 | + { 0x0414, KEY_TEXT }, | |
| 109 | + { 0x0415, KEY_EPG }, | |
| 110 | + { 0x041a, KEY_TV2 }, /* PIP */ | |
| 111 | + { 0x041b, KEY_MHP }, /* Snapshot */ | |
| 112 | + | |
| 113 | + { 0x0417, KEY_RECORD }, | |
| 114 | + { 0x0416, KEY_PLAYPAUSE }, | |
| 115 | + { 0x0418, KEY_STOP }, | |
| 116 | + { 0x0419, KEY_PAUSE }, | |
| 117 | + | |
| 118 | + { 0x041f, KEY_PREVIOUS }, | |
| 119 | + { 0x041c, KEY_REWIND }, | |
| 120 | + { 0x041d, KEY_FORWARD }, | |
| 121 | + { 0x041e, KEY_NEXT }, | |
| 122 | +}; | |
| 123 | + | |
| 124 | +static struct rc_keymap avermedia_m135a_map = { | |
| 125 | + .map = { | |
| 126 | + .scan = avermedia_m135a, | |
| 127 | + .size = ARRAY_SIZE(avermedia_m135a), | |
| 128 | + .ir_type = IR_TYPE_NEC, | |
| 129 | + .name = RC_MAP_AVERMEDIA_M135A, | |
| 130 | + } | |
| 131 | +}; | |
| 132 | + | |
| 133 | +static int __init init_rc_map_avermedia_m135a(void) | |
| 134 | +{ | |
| 135 | + return ir_register_map(&avermedia_m135a_map); | |
| 136 | +} | |
| 137 | + | |
| 138 | +static void __exit exit_rc_map_avermedia_m135a(void) | |
| 139 | +{ | |
| 140 | + ir_unregister_map(&avermedia_m135a_map); | |
| 141 | +} | |
| 142 | + | |
| 143 | +module_init(init_rc_map_avermedia_m135a) | |
| 144 | +module_exit(exit_rc_map_avermedia_m135a) | |
| 145 | + | |
| 146 | +MODULE_LICENSE("GPL"); | |
| 147 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | |
| @@ -0,0 +1,95 @@ | ||
| 1 | +/* avermedia-m733a-rm-k6.h - Keytable for avermedia_m733a_rm_k6 Remote Controller | |
| 2 | + * | |
| 3 | + * Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify | |
| 6 | + * it under the terms of the GNU General Public License as published by | |
| 7 | + * the Free Software Foundation; either version 2 of the License, or | |
| 8 | + * (at your option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#include <media/rc-map.h> | |
| 12 | + | |
| 13 | +/* | |
| 14 | + * Avermedia M733A with IR model RM-K6 | |
| 15 | + * This is the stock remote controller used with Positivo machines with M733A | |
| 16 | + * Herton Ronaldo Krzesinski <herton@mandriva.com.br> | |
| 17 | + */ | |
| 18 | + | |
| 19 | +static struct ir_scancode avermedia_m733a_rm_k6[] = { | |
| 20 | + { 0x0401, KEY_POWER2 }, | |
| 21 | + { 0x0406, KEY_MUTE }, | |
| 22 | + { 0x0408, KEY_MODE }, /* TV/FM */ | |
| 23 | + | |
| 24 | + { 0x0409, KEY_1 }, | |
| 25 | + { 0x040a, KEY_2 }, | |
| 26 | + { 0x040b, KEY_3 }, | |
| 27 | + { 0x040c, KEY_4 }, | |
| 28 | + { 0x040d, KEY_5 }, | |
| 29 | + { 0x040e, KEY_6 }, | |
| 30 | + { 0x040f, KEY_7 }, | |
| 31 | + { 0x0410, KEY_8 }, | |
| 32 | + { 0x0411, KEY_9 }, | |
| 33 | + { 0x044c, KEY_DOT }, /* '.' */ | |
| 34 | + { 0x0412, KEY_0 }, | |
| 35 | + { 0x0407, KEY_REFRESH }, /* Refresh/Reload */ | |
| 36 | + | |
| 37 | + { 0x0413, KEY_AUDIO }, | |
| 38 | + { 0x0440, KEY_SCREEN }, /* Full Screen toggle */ | |
| 39 | + { 0x0441, KEY_HOME }, | |
| 40 | + { 0x0442, KEY_BACK }, | |
| 41 | + { 0x0447, KEY_UP }, | |
| 42 | + { 0x0448, KEY_DOWN }, | |
| 43 | + { 0x0449, KEY_LEFT }, | |
| 44 | + { 0x044a, KEY_RIGHT }, | |
| 45 | + { 0x044b, KEY_OK }, | |
| 46 | + { 0x0404, KEY_VOLUMEUP }, | |
| 47 | + { 0x0405, KEY_VOLUMEDOWN }, | |
| 48 | + { 0x0402, KEY_CHANNELUP }, | |
| 49 | + { 0x0403, KEY_CHANNELDOWN }, | |
| 50 | + | |
| 51 | + { 0x0443, KEY_RED }, | |
| 52 | + { 0x0444, KEY_GREEN }, | |
| 53 | + { 0x0445, KEY_YELLOW }, | |
| 54 | + { 0x0446, KEY_BLUE }, | |
| 55 | + | |
| 56 | + { 0x0414, KEY_TEXT }, | |
| 57 | + { 0x0415, KEY_EPG }, | |
| 58 | + { 0x041a, KEY_TV2 }, /* PIP */ | |
| 59 | + { 0x041b, KEY_MHP }, /* Snapshot */ | |
| 60 | + | |
| 61 | + { 0x0417, KEY_RECORD }, | |
| 62 | + { 0x0416, KEY_PLAYPAUSE }, | |
| 63 | + { 0x0418, KEY_STOP }, | |
| 64 | + { 0x0419, KEY_PAUSE }, | |
| 65 | + | |
| 66 | + { 0x041f, KEY_PREVIOUS }, | |
| 67 | + { 0x041c, KEY_REWIND }, | |
| 68 | + { 0x041d, KEY_FORWARD }, | |
| 69 | + { 0x041e, KEY_NEXT }, | |
| 70 | +}; | |
| 71 | + | |
| 72 | +static struct rc_keymap avermedia_m733a_rm_k6_map = { | |
| 73 | + .map = { | |
| 74 | + .scan = avermedia_m733a_rm_k6, | |
| 75 | + .size = ARRAY_SIZE(avermedia_m733a_rm_k6), | |
| 76 | + .ir_type = IR_TYPE_NEC, | |
| 77 | + .name = RC_MAP_AVERMEDIA_M733A_RM_K6, | |
| 78 | + } | |
| 79 | +}; | |
| 80 | + | |
| 81 | +static int __init init_rc_map_avermedia_m733a_rm_k6(void) | |
| 82 | +{ | |
| 83 | + return ir_register_map(&avermedia_m733a_rm_k6_map); | |
| 84 | +} | |
| 85 | + | |
| 86 | +static void __exit exit_rc_map_avermedia_m733a_rm_k6(void) | |
| 87 | +{ | |
| 88 | + ir_unregister_map(&avermedia_m733a_rm_k6_map); | |
| 89 | +} | |
| 90 | + | |
| 91 | +module_init(init_rc_map_avermedia_m733a_rm_k6) | |
| 92 | +module_exit(exit_rc_map_avermedia_m733a_rm_k6) | |
| 93 | + | |
| 94 | +MODULE_LICENSE("GPL"); | |
| 95 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | |
| @@ -594,7 +594,7 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id) · 593 unmodified lines | ||
| 594 | 594 | int __devinit dm1105_ir_init(struct dm1105_dev *dm1105) |
| 595 | 595 | { |
| 596 | 596 | struct input_dev *input_dev; |
| 597 | − char *ir_codes = NULL; | |
| 597 | + char *ir_codes = RC_MAP_DM1105_NEC; | |
| 598 | 598 | int err = -ENOMEM; |
| 599 | 599 | |
| 600 | 600 | 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 ) · 350 unmodified lines | ||
| 351 | 351 | const u8 *ts, *ts_end, *from_where = NULL; |
| 352 | 352 | u8 ts_remain = 0, how_much = 0, new_ts = 1; |
| 353 | 353 | struct ethhdr *ethh = NULL; |
| 354 | + bool error = false; | |
| 354 | 355 | |
| 355 | 356 | #ifdef ULE_DEBUG |
| 356 | 357 | /* 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 ) · 103 unmodified lines | ||
| 460 | 461 | |
| 461 | 462 | /* Drop partly decoded SNDU, reset state, resync on PUSI. */ |
| 462 | 463 | if (priv->ule_skb) { |
| 463 | − dev_kfree_skb( priv->ule_skb ); | |
| 464 | + error = true; | |
| 465 | + dev_kfree_skb(priv->ule_skb); | |
| 466 | + } | |
| 467 | + | |
| 468 | + if (error || priv->ule_sndu_remain) { | |
| 464 | 469 | dev->stats.rx_errors++; |
| 465 | 470 | dev->stats.rx_frame_errors++; |
| 471 | + error = false; | |
| 466 | 472 | } |
| 473 | + | |
| 467 | 474 | reset_ule(priv); |
| 468 | 475 | priv->need_pusi = 1; |
| 469 | 476 | continue; |
| @@ -535,6 +542,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) · 65 unmodified lines | ||
| 535 | 542 | from_where += 2; |
| 536 | 543 | } |
| 537 | 544 | |
| 545 | + priv->ule_sndu_remain = priv->ule_sndu_len + 2; | |
| 538 | 546 | /* |
| 539 | 547 | * State of current TS: |
| 540 | 548 | * 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 ) · 3 unmodified lines | ||
| 544 | 552 | */ |
| 545 | 553 | switch (ts_remain) { |
| 546 | 554 | case 1: |
| 555 | + priv->ule_sndu_remain--; | |
| 547 | 556 | priv->ule_sndu_type = from_where[0] << 8; |
| 548 | 557 | priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */ |
| 549 | 558 | 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 ) · 7 unmodified lines | ||
| 557 | 566 | default: /* complete ULE header is present in current TS. */ |
| 558 | 567 | /* Extract ULE type field. */ |
| 559 | 568 | if (priv->ule_sndu_type_1) { |
| 569 | + priv->ule_sndu_type_1 = 0; | |
| 560 | 570 | priv->ule_sndu_type |= from_where[0]; |
| 561 | 571 | from_where += 1; /* points to payload start. */ |
| 562 | 572 | ts_remain -= 1; |
| @@ -76,6 +76,7 @@ config DVB_USB_DIB0700 · 75 unmodified lines | ||
| 76 | 76 | select DVB_S5H1411 if !DVB_FE_CUSTOMISE |
| 77 | 77 | select DVB_LGDT3305 if !DVB_FE_CUSTOMISE |
| 78 | 78 | select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE |
| 79 | + select DVB_TUNER_DIB0090 if !DVB_FE_CUSTOMISE | |
| 79 | 80 | select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE |
| 80 | 81 | select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE |
| 81 | 82 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE |
| @@ -134,6 +135,7 @@ config DVB_USB_M920X · 52 unmodified lines | ||
| 134 | 135 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE |
| 135 | 136 | select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE |
| 136 | 137 | select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE |
| 138 | + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE | |
| 137 | 139 | help |
| 138 | 140 | Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. |
| 139 | 141 | Currently, only devices with a product id of |
| @@ -264,7 +266,7 @@ config DVB_USB_DW2102 · 124 unmodified lines | ||
| 264 | 266 | select DVB_STB6000 if !DVB_FE_CUSTOMISE |
| 265 | 267 | select DVB_CX24116 if !DVB_FE_CUSTOMISE |
| 266 | 268 | select DVB_SI21XX if !DVB_FE_CUSTOMISE |
| 267 | − select DVB_TDA10021 if !DVB_FE_CUSTOMISE | |
| 269 | + select DVB_TDA10023 if !DVB_FE_CUSTOMISE | |
| 268 | 270 | select DVB_MT312 if !DVB_FE_CUSTOMISE |
| 269 | 271 | select DVB_ZL10039 if !DVB_FE_CUSTOMISE |
| 270 | 272 | select DVB_DS3000 if !DVB_FE_CUSTOMISE |
| @@ -1026,8 +1026,10 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) · 1025 unmodified lines | ||
| 1026 | 1026 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); |
| 1027 | 1027 | |
| 1028 | 1028 | if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, |
| 1029 | − &cxusb_dualdig4_rev2_config) < 0) | |
| 1029 | + &cxusb_dualdig4_rev2_config) < 0) { | |
| 1030 | + printk(KERN_WARNING "Unable to enumerate dib7000p\n"); | |
| 1030 | 1031 | return -ENODEV; |
| 1032 | + } | |
| 1031 | 1033 | |
| 1032 | 1034 | adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, |
| 1033 | 1035 | &cxusb_dualdig4_rev2_config); |
| @@ -198,6 +198,7 @@ · 197 unmodified lines | ||
| 198 | 198 | #define USB_PID_AVERMEDIA_A850 0x850a |
| 199 | 199 | #define USB_PID_AVERMEDIA_A805 0xa805 |
| 200 | 200 | #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 |
| 201 | +#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d | |
| 201 | 202 | #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a |
| 202 | 203 | #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 |
| 203 | 204 | #define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 |
| @@ -29,6 +29,8 @@ · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | #include "tda826x.h" |
| 31 | 31 | #include "tda10086.h" |
| 32 | +#include "tda1002x.h" | |
| 33 | +#include "tda827x.h" | |
| 32 | 34 | #include "lnbp21.h" |
| 33 | 35 | |
| 34 | 36 | /* debug */ |
| @@ -150,7 +152,17 @@ static struct tda10086_config tda10086_config = { · 115 unmodified lines | ||
| 150 | 152 | .xtal_freq = TDA10086_XTAL_16M, |
| 151 | 153 | }; |
| 152 | 154 | |
| 153 | −static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) | |
| 155 | +static struct tda10023_config tda10023_config = { | |
| 156 | + .demod_address = 0x0c, | |
| 157 | + .invert = 0, | |
| 158 | + .xtal = 16000000, | |
| 159 | + .pll_m = 11, | |
| 160 | + .pll_p = 3, | |
| 161 | + .pll_n = 1, | |
| 162 | + .deltaf = 0xa511, | |
| 163 | +}; | |
| 164 | + | |
| 165 | +static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap) | |
| 154 | 166 | { |
| 155 | 167 | if (usb_set_interface(adap->dev->udev,0,3) < 0) |
| 156 | 168 | err("set interface to alts=3 failed"); |
| @@ -163,7 +175,27 @@ static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) · 6 unmodified lines | ||
| 163 | 175 | return 0; |
| 164 | 176 | } |
| 165 | 177 | |
| 166 | −static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap) | |
| 178 | +static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap) | |
| 179 | +{ | |
| 180 | + if (usb_set_interface(adap->dev->udev, 0, 3) < 0) | |
| 181 | + err("set interface to alts=3 failed"); | |
| 182 | + if ((adap->fe = dvb_attach(tda10023_attach, &tda10023_config, &adap->dev->i2c_adap, 0x48)) == NULL) { | |
| 183 | + deb_info("TDA10023 attach failed\n"); | |
| 184 | + return -ENODEV; | |
| 185 | + } | |
| 186 | + return 0; | |
| 187 | +} | |
| 188 | + | |
| 189 | +static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap) | |
| 190 | +{ | |
| 191 | + if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) { | |
| 192 | + printk(KERN_ERR "%s: No tda827x found!\n", __func__); | |
| 193 | + return -ENODEV; | |
| 194 | + } | |
| 195 | + return 0; | |
| 196 | +} | |
| 197 | + | |
| 198 | +static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap) | |
| 167 | 199 | { |
| 168 | 200 | if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) { |
| 169 | 201 | deb_info("TDA8263 attach failed\n"); |
| @@ -180,6 +212,7 @@ static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap) · 10 unmodified lines | ||
| 180 | 212 | /* DVB USB Driver stuff */ |
| 181 | 213 | static struct dvb_usb_device_properties ttusb2_properties; |
| 182 | 214 | static struct dvb_usb_device_properties ttusb2_properties_s2400; |
| 215 | +static struct dvb_usb_device_properties ttusb2_properties_ct3650; | |
| 183 | 216 | |
| 184 | 217 | static int ttusb2_probe(struct usb_interface *intf, |
| 185 | 218 | const struct usb_device_id *id) |
| @@ -187,6 +220,8 @@ static int ttusb2_probe(struct usb_interface *intf, · 1 unmodified line | ||
| 187 | 220 | if (0 == dvb_usb_device_init(intf, &ttusb2_properties, |
| 188 | 221 | THIS_MODULE, NULL, adapter_nr) || |
| 189 | 222 | 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400, |
| 223 | + THIS_MODULE, NULL, adapter_nr) || | |
| 224 | + 0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650, | |
| 190 | 225 | THIS_MODULE, NULL, adapter_nr)) |
| 191 | 226 | return 0; |
| 192 | 227 | return -ENODEV; |
| @@ -197,6 +232,8 @@ static struct usb_device_id ttusb2_table [] = { · 4 unmodified lines | ||
| 197 | 232 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) }, |
| 198 | 233 | { USB_DEVICE(USB_VID_TECHNOTREND, |
| 199 | 234 | USB_PID_TECHNOTREND_CONNECT_S2400) }, |
| 235 | + { USB_DEVICE(USB_VID_TECHNOTREND, | |
| 236 | + USB_PID_TECHNOTREND_CONNECT_CT3650) }, | |
| 200 | 237 | {} /* Terminating entry */ |
| 201 | 238 | }; |
| 202 | 239 | MODULE_DEVICE_TABLE (usb, ttusb2_table); |
| @@ -214,8 +251,8 @@ static struct dvb_usb_device_properties ttusb2_properties = { · 11 unmodified lines | ||
| 214 | 251 | { |
| 215 | 252 | .streaming_ctrl = NULL, // ttusb2_streaming_ctrl, |
| 216 | 253 | |
| 217 | − .frontend_attach = ttusb2_frontend_attach, | |
| 218 | − .tuner_attach = ttusb2_tuner_attach, | |
| 254 | + .frontend_attach = ttusb2_frontend_tda10086_attach, | |
| 255 | + .tuner_attach = ttusb2_tuner_tda826x_attach, | |
| 219 | 256 | |
| 220 | 257 | /* parameter for the MPEG2-data transfer */ |
| 221 | 258 | .stream = { |
| @@ -266,8 +303,8 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = { · 44 unmodified lines | ||
| 266 | 303 | { |
| 267 | 304 | .streaming_ctrl = NULL, |
| 268 | 305 | |
| 269 | − .frontend_attach = ttusb2_frontend_attach, | |
| 270 | − .tuner_attach = ttusb2_tuner_attach, | |
| 306 | + .frontend_attach = ttusb2_frontend_tda10086_attach, | |
| 307 | + .tuner_attach = ttusb2_tuner_tda826x_attach, | |
| 271 | 308 | |
| 272 | 309 | /* parameter for the MPEG2-data transfer */ |
| 273 | 310 | .stream = { |
| @@ -301,6 +338,52 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = { · 27 unmodified lines | ||
| 301 | 338 | } |
| 302 | 339 | }; |
| 303 | 340 | |
| 341 | +static struct dvb_usb_device_properties ttusb2_properties_ct3650 = { | |
| 342 | + .caps = DVB_USB_IS_AN_I2C_ADAPTER, | |
| 343 | + | |
| 344 | + .usb_ctrl = CYPRESS_FX2, | |
| 345 | + | |
| 346 | + .size_of_priv = sizeof(struct ttusb2_state), | |
| 347 | + | |
| 348 | + .num_adapters = 1, | |
| 349 | + .adapter = { | |
| 350 | + { | |
| 351 | + .streaming_ctrl = NULL, | |
| 352 | + | |
| 353 | + .frontend_attach = ttusb2_frontend_tda10023_attach, | |
| 354 | + .tuner_attach = ttusb2_tuner_tda827x_attach, | |
| 355 | + | |
| 356 | + /* parameter for the MPEG2-data transfer */ | |
| 357 | + .stream = { | |
| 358 | + .type = USB_ISOC, | |
| 359 | + .count = 5, | |
| 360 | + .endpoint = 0x02, | |
| 361 | + .u = { | |
| 362 | + .isoc = { | |
| 363 | + .framesperurb = 4, | |
| 364 | + .framesize = 940, | |
| 365 | + .interval = 1, | |
| 366 | + } | |
| 367 | + } | |
| 368 | + } | |
| 369 | + }, | |
| 370 | + }, | |
| 371 | + | |
| 372 | + .power_ctrl = ttusb2_power_ctrl, | |
| 373 | + .identify_state = ttusb2_identify_state, | |
| 374 | + | |
| 375 | + .i2c_algo = &ttusb2_i2c_algo, | |
| 376 | + | |
| 377 | + .generic_bulk_ctrl_endpoint = 0x01, | |
| 378 | + | |
| 379 | + .num_device_descs = 1, | |
| 380 | + .devices = { | |
| 381 | + { "Technotrend TT-connect CT-3650", | |
| 382 | + .warm_ids = { &ttusb2_table[3], NULL }, | |
| 383 | + }, | |
| 384 | + } | |
| 385 | +}; | |
| 386 | + | |
| 304 | 387 | static struct usb_driver ttusb2_driver = { |
| 305 | 388 | .name = "dvb_usb_ttusb2", |
| 306 | 389 | .probe = ttusb2_probe, |
| @@ -58,7 +58,7 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) · 57 unmodified lines | ||
| 58 | 58 | num = hpsb_iso_n_ready(iso); |
| 59 | 59 | |
| 60 | 60 | if (!fdtv) { |
| 61 | − dev_err(fdtv->device, "received at unknown iso channel\n"); | |
| 61 | + pr_err("received at unknown iso channel\n"); | |
| 62 | 62 | goto out; |
| 63 | 63 | } |
| 64 | 64 | |
| @@ -567,30 +567,6 @@ static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) · 566 unmodified lines | ||
| 567 | 567 | |
| 568 | 568 | /* ----------------------------------------------------------------------- */ |
| 569 | 569 | |
| 570 | −static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 571 | −{ | |
| 572 | − switch (fmt->type) { | |
| 573 | − default: | |
| 574 | − return -EINVAL; | |
| 575 | − } | |
| 576 | − return 0; | |
| 577 | −} | |
| 578 | − | |
| 579 | −static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 580 | −{ | |
| 581 | − switch (fmt->type) { | |
| 582 | − case V4L2_BUF_TYPE_VIDEO_CAPTURE: | |
| 583 | − /* Not yet implemented */ | |
| 584 | − break; | |
| 585 | − default: | |
| 586 | − return -EINVAL; | |
| 587 | − } | |
| 588 | − | |
| 589 | − return 0; | |
| 590 | −} | |
| 591 | − | |
| 592 | −/* ----------------------------------------------------------------------- */ | |
| 593 | − | |
| 594 | 570 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 595 | 571 | static int au8522_g_register(struct v4l2_subdev *sd, |
| 596 | 572 | struct v4l2_dbg_register *reg) |
| @@ -772,8 +748,6 @@ static const struct v4l2_subdev_audio_ops au8522_audio_ops = { · 175 unmodified lines | ||
| 772 | 748 | |
| 773 | 749 | static const struct v4l2_subdev_video_ops au8522_video_ops = { |
| 774 | 750 | .s_routing = au8522_s_video_routing, |
| 775 | − .g_fmt = au8522_g_fmt, | |
| 776 | − .s_fmt = au8522_s_fmt, | |
| 777 | 751 | .s_stream = au8522_s_stream, |
| 778 | 752 | }; |
| 779 | 753 | |
| @@ -969,15 +969,12 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, · 968 unmodified lines | ||
| 969 | 969 | dprintk("%s\n", __func__); |
| 970 | 970 | |
| 971 | 971 | /* allocate memory for the internal state */ |
| 972 | − state = kmalloc(sizeof(struct ds3000_state), GFP_KERNEL); | |
| 972 | + state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL); | |
| 973 | 973 | if (state == NULL) { |
| 974 | 974 | printk(KERN_ERR "Unable to kmalloc\n"); |
| 975 | 975 | goto error2; |
| 976 | 976 | } |
| 977 | 977 | |
| 978 | − /* setup the state */ | |
| 979 | − memset(state, 0, sizeof(struct ds3000_state)); | |
| 980 | − | |
| 981 | 978 | state->config = config; |
| 982 | 979 | state->i2c = i2c; |
| 983 | 980 | state->prevUCBS2 = 0; |
| @@ -303,7 +303,10 @@ static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode) · 302 unmodified lines | ||
| 303 | 303 | |
| 304 | 304 | static int stv6110x_sleep(struct dvb_frontend *fe) |
| 305 | 305 | { |
| 306 | − return stv6110x_set_mode(fe, TUNER_SLEEP); | |
| 306 | + if (fe->tuner_priv) | |
| 307 | + return stv6110x_set_mode(fe, TUNER_SLEEP); | |
| 308 | + | |
| 309 | + return 0; | |
| 307 | 310 | } |
| 308 | 311 | |
| 309 | 312 | static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) |
| @@ -217,6 +217,19 @@ static struct ngene_info ngene_info_cineS2v5 = { · 216 unmodified lines | ||
| 217 | 217 | .fw_version = 15, |
| 218 | 218 | }; |
| 219 | 219 | |
| 220 | +static struct ngene_info ngene_info_duoFlexS2 = { | |
| 221 | + .type = NGENE_SIDEWINDER, | |
| 222 | + .name = "Digital Devices DuoFlex S2 miniPCIe", | |
| 223 | + .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | |
| 224 | + .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | |
| 225 | + .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | |
| 226 | + .fe_config = {&fe_cineS2, &fe_cineS2}, | |
| 227 | + .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | |
| 228 | + .lnb = {0x0a, 0x08}, | |
| 229 | + .tsf = {3, 3}, | |
| 230 | + .fw_version = 15, | |
| 231 | +}; | |
| 232 | + | |
| 220 | 233 | static struct ngene_info ngene_info_m780 = { |
| 221 | 234 | .type = NGENE_APP, |
| 222 | 235 | .name = "Aver M780 ATSC/QAM-B", |
| @@ -256,6 +269,8 @@ static const struct pci_device_id ngene_id_tbl[] __devinitdata = { · 33 unmodified lines | ||
| 256 | 269 | NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), |
| 257 | 270 | NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2), |
| 258 | 271 | NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5), |
| 272 | + NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlexS2), | |
| 273 | + NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlexS2), | |
| 259 | 274 | NGENE_ID(0x1461, 0x062e, ngene_info_m780), |
| 260 | 275 | {0} |
| 261 | 276 | }; |
| @@ -53,8 +53,6 @@ MODULE_PARM_DESC(debug, "Print debugging information."); · 52 unmodified lines | ||
| 53 | 53 | |
| 54 | 54 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
| 55 | 55 | |
| 56 | −#define COMMAND_TIMEOUT_WORKAROUND | |
| 57 | − | |
| 58 | 56 | #define dprintk if (debug) printk |
| 59 | 57 | |
| 60 | 58 | #define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) |
| @@ -147,24 +145,24 @@ static void demux_tasklet(unsigned long data) · 86 unmodified lines | ||
| 147 | 145 | } else { |
| 148 | 146 | if (chan->HWState == HWSTATE_RUN) { |
| 149 | 147 | u32 Flags = 0; |
| 148 | + IBufferExchange *exch1 = chan->pBufferExchange; | |
| 149 | + IBufferExchange *exch2 = chan->pBufferExchange2; | |
| 150 | 150 | if (Cur->ngeneBuffer.SR.Flags & 0x01) |
| 151 | 151 | Flags |= BEF_EVEN_FIELD; |
| 152 | 152 | if (Cur->ngeneBuffer.SR.Flags & 0x20) |
| 153 | 153 | Flags |= BEF_OVERFLOW; |
| 154 | − if (chan->pBufferExchange) | |
| 155 | − chan->pBufferExchange(chan, | |
| 156 | − Cur->Buffer1, | |
| 157 | − chan-> | |
| 158 | − Capture1Length, | |
| 159 | − Cur->ngeneBuffer. | |
| 160 | − SR.Clock, Flags); | |
| 161 | − if (chan->pBufferExchange2) | |
| 162 | − chan->pBufferExchange2(chan, | |
| 163 | − Cur->Buffer2, | |
| 164 | − chan-> | |
| 165 | − Capture2Length, | |
| 166 | − Cur->ngeneBuffer. | |
| 167 | − SR.Clock, Flags); | |
| 154 | + spin_unlock_irq(&chan->state_lock); | |
| 155 | + if (exch1) | |
| 156 | + exch1(chan, Cur->Buffer1, | |
| 157 | + chan->Capture1Length, | |
| 158 | + Cur->ngeneBuffer.SR.Clock, | |
| 159 | + Flags); | |
| 160 | + if (exch2) | |
| 161 | + exch2(chan, Cur->Buffer2, | |
| 162 | + chan->Capture2Length, | |
| 163 | + Cur->ngeneBuffer.SR.Clock, | |
| 164 | + Flags); | |
| 165 | + spin_lock_irq(&chan->state_lock); | |
| 168 | 166 | } else if (chan->HWState != HWSTATE_STOP) |
| 169 | 167 | chan->HWState = HWSTATE_RUN; |
| 170 | 168 | } |
| @@ -572,11 +570,7 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream, · 401 unmodified lines | ||
| 572 | 570 | u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700); |
| 573 | 571 | u16 BsSDO = 0x9B00; |
| 574 | 572 | |
| 575 | − /* down(&dev->stream_mutex); */ | |
| 576 | − while (down_trylock(&dev->stream_mutex)) { | |
| 577 | − printk(KERN_INFO DEVICE_NAME ": SC locked\n"); | |
| 578 | − msleep(1); | |
| 579 | − } | |
| 573 | + down(&dev->stream_mutex); | |
| 580 | 574 | memset(&com, 0, sizeof(com)); |
| 581 | 575 | com.cmd.hdr.Opcode = CMD_CONTROL; |
| 582 | 576 | com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2; |
| @@ -1252,14 +1246,17 @@ static int ngene_load_firm(struct ngene *dev) · 669 unmodified lines | ||
| 1252 | 1246 | version = 15; |
| 1253 | 1247 | size = 23466; |
| 1254 | 1248 | fw_name = "ngene_15.fw"; |
| 1249 | + dev->cmd_timeout_workaround = true; | |
| 1255 | 1250 | break; |
| 1256 | 1251 | case 16: |
| 1257 | 1252 | size = 23498; |
| 1258 | 1253 | fw_name = "ngene_16.fw"; |
| 1254 | + dev->cmd_timeout_workaround = true; | |
| 1259 | 1255 | break; |
| 1260 | 1256 | case 17: |
| 1261 | 1257 | size = 24446; |
| 1262 | 1258 | fw_name = "ngene_17.fw"; |
| 1259 | + dev->cmd_timeout_workaround = true; | |
| 1263 | 1260 | break; |
| 1264 | 1261 | } |
| 1265 | 1262 | |
| @@ -1299,11 +1296,16 @@ static void ngene_stop(struct ngene *dev) · 33 unmodified lines | ||
| 1299 | 1296 | ngwritel(0, NGENE_EVENT); |
| 1300 | 1297 | ngwritel(0, NGENE_EVENT_HI); |
| 1301 | 1298 | free_irq(dev->pci_dev->irq, dev); |
| 1299 | +#ifdef CONFIG_PCI_MSI | |
| 1300 | + if (dev->msi_enabled) | |
| 1301 | + pci_disable_msi(dev->pci_dev); | |
| 1302 | +#endif | |
| 1302 | 1303 | } |
| 1303 | 1304 | |
| 1304 | 1305 | static int ngene_start(struct ngene *dev) |
| 1305 | 1306 | { |
| 1306 | 1307 | int stat; |
| 1308 | + unsigned long flags; | |
| 1307 | 1309 | int i; |
| 1308 | 1310 | |
| 1309 | 1311 | pci_set_master(dev->pci_dev); |
| @@ -1333,6 +1335,28 @@ static int ngene_start(struct ngene *dev) · 23 unmodified lines | ||
| 1333 | 1335 | if (stat < 0) |
| 1334 | 1336 | goto fail; |
| 1335 | 1337 | |
| 1338 | +#ifdef CONFIG_PCI_MSI | |
| 1339 | + /* enable MSI if kernel and card support it */ | |
| 1340 | + if (pci_msi_enabled() && dev->card_info->msi_supported) { | |
| 1341 | + ngwritel(0, NGENE_INT_ENABLE); | |
| 1342 | + free_irq(dev->pci_dev->irq, dev); | |
| 1343 | + stat = pci_enable_msi(dev->pci_dev); | |
| 1344 | + if (stat) { | |
| 1345 | + printk(KERN_INFO DEVICE_NAME | |
| 1346 | + ": MSI not available\n"); | |
| 1347 | + flags = IRQF_SHARED; | |
| 1348 | + } else { | |
| 1349 | + flags = 0; | |
| 1350 | + dev->msi_enabled = true; | |
| 1351 | + } | |
| 1352 | + stat = request_irq(dev->pci_dev->irq, irq_handler, | |
| 1353 | + flags, "nGene", dev); | |
| 1354 | + if (stat < 0) | |
| 1355 | + goto fail2; | |
| 1356 | + ngwritel(1, NGENE_INT_ENABLE); | |
| 1357 | + } | |
| 1358 | +#endif | |
| 1359 | + | |
| 1336 | 1360 | stat = ngene_i2c_init(dev, 0); |
| 1337 | 1361 | if (stat < 0) |
| 1338 | 1362 | goto fail; |
| @@ -1358,10 +1382,18 @@ static int ngene_start(struct ngene *dev) · 19 unmodified lines | ||
| 1358 | 1382 | bconf = BUFFER_CONFIG_3333; |
| 1359 | 1383 | stat = ngene_command_config_buf(dev, bconf); |
| 1360 | 1384 | } |
| 1361 | − return stat; | |
| 1385 | + if (!stat) | |
| 1386 | + return stat; | |
| 1387 | + | |
| 1388 | + /* otherwise error: fall through */ | |
| 1362 | 1389 | fail: |
| 1363 | 1390 | ngwritel(0, NGENE_INT_ENABLE); |
| 1364 | 1391 | free_irq(dev->pci_dev->irq, dev); |
| 1392 | +#ifdef CONFIG_PCI_MSI | |
| 1393 | +fail2: | |
| 1394 | + if (dev->msi_enabled) | |
| 1395 | + pci_disable_msi(dev->pci_dev); | |
| 1396 | +#endif | |
| 1365 | 1397 | return stat; |
| 1366 | 1398 | } |
| 1367 | 1399 | |
| @@ -1379,10 +1411,8 @@ static void release_channel(struct ngene_channel *chan) · 11 unmodified lines | ||
| 1379 | 1411 | struct ngene_info *ni = dev->card_info; |
| 1380 | 1412 | int io = ni->io_type[chan->number]; |
| 1381 | 1413 | |
| 1382 | −#ifdef COMMAND_TIMEOUT_WORKAROUND | |
| 1383 | − if (chan->running) | |
| 1414 | + if (chan->dev->cmd_timeout_workaround && chan->running) | |
| 1384 | 1415 | set_transfer(chan, 0); |
| 1385 | −#endif | |
| 1386 | 1416 | |
| 1387 | 1417 | tasklet_kill(&chan->demux_tasklet); |
| 1388 | 1418 | |
| @@ -37,15 +37,12 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <linux/pci.h> |
| 38 | 38 | #include <linux/smp_lock.h> |
| 39 | 39 | #include <linux/timer.h> |
| 40 | −#include <linux/version.h> | |
| 41 | 40 | #include <linux/byteorder/generic.h> |
| 42 | 41 | #include <linux/firmware.h> |
| 43 | 42 | #include <linux/vmalloc.h> |
| 44 | 43 | |
| 45 | 44 | #include "ngene.h" |
| 46 | 45 | |
| 47 | −#define COMMAND_TIMEOUT_WORKAROUND | |
| 48 | − | |
| 49 | 46 | |
| 50 | 47 | /****************************************************************************/ |
| 51 | 48 | /* COMMAND API interface ****************************************************/ |
| @@ -69,9 +66,7 @@ void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) · 17 unmodified lines | ||
| 69 | 66 | struct ngene_channel *chan = priv; |
| 70 | 67 | |
| 71 | 68 | |
| 72 | −#ifdef COMMAND_TIMEOUT_WORKAROUND | |
| 73 | 69 | if (chan->users > 0) |
| 74 | −#endif | |
| 75 | 70 | dvb_dmx_swfilter(&chan->demux, buf, len); |
| 76 | 71 | return NULL; |
| 77 | 72 | } |
| @@ -106,11 +101,8 @@ int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed) · 28 unmodified lines | ||
| 106 | 101 | struct ngene_channel *chan = dvbdmx->priv; |
| 107 | 102 | |
| 108 | 103 | if (chan->users == 0) { |
| 109 | −#ifdef COMMAND_TIMEOUT_WORKAROUND | |
| 110 | − if (!chan->running) | |
| 111 | −#endif | |
| 104 | + if (!chan->dev->cmd_timeout_workaround || !chan->running) | |
| 112 | 105 | set_transfer(chan, 1); |
| 113 | − /* msleep(10); */ | |
| 114 | 106 | } |
| 115 | 107 | |
| 116 | 108 | return ++chan->users; |
| @@ -124,9 +116,8 @@ int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed) · 7 unmodified lines | ||
| 124 | 116 | if (--chan->users) |
| 125 | 117 | return chan->users; |
| 126 | 118 | |
| 127 | −#ifndef COMMAND_TIMEOUT_WORKAROUND | |
| 128 | − set_transfer(chan, 0); | |
| 129 | −#endif | |
| 119 | + if (!chan->dev->cmd_timeout_workaround) | |
| 120 | + set_transfer(chan, 0); | |
| 130 | 121 | |
| 131 | 122 | return 0; |
| 132 | 123 | } |
| @@ -39,7 +39,6 @@ · 38 unmodified lines | ||
| 39 | 39 | #include <linux/pci_ids.h> |
| 40 | 40 | #include <linux/smp_lock.h> |
| 41 | 41 | #include <linux/timer.h> |
| 42 | −#include <linux/version.h> | |
| 43 | 42 | #include <linux/byteorder/generic.h> |
| 44 | 43 | #include <linux/firmware.h> |
| 45 | 44 | #include <linux/vmalloc.h> |
| @@ -725,6 +725,8 @@ struct ngene { · 724 unmodified lines | ||
| 725 | 725 | u32 device_version; |
| 726 | 726 | u32 fw_interface_version; |
| 727 | 727 | u32 icounts; |
| 728 | + bool msi_enabled; | |
| 729 | + bool cmd_timeout_workaround; | |
| 728 | 730 | |
| 729 | 731 | u8 *CmdDoneByte; |
| 730 | 732 | int BootFirmware; |
| @@ -797,6 +799,7 @@ struct ngene_info { · 66 unmodified lines | ||
| 797 | 799 | #define NGENE_VBOX_V2 7 |
| 798 | 800 | |
| 799 | 801 | int fw_version; |
| 802 | + bool msi_supported; | |
| 800 | 803 | char *name; |
| 801 | 804 | |
| 802 | 805 | int io_type[MAX_STREAM]; |
| @@ -68,13 +68,14 @@ config DVB_BUDGET · 67 unmodified lines | ||
| 68 | 68 | select DVB_VES1820 if !DVB_FE_CUSTOMISE |
| 69 | 69 | select DVB_L64781 if !DVB_FE_CUSTOMISE |
| 70 | 70 | select DVB_TDA8083 if !DVB_FE_CUSTOMISE |
| 71 | − select DVB_TDA10021 if !DVB_FE_CUSTOMISE | |
| 72 | − select DVB_TDA10023 if !DVB_FE_CUSTOMISE | |
| 73 | 71 | select DVB_S5H1420 if !DVB_FE_CUSTOMISE |
| 74 | 72 | select DVB_TDA10086 if !DVB_FE_CUSTOMISE |
| 75 | 73 | select DVB_TDA826X if !DVB_FE_CUSTOMISE |
| 76 | 74 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE |
| 77 | 75 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE |
| 76 | + select DVB_ISL6423 if !DVB_FE_CUSTOMISE | |
| 77 | + select DVB_STV090x if !DVB_FE_CUSTOMISE | |
| 78 | + select DVB_STV6110x if !DVB_FE_CUSTOMISE | |
| 78 | 79 | help |
| 79 | 80 | Support for simple SAA7146 based DVB cards (so called Budget- |
| 80 | 81 | or Nova-PCI cards) without onboard MPEG2 decoder, and without |
| @@ -215,6 +215,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) · 214 unmodified lines | ||
| 215 | 215 | break; |
| 216 | 216 | case 0x1010: |
| 217 | 217 | case 0x1017: |
| 218 | + case 0x1019: | |
| 218 | 219 | case 0x101a: |
| 219 | 220 | /* for the Technotrend 1500 bundled remote */ |
| 220 | 221 | ir_codes = RC_MAP_TT_1500; |
| @@ -646,7 +646,7 @@ config VIDEO_PMS · 645 unmodified lines | ||
| 646 | 646 | |
| 647 | 647 | config VIDEO_BWQCAM |
| 648 | 648 | tristate "Quickcam BW Video For Linux" |
| 649 | − depends on PARPORT && VIDEO_V4L1 | |
| 649 | + depends on PARPORT && VIDEO_V4L2 | |
| 650 | 650 | help |
| 651 | 651 | Say Y have if you the black and white version of the QuickCam |
| 652 | 652 | camera. See the next option for the color version. |
| @@ -656,7 +656,7 @@ config VIDEO_BWQCAM · 3 unmodified lines | ||
| 656 | 656 | |
| 657 | 657 | config VIDEO_CQCAM |
| 658 | 658 | tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)" |
| 659 | − depends on EXPERIMENTAL && PARPORT && VIDEO_V4L1 | |
| 659 | + depends on EXPERIMENTAL && PARPORT && VIDEO_V4L2 | |
| 660 | 660 | help |
| 661 | 661 | This is the video4linux driver for the colour version of the |
| 662 | 662 | Connectix QuickCam. If you have one of these cameras, say Y here, |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/i2c.h> |
| 12 | 12 | #include <linux/init.h> |
| 13 | 13 | #include <linux/platform_device.h> |
| 14 | +#include <linux/slab.h> | |
| 14 | 15 | #include <linux/videodev2.h> |
| 15 | 16 | |
| 16 | 17 | #include <media/ak881x.h> |
| @@ -141,7 +142,7 @@ static int ak881x_s_mbus_fmt(struct v4l2_subdev *sd, · 124 unmodified lines | ||
| 141 | 142 | return ak881x_try_g_mbus_fmt(sd, mf); |
| 142 | 143 | } |
| 143 | 144 | |
| 144 | −static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, int index, | |
| 145 | +static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 145 | 146 | enum v4l2_mbus_pixelcode *code) |
| 146 | 147 | { |
| 147 | 148 | if (index) |
| @@ -66,19 +66,58 @@ OTHER DEALINGS IN THE SOFTWARE. · 65 unmodified lines | ||
| 66 | 66 | #include <linux/delay.h> |
| 67 | 67 | #include <linux/errno.h> |
| 68 | 68 | #include <linux/fs.h> |
| 69 | −#include <linux/init.h> | |
| 70 | 69 | #include <linux/kernel.h> |
| 71 | 70 | #include <linux/slab.h> |
| 72 | 71 | #include <linux/mm.h> |
| 73 | 72 | #include <linux/parport.h> |
| 74 | 73 | #include <linux/sched.h> |
| 75 | −#include <linux/videodev.h> | |
| 76 | −#include <media/v4l2-common.h> | |
| 77 | −#include <media/v4l2-ioctl.h> | |
| 74 | +#include <linux/version.h> | |
| 75 | +#include <linux/videodev2.h> | |
| 78 | 76 | #include <linux/mutex.h> |
| 79 | 77 | #include <asm/uaccess.h> |
| 80 | − | |
| 81 | −#include "bw-qcam.h" | |
| 78 | +#include <media/v4l2-common.h> | |
| 79 | +#include <media/v4l2-ioctl.h> | |
| 80 | +#include <media/v4l2-device.h> | |
| 81 | + | |
| 82 | +/* One from column A... */ | |
| 83 | +#define QC_NOTSET 0 | |
| 84 | +#define QC_UNIDIR 1 | |
| 85 | +#define QC_BIDIR 2 | |
| 86 | +#define QC_SERIAL 3 | |
| 87 | + | |
| 88 | +/* ... and one from column B */ | |
| 89 | +#define QC_ANY 0x00 | |
| 90 | +#define QC_FORCE_UNIDIR 0x10 | |
| 91 | +#define QC_FORCE_BIDIR 0x20 | |
| 92 | +#define QC_FORCE_SERIAL 0x30 | |
| 93 | +/* in the port_mode member */ | |
| 94 | + | |
| 95 | +#define QC_MODE_MASK 0x07 | |
| 96 | +#define QC_FORCE_MASK 0x70 | |
| 97 | + | |
| 98 | +#define MAX_HEIGHT 243 | |
| 99 | +#define MAX_WIDTH 336 | |
| 100 | + | |
| 101 | +/* Bit fields for status flags */ | |
| 102 | +#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */ | |
| 103 | + | |
| 104 | +struct qcam { | |
| 105 | + struct v4l2_device v4l2_dev; | |
| 106 | + struct video_device vdev; | |
| 107 | + struct pardevice *pdev; | |
| 108 | + struct parport *pport; | |
| 109 | + struct mutex lock; | |
| 110 | + int width, height; | |
| 111 | + int bpp; | |
| 112 | + int mode; | |
| 113 | + int contrast, brightness, whitebal; | |
| 114 | + int port_mode; | |
| 115 | + int transfer_scale; | |
| 116 | + int top, left; | |
| 117 | + int status; | |
| 118 | + unsigned int saved_bits; | |
| 119 | + unsigned long in_use; | |
| 120 | +}; | |
| 82 | 121 | |
| 83 | 122 | static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */ |
| 84 | 123 | static unsigned int yieldlines = 4; /* Yield after this many during capture */ |
| @@ -93,22 +132,26 @@ module_param(video_nr, int, 0); · 8 unmodified lines | ||
| 93 | 132 | * immediately attempt to initialize qcam */ |
| 94 | 133 | module_param(force_init, int, 0); |
| 95 | 134 | |
| 96 | −static inline int read_lpstatus(struct qcam_device *q) | |
| 135 | +#define MAX_CAMS 4 | |
| 136 | +static struct qcam *qcams[MAX_CAMS]; | |
| 137 | +static unsigned int num_cams; | |
| 138 | + | |
| 139 | +static inline int read_lpstatus(struct qcam *q) | |
| 97 | 140 | { |
| 98 | 141 | return parport_read_status(q->pport); |
| 99 | 142 | } |
| 100 | 143 | |
| 101 | −static inline int read_lpdata(struct qcam_device *q) | |
| 144 | +static inline int read_lpdata(struct qcam *q) | |
| 102 | 145 | { |
| 103 | 146 | return parport_read_data(q->pport); |
| 104 | 147 | } |
| 105 | 148 | |
| 106 | −static inline void write_lpdata(struct qcam_device *q, int d) | |
| 149 | +static inline void write_lpdata(struct qcam *q, int d) | |
| 107 | 150 | { |
| 108 | 151 | parport_write_data(q->pport, d); |
| 109 | 152 | } |
| 110 | 153 | |
| 111 | −static inline void write_lpcontrol(struct qcam_device *q, int d) | |
| 154 | +static void write_lpcontrol(struct qcam *q, int d) | |
| 112 | 155 | { |
| 113 | 156 | if (d & 0x20) { |
| 114 | 157 | /* Set bidirectional mode to reverse (data in) */ |
| @@ -124,126 +167,11 @@ static inline void write_lpcontrol(struct qcam_device *q, int d) · 9 unmodified lines | ||
| 124 | 167 | parport_write_control(q->pport, d); |
| 125 | 168 | } |
| 126 | 169 | |
| 127 | −static int qc_waithand(struct qcam_device *q, int val); | |
| 128 | −static int qc_command(struct qcam_device *q, int command); | |
| 129 | −static int qc_readparam(struct qcam_device *q); | |
| 130 | −static int qc_setscanmode(struct qcam_device *q); | |
| 131 | −static int qc_readbytes(struct qcam_device *q, char buffer[]); | |
| 132 | − | |
| 133 | −static struct video_device qcam_template; | |
| 134 | − | |
| 135 | −static int qc_calibrate(struct qcam_device *q) | |
| 136 | −{ | |
| 137 | − /* | |
| 138 | − * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96 | |
| 139 | − * The white balance is an individiual value for each | |
| 140 | − * quickcam. | |
| 141 | − */ | |
| 142 | − | |
| 143 | − int value; | |
| 144 | − int count = 0; | |
| 145 | − | |
| 146 | − qc_command(q, 27); /* AutoAdjustOffset */ | |
| 147 | − qc_command(q, 0); /* Dummy Parameter, ignored by the camera */ | |
| 148 | − | |
| 149 | − /* GetOffset (33) will read 255 until autocalibration */ | |
| 150 | − /* is finished. After that, a value of 1-254 will be */ | |
| 151 | − /* returned. */ | |
| 152 | − | |
| 153 | − do { | |
| 154 | − qc_command(q, 33); | |
| 155 | − value = qc_readparam(q); | |
| 156 | − mdelay(1); | |
| 157 | − schedule(); | |
| 158 | − count++; | |
| 159 | − } while (value == 0xff && count < 2048); | |
| 160 | − | |
| 161 | − q->whitebal = value; | |
| 162 | − return value; | |
| 163 | −} | |
| 164 | − | |
| 165 | −/* Initialize the QuickCam driver control structure. This is where | |
| 166 | − * defaults are set for people who don't have a config file.*/ | |
| 167 | − | |
| 168 | −static struct qcam_device *qcam_init(struct parport *port) | |
| 169 | −{ | |
| 170 | − struct qcam_device *q; | |
| 171 | − | |
| 172 | − q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); | |
| 173 | − if (q == NULL) | |
| 174 | − return NULL; | |
| 175 | − | |
| 176 | − q->pport = port; | |
| 177 | − q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, | |
| 178 | − NULL, 0, NULL); | |
| 179 | − if (q->pdev == NULL) { | |
| 180 | − printk(KERN_ERR "bw-qcam: couldn't register for %s.\n", | |
| 181 | − port->name); | |
| 182 | − kfree(q); | |
| 183 | − return NULL; | |
| 184 | − } | |
| 185 | − | |
| 186 | − memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); | |
| 187 | − | |
| 188 | − mutex_init(&q->lock); | |
| 189 | − | |
| 190 | − q->port_mode = (QC_ANY | QC_NOTSET); | |
| 191 | − q->width = 320; | |
| 192 | − q->height = 240; | |
| 193 | − q->bpp = 4; | |
| 194 | − q->transfer_scale = 2; | |
| 195 | − q->contrast = 192; | |
| 196 | − q->brightness = 180; | |
| 197 | − q->whitebal = 105; | |
| 198 | − q->top = 1; | |
| 199 | − q->left = 14; | |
| 200 | − q->mode = -1; | |
| 201 | − q->status = QC_PARAM_CHANGE; | |
| 202 | − return q; | |
| 203 | −} | |
| 204 | − | |
| 205 | − | |
| 206 | −/* qc_command is probably a bit of a misnomer -- it's used to send | |
| 207 | − * bytes *to* the camera. Generally, these bytes are either commands | |
| 208 | − * or arguments to commands, so the name fits, but it still bugs me a | |
| 209 | − * bit. See the documentation for a list of commands. */ | |
| 210 | − | |
| 211 | −static int qc_command(struct qcam_device *q, int command) | |
| 212 | −{ | |
| 213 | − int n1, n2; | |
| 214 | − int cmd; | |
| 215 | − | |
| 216 | − write_lpdata(q, command); | |
| 217 | − write_lpcontrol(q, 6); | |
| 218 | − | |
| 219 | − n1 = qc_waithand(q, 1); | |
| 220 | − | |
| 221 | − write_lpcontrol(q, 0xe); | |
| 222 | − n2 = qc_waithand(q, 0); | |
| 223 | − | |
| 224 | − cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); | |
| 225 | − return cmd; | |
| 226 | −} | |
| 227 | − | |
| 228 | −static int qc_readparam(struct qcam_device *q) | |
| 229 | −{ | |
| 230 | − int n1, n2; | |
| 231 | − int cmd; | |
| 232 | − | |
| 233 | − write_lpcontrol(q, 6); | |
| 234 | − n1 = qc_waithand(q, 1); | |
| 235 | − | |
| 236 | − write_lpcontrol(q, 0xe); | |
| 237 | − n2 = qc_waithand(q, 0); | |
| 238 | − | |
| 239 | − cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); | |
| 240 | − return cmd; | |
| 241 | −} | |
| 242 | 170 | |
| 243 | 171 | /* qc_waithand busy-waits for a handshake signal from the QuickCam. |
| 244 | 172 | * Almost all communication with the camera requires handshaking. */ |
| 245 | 173 | |
| 246 | −static int qc_waithand(struct qcam_device *q, int val) | |
| 174 | +static int qc_waithand(struct qcam *q, int val) | |
| 247 | 175 | { |
| 248 | 176 | int status; |
| 249 | 177 | int runs = 0; |
| @@ -286,7 +214,7 @@ static int qc_waithand(struct qcam_device *q, int val) · 36 unmodified lines | ||
| 286 | 214 | * (bit 3 of status register). It also returns the last value read, |
| 287 | 215 | * since this data is useful. */ |
| 288 | 216 | |
| 289 | −static unsigned int qc_waithand2(struct qcam_device *q, int val) | |
| 217 | +static unsigned int qc_waithand2(struct qcam *q, int val) | |
| 290 | 218 | { |
| 291 | 219 | unsigned int status; |
| 292 | 220 | int runs = 0; |
| @@ -309,6 +237,43 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val) · 16 unmodified lines | ||
| 309 | 237 | return status; |
| 310 | 238 | } |
| 311 | 239 | |
| 240 | +/* qc_command is probably a bit of a misnomer -- it's used to send | |
| 241 | + * bytes *to* the camera. Generally, these bytes are either commands | |
| 242 | + * or arguments to commands, so the name fits, but it still bugs me a | |
| 243 | + * bit. See the documentation for a list of commands. */ | |
| 244 | + | |
| 245 | +static int qc_command(struct qcam *q, int command) | |
| 246 | +{ | |
| 247 | + int n1, n2; | |
| 248 | + int cmd; | |
| 249 | + | |
| 250 | + write_lpdata(q, command); | |
| 251 | + write_lpcontrol(q, 6); | |
| 252 | + | |
| 253 | + n1 = qc_waithand(q, 1); | |
| 254 | + | |
| 255 | + write_lpcontrol(q, 0xe); | |
| 256 | + n2 = qc_waithand(q, 0); | |
| 257 | + | |
| 258 | + cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); | |
| 259 | + return cmd; | |
| 260 | +} | |
| 261 | + | |
| 262 | +static int qc_readparam(struct qcam *q) | |
| 263 | +{ | |
| 264 | + int n1, n2; | |
| 265 | + int cmd; | |
| 266 | + | |
| 267 | + write_lpcontrol(q, 6); | |
| 268 | + n1 = qc_waithand(q, 1); | |
| 269 | + | |
| 270 | + write_lpcontrol(q, 0xe); | |
| 271 | + n2 = qc_waithand(q, 0); | |
| 272 | + | |
| 273 | + cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); | |
| 274 | + return cmd; | |
| 275 | +} | |
| 276 | + | |
| 312 | 277 | |
| 313 | 278 | /* Try to detect a QuickCam. It appears to flash the upper 4 bits of |
| 314 | 279 | 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) · 2 unmodified lines | ||
| 317 | 282 | almost completely safe, while their method screws up my printer if |
| 318 | 283 | I plug it in before the camera. */ |
| 319 | 284 | |
| 320 | −static int qc_detect(struct qcam_device *q) | |
| 285 | +static int qc_detect(struct qcam *q) | |
| 321 | 286 | { |
| 322 | 287 | int reg, lastreg; |
| 323 | 288 | int count = 0; |
| @@ -358,41 +323,6 @@ static int qc_detect(struct qcam_device *q) · 34 unmodified lines | ||
| 358 | 323 | } |
| 359 | 324 | } |
| 360 | 325 | |
| 361 | − | |
| 362 | −/* Reset the QuickCam. This uses the same sequence the Windows | |
| 363 | − * QuickPic program uses. Someone with a bi-directional port should | |
| 364 | − * check that bi-directional mode is detected right, and then | |
| 365 | − * implement bi-directional mode in qc_readbyte(). */ | |
| 366 | − | |
| 367 | −static void qc_reset(struct qcam_device *q) | |
| 368 | −{ | |
| 369 | − switch (q->port_mode & QC_FORCE_MASK) { | |
| 370 | − case QC_FORCE_UNIDIR: | |
| 371 | − q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; | |
| 372 | − break; | |
| 373 | − | |
| 374 | − case QC_FORCE_BIDIR: | |
| 375 | − q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; | |
| 376 | − break; | |
| 377 | − | |
| 378 | − case QC_ANY: | |
| 379 | − write_lpcontrol(q, 0x20); | |
| 380 | − write_lpdata(q, 0x75); | |
| 381 | − | |
| 382 | − if (read_lpdata(q) != 0x75) | |
| 383 | − q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; | |
| 384 | − else | |
| 385 | − q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; | |
| 386 | − break; | |
| 387 | − } | |
| 388 | − | |
| 389 | − write_lpcontrol(q, 0xb); | |
| 390 | − udelay(250); | |
| 391 | − write_lpcontrol(q, 0xe); | |
| 392 | − qc_setscanmode(q); /* in case port_mode changed */ | |
| 393 | −} | |
| 394 | − | |
| 395 | − | |
| 396 | 326 | /* Decide which scan mode to use. There's no real requirement that |
| 397 | 327 | * the scanmode match the resolution in q->height and q-> width -- the |
| 398 | 328 | * camera takes the picture at the resolution specified in the |
| @@ -402,7 +332,7 @@ static void qc_reset(struct qcam_device *q) · 3 unmodified lines | ||
| 402 | 332 | * returned. If the scan is smaller, then the rest of the image |
| 403 | 333 | * returned contains garbage. */ |
| 404 | 334 | |
| 405 | −static int qc_setscanmode(struct qcam_device *q) | |
| 335 | +static int qc_setscanmode(struct qcam *q) | |
| 406 | 336 | { |
| 407 | 337 | int old_mode = q->mode; |
| 408 | 338 | |
| @@ -442,10 +372,45 @@ static int qc_setscanmode(struct qcam_device *q) · 33 unmodified lines | ||
| 442 | 372 | } |
| 443 | 373 | |
| 444 | 374 | |
| 375 | +/* Reset the QuickCam. This uses the same sequence the Windows | |
| 376 | + * QuickPic program uses. Someone with a bi-directional port should | |
| 377 | + * check that bi-directional mode is detected right, and then | |
| 378 | + * implement bi-directional mode in qc_readbyte(). */ | |
| 379 | + | |
| 380 | +static void qc_reset(struct qcam *q) | |
| 381 | +{ | |
| 382 | + switch (q->port_mode & QC_FORCE_MASK) { | |
| 383 | + case QC_FORCE_UNIDIR: | |
| 384 | + q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; | |
| 385 | + break; | |
| 386 | + | |
| 387 | + case QC_FORCE_BIDIR: | |
| 388 | + q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; | |
| 389 | + break; | |
| 390 | + | |
| 391 | + case QC_ANY: | |
| 392 | + write_lpcontrol(q, 0x20); | |
| 393 | + write_lpdata(q, 0x75); | |
| 394 | + | |
| 395 | + if (read_lpdata(q) != 0x75) | |
| 396 | + q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; | |
| 397 | + else | |
| 398 | + q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; | |
| 399 | + break; | |
| 400 | + } | |
| 401 | + | |
| 402 | + write_lpcontrol(q, 0xb); | |
| 403 | + udelay(250); | |
| 404 | + write_lpcontrol(q, 0xe); | |
| 405 | + qc_setscanmode(q); /* in case port_mode changed */ | |
| 406 | +} | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 445 | 410 | /* Reset the QuickCam and program for brightness, contrast, |
| 446 | 411 | * white-balance, and resolution. */ |
| 447 | 412 | |
| 448 | −static void qc_set(struct qcam_device *q) | |
| 413 | +static void qc_set(struct qcam *q) | |
| 449 | 414 | { |
| 450 | 415 | int val; |
| 451 | 416 | int val2; |
| @@ -499,7 +464,7 @@ static void qc_set(struct qcam_device *q) · 47 unmodified lines | ||
| 499 | 464 | the supplied buffer. It returns the number of bytes read, |
| 500 | 465 | or -1 on error. */ |
| 501 | 466 | |
| 502 | −static inline int qc_readbytes(struct qcam_device *q, char buffer[]) | |
| 467 | +static inline int qc_readbytes(struct qcam *q, char buffer[]) | |
| 503 | 468 | { |
| 504 | 469 | int ret = 1; |
| 505 | 470 | unsigned int hi, lo; |
| @@ -590,7 +555,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) · 84 unmodified lines | ||
| 590 | 555 | * n=2^(bit depth)-1. Ask me for more details if you don't understand |
| 591 | 556 | * this. */ |
| 592 | 557 | |
| 593 | −static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len) | |
| 558 | +static long qc_capture(struct qcam *q, char __user *buf, unsigned long len) | |
| 594 | 559 | { |
| 595 | 560 | int i, j, k, yield; |
| 596 | 561 | int bytes; |
| @@ -674,171 +639,206 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le · 77 unmodified lines | ||
| 674 | 639 | * Video4linux interfacing |
| 675 | 640 | */ |
| 676 | 641 | |
| 677 | −static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |
| 642 | +static int qcam_querycap(struct file *file, void *priv, | |
| 643 | + struct v4l2_capability *vcap) | |
| 678 | 644 | { |
| 679 | − struct video_device *dev = video_devdata(file); | |
| 680 | − struct qcam_device *qcam = (struct qcam_device *)dev; | |
| 681 | − | |
| 682 | − switch (cmd) { | |
| 683 | − case VIDIOCGCAP: | |
| 684 | − { | |
| 685 | − struct video_capability *b = arg; | |
| 686 | − strcpy(b->name, "Quickcam"); | |
| 687 | − b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME; | |
| 688 | − b->channels = 1; | |
| 689 | − b->audios = 0; | |
| 690 | − b->maxwidth = 320; | |
| 691 | − b->maxheight = 240; | |
| 692 | − b->minwidth = 80; | |
| 693 | − b->minheight = 60; | |
| 694 | − return 0; | |
| 695 | − } | |
| 696 | − case VIDIOCGCHAN: | |
| 697 | − { | |
| 698 | − struct video_channel *v = arg; | |
| 699 | − if (v->channel != 0) | |
| 700 | − return -EINVAL; | |
| 701 | − v->flags = 0; | |
| 702 | − v->tuners = 0; | |
| 703 | − /* Good question.. its composite or SVHS so.. */ | |
| 704 | − v->type = VIDEO_TYPE_CAMERA; | |
| 705 | − strcpy(v->name, "Camera"); | |
| 706 | − return 0; | |
| 707 | − } | |
| 708 | − case VIDIOCSCHAN: | |
| 709 | − { | |
| 710 | − struct video_channel *v = arg; | |
| 711 | − if (v->channel != 0) | |
| 712 | − return -EINVAL; | |
| 713 | − return 0; | |
| 714 | − } | |
| 715 | − case VIDIOCGTUNER: | |
| 716 | − { | |
| 717 | − struct video_tuner *v = arg; | |
| 718 | − if (v->tuner) | |
| 719 | − return -EINVAL; | |
| 720 | − strcpy(v->name, "Format"); | |
| 721 | − v->rangelow = 0; | |
| 722 | − v->rangehigh = 0; | |
| 723 | − v->flags = 0; | |
| 724 | − v->mode = VIDEO_MODE_AUTO; | |
| 725 | − return 0; | |
| 726 | − } | |
| 727 | − case VIDIOCSTUNER: | |
| 728 | − { | |
| 729 | − struct video_tuner *v = arg; | |
| 730 | − if (v->tuner) | |
| 731 | − return -EINVAL; | |
| 732 | − if (v->mode != VIDEO_MODE_AUTO) | |
| 733 | − return -EINVAL; | |
| 734 | − return 0; | |
| 735 | − } | |
| 736 | − case VIDIOCGPICT: | |
| 737 | − { | |
| 738 | − struct video_picture *p = arg; | |
| 739 | − p->colour = 0x8000; | |
| 740 | − p->hue = 0x8000; | |
| 741 | − p->brightness = qcam->brightness << 8; | |
| 742 | − p->contrast = qcam->contrast << 8; | |
| 743 | − p->whiteness = qcam->whitebal << 8; | |
| 744 | − p->depth = qcam->bpp; | |
| 745 | − p->palette = VIDEO_PALETTE_GREY; | |
| 746 | − return 0; | |
| 747 | − } | |
| 748 | − case VIDIOCSPICT: | |
| 749 | − { | |
| 750 | − struct video_picture *p = arg; | |
| 751 | − if (p->palette != VIDEO_PALETTE_GREY) | |
| 752 | − return -EINVAL; | |
| 753 | − if (p->depth != 4 && p->depth != 6) | |
| 754 | − return -EINVAL; | |
| 755 | − | |
| 756 | − /* | |
| 757 | − * Now load the camera. | |
| 758 | − */ | |
| 759 | − | |
| 760 | − qcam->brightness = p->brightness >> 8; | |
| 761 | − qcam->contrast = p->contrast >> 8; | |
| 762 | − qcam->whitebal = p->whiteness >> 8; | |
| 763 | − qcam->bpp = p->depth; | |
| 764 | − | |
| 765 | − mutex_lock(&qcam->lock); | |
| 766 | − qc_setscanmode(qcam); | |
| 767 | − mutex_unlock(&qcam->lock); | |
| 768 | − qcam->status |= QC_PARAM_CHANGE; | |
| 645 | + struct qcam *qcam = video_drvdata(file); | |
| 769 | 646 | |
| 770 | − return 0; | |
| 771 | − } | |
| 772 | − case VIDIOCSWIN: | |
| 773 | − { | |
| 774 | − struct video_window *vw = arg; | |
| 775 | − if (vw->flags) | |
| 776 | − return -EINVAL; | |
| 777 | − if (vw->clipcount) | |
| 778 | − return -EINVAL; | |
| 779 | − if (vw->height < 60 || vw->height > 240) | |
| 780 | − return -EINVAL; | |
| 781 | − if (vw->width < 80 || vw->width > 320) | |
| 782 | − return -EINVAL; | |
| 783 | − | |
| 784 | − qcam->width = 320; | |
| 785 | − qcam->height = 240; | |
| 786 | − qcam->transfer_scale = 4; | |
| 787 | − | |
| 788 | − if (vw->width >= 160 && vw->height >= 120) | |
| 789 | − qcam->transfer_scale = 2; | |
| 790 | − if (vw->width >= 320 && vw->height >= 240) { | |
| 791 | − qcam->width = 320; | |
| 792 | − qcam->height = 240; | |
| 793 | − qcam->transfer_scale = 1; | |
| 794 | − } | |
| 795 | − mutex_lock(&qcam->lock); | |
| 796 | − qc_setscanmode(qcam); | |
| 797 | − mutex_unlock(&qcam->lock); | |
| 647 | + strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); | |
| 648 | + strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card)); | |
| 649 | + strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); | |
| 650 | + vcap->version = KERNEL_VERSION(0, 0, 2); | |
| 651 | + vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; | |
| 652 | + return 0; | |
| 653 | +} | |
| 798 | 654 | |
| 799 | − /* We must update the camera before we grab. We could | |
| 800 | − just have changed the grab size */ | |
| 801 | − qcam->status |= QC_PARAM_CHANGE; | |
| 655 | +static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin) | |
| 656 | +{ | |
| 657 | + if (vin->index > 0) | |
| 658 | + return -EINVAL; | |
| 659 | + strlcpy(vin->name, "Camera", sizeof(vin->name)); | |
| 660 | + vin->type = V4L2_INPUT_TYPE_CAMERA; | |
| 661 | + vin->audioset = 0; | |
| 662 | + vin->tuner = 0; | |
| 663 | + vin->std = 0; | |
| 664 | + vin->status = 0; | |
| 665 | + return 0; | |
| 666 | +} | |
| 802 | 667 | |
| 803 | − /* Ok we figured out what to use from our wide choice */ | |
| 804 | − return 0; | |
| 805 | − } | |
| 806 | − case VIDIOCGWIN: | |
| 807 | − { | |
| 808 | − struct video_window *vw = arg; | |
| 668 | +static int qcam_g_input(struct file *file, void *fh, unsigned int *inp) | |
| 669 | +{ | |
| 670 | + *inp = 0; | |
| 671 | + return 0; | |
| 672 | +} | |
| 809 | 673 | |
| 810 | − memset(vw, 0, sizeof(*vw)); | |
| 811 | − vw->width = qcam->width / qcam->transfer_scale; | |
| 812 | − vw->height = qcam->height / qcam->transfer_scale; | |
| 813 | − return 0; | |
| 814 | − } | |
| 815 | − case VIDIOCKEY: | |
| 816 | − return 0; | |
| 817 | − case VIDIOCCAPTURE: | |
| 818 | − case VIDIOCGFBUF: | |
| 819 | − case VIDIOCSFBUF: | |
| 820 | − case VIDIOCGFREQ: | |
| 821 | − case VIDIOCSFREQ: | |
| 822 | − case VIDIOCGAUDIO: | |
| 823 | − case VIDIOCSAUDIO: | |
| 824 | − return -EINVAL; | |
| 674 | +static int qcam_s_input(struct file *file, void *fh, unsigned int inp) | |
| 675 | +{ | |
| 676 | + return (inp > 0) ? -EINVAL : 0; | |
| 677 | +} | |
| 678 | + | |
| 679 | +static int qcam_queryctrl(struct file *file, void *priv, | |
| 680 | + struct v4l2_queryctrl *qc) | |
| 681 | +{ | |
| 682 | + switch (qc->id) { | |
| 683 | + case V4L2_CID_BRIGHTNESS: | |
| 684 | + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180); | |
| 685 | + case V4L2_CID_CONTRAST: | |
| 686 | + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192); | |
| 687 | + case V4L2_CID_GAMMA: | |
| 688 | + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105); | |
| 689 | + } | |
| 690 | + return -EINVAL; | |
| 691 | +} | |
| 692 | + | |
| 693 | +static int qcam_g_ctrl(struct file *file, void *priv, | |
| 694 | + struct v4l2_control *ctrl) | |
| 695 | +{ | |
| 696 | + struct qcam *qcam = video_drvdata(file); | |
| 697 | + int ret = 0; | |
| 698 | + | |
| 699 | + switch (ctrl->id) { | |
| 700 | + case V4L2_CID_BRIGHTNESS: | |
| 701 | + ctrl->value = qcam->brightness; | |
| 702 | + break; | |
| 703 | + case V4L2_CID_CONTRAST: | |
| 704 | + ctrl->value = qcam->contrast; | |
| 705 | + break; | |
| 706 | + case V4L2_CID_GAMMA: | |
| 707 | + ctrl->value = qcam->whitebal; | |
| 708 | + break; | |
| 825 | 709 | default: |
| 826 | − return -ENOIOCTLCMD; | |
| 710 | + ret = -EINVAL; | |
| 711 | + break; | |
| 827 | 712 | } |
| 713 | + return ret; | |
| 714 | +} | |
| 715 | + | |
| 716 | +static int qcam_s_ctrl(struct file *file, void *priv, | |
| 717 | + struct v4l2_control *ctrl) | |
| 718 | +{ | |
| 719 | + struct qcam *qcam = video_drvdata(file); | |
| 720 | + int ret = 0; | |
| 721 | + | |
| 722 | + mutex_lock(&qcam->lock); | |
| 723 | + switch (ctrl->id) { | |
| 724 | + case V4L2_CID_BRIGHTNESS: | |
| 725 | + qcam->brightness = ctrl->value; | |
| 726 | + break; | |
| 727 | + case V4L2_CID_CONTRAST: | |
| 728 | + qcam->contrast = ctrl->value; | |
| 729 | + break; | |
| 730 | + case V4L2_CID_GAMMA: | |
| 731 | + qcam->whitebal = ctrl->value; | |
| 732 | + break; | |
| 733 | + default: | |
| 734 | + ret = -EINVAL; | |
| 735 | + break; | |
| 736 | + } | |
| 737 | + if (ret == 0) { | |
| 738 | + qc_setscanmode(qcam); | |
| 739 | + qcam->status |= QC_PARAM_CHANGE; | |
| 740 | + } | |
| 741 | + mutex_unlock(&qcam->lock); | |
| 742 | + return ret; | |
| 743 | +} | |
| 744 | + | |
| 745 | +static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | |
| 746 | +{ | |
| 747 | + struct qcam *qcam = video_drvdata(file); | |
| 748 | + struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
| 749 | + | |
| 750 | + pix->width = qcam->width / qcam->transfer_scale; | |
| 751 | + pix->height = qcam->height / qcam->transfer_scale; | |
| 752 | + pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6; | |
| 753 | + pix->field = V4L2_FIELD_NONE; | |
| 754 | + pix->bytesperline = qcam->width; | |
| 755 | + pix->sizeimage = qcam->width * qcam->height; | |
| 756 | + /* Just a guess */ | |
| 757 | + pix->colorspace = V4L2_COLORSPACE_SRGB; | |
| 758 | + return 0; | |
| 759 | +} | |
| 760 | + | |
| 761 | +static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | |
| 762 | +{ | |
| 763 | + struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
| 764 | + | |
| 765 | + if (pix->height <= 60 || pix->width <= 80) { | |
| 766 | + pix->height = 60; | |
| 767 | + pix->width = 80; | |
| 768 | + } else if (pix->height <= 120 || pix->width <= 160) { | |
| 769 | + pix->height = 120; | |
| 770 | + pix->width = 160; | |
| 771 | + } else { | |
| 772 | + pix->height = 240; | |
| 773 | + pix->width = 320; | |
| 774 | + } | |
| 775 | + if (pix->pixelformat != V4L2_PIX_FMT_Y4 && | |
| 776 | + pix->pixelformat != V4L2_PIX_FMT_Y6) | |
| 777 | + pix->pixelformat = V4L2_PIX_FMT_Y4; | |
| 778 | + pix->field = V4L2_FIELD_NONE; | |
| 779 | + pix->bytesperline = pix->width; | |
| 780 | + pix->sizeimage = pix->width * pix->height; | |
| 781 | + /* Just a guess */ | |
| 782 | + pix->colorspace = V4L2_COLORSPACE_SRGB; | |
| 783 | + return 0; | |
| 784 | +} | |
| 785 | + | |
| 786 | +static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | |
| 787 | +{ | |
| 788 | + struct qcam *qcam = video_drvdata(file); | |
| 789 | + struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
| 790 | + int ret = qcam_try_fmt_vid_cap(file, fh, fmt); | |
| 791 | + | |
| 792 | + if (ret) | |
| 793 | + return ret; | |
| 794 | + qcam->width = 320; | |
| 795 | + qcam->height = 240; | |
| 796 | + if (pix->height == 60) | |
| 797 | + qcam->transfer_scale = 4; | |
| 798 | + else if (pix->height == 120) | |
| 799 | + qcam->transfer_scale = 2; | |
| 800 | + else | |
| 801 | + qcam->transfer_scale = 1; | |
| 802 | + if (pix->pixelformat == V4L2_PIX_FMT_Y6) | |
| 803 | + qcam->bpp = 6; | |
| 804 | + else | |
| 805 | + qcam->bpp = 4; | |
| 806 | + | |
| 807 | + mutex_lock(&qcam->lock); | |
| 808 | + qc_setscanmode(qcam); | |
| 809 | + /* We must update the camera before we grab. We could | |
| 810 | + just have changed the grab size */ | |
| 811 | + qcam->status |= QC_PARAM_CHANGE; | |
| 812 | + mutex_unlock(&qcam->lock); | |
| 828 | 813 | return 0; |
| 829 | 814 | } |
| 830 | 815 | |
| 831 | −static long qcam_ioctl(struct file *file, | |
| 832 | − unsigned int cmd, unsigned long arg) | |
| 816 | +static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) | |
| 833 | 817 | { |
| 834 | − return video_usercopy(file, cmd, arg, qcam_do_ioctl); | |
| 818 | + static struct v4l2_fmtdesc formats[] = { | |
| 819 | + { 0, 0, 0, | |
| 820 | + "4-Bit Monochrome", V4L2_PIX_FMT_Y4, | |
| 821 | + { 0, 0, 0, 0 } | |
| 822 | + }, | |
| 823 | + { 0, 0, 0, | |
| 824 | + "6-Bit Monochrome", V4L2_PIX_FMT_Y6, | |
| 825 | + { 0, 0, 0, 0 } | |
| 826 | + }, | |
| 827 | + }; | |
| 828 | + enum v4l2_buf_type type = fmt->type; | |
| 829 | + | |
| 830 | + if (fmt->index > 1) | |
| 831 | + return -EINVAL; | |
| 832 | + | |
| 833 | + *fmt = formats[fmt->index]; | |
| 834 | + fmt->type = type; | |
| 835 | + return 0; | |
| 835 | 836 | } |
| 836 | 837 | |
| 837 | 838 | static ssize_t qcam_read(struct file *file, char __user *buf, |
| 838 | 839 | size_t count, loff_t *ppos) |
| 839 | 840 | { |
| 840 | − struct video_device *v = video_devdata(file); | |
| 841 | − struct qcam_device *qcam = (struct qcam_device *)v; | |
| 841 | + struct qcam *qcam = video_drvdata(file); | |
| 842 | 842 | int len; |
| 843 | 843 | parport_claim_or_block(qcam->pdev); |
| 844 | 844 | |
| @@ -858,43 +858,112 @@ static ssize_t qcam_read(struct file *file, char __user *buf, · 13 unmodified lines | ||
| 858 | 858 | return len; |
| 859 | 859 | } |
| 860 | 860 | |
| 861 | −static int qcam_exclusive_open(struct file *file) | |
| 861 | +static const struct v4l2_file_operations qcam_fops = { | |
| 862 | + .owner = THIS_MODULE, | |
| 863 | + .ioctl = video_ioctl2, | |
| 864 | + .read = qcam_read, | |
| 865 | +}; | |
| 866 | + | |
| 867 | +static const struct v4l2_ioctl_ops qcam_ioctl_ops = { | |
| 868 | + .vidioc_querycap = qcam_querycap, | |
| 869 | + .vidioc_g_input = qcam_g_input, | |
| 870 | + .vidioc_s_input = qcam_s_input, | |
| 871 | + .vidioc_enum_input = qcam_enum_input, | |
| 872 | + .vidioc_queryctrl = qcam_queryctrl, | |
| 873 | + .vidioc_g_ctrl = qcam_g_ctrl, | |
| 874 | + .vidioc_s_ctrl = qcam_s_ctrl, | |
| 875 | + .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, | |
| 876 | + .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, | |
| 877 | + .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, | |
| 878 | + .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, | |
| 879 | +}; | |
| 880 | + | |
| 881 | +/* Initialize the QuickCam driver control structure. This is where | |
| 882 | + * defaults are set for people who don't have a config file.*/ | |
| 883 | + | |
| 884 | +static struct qcam *qcam_init(struct parport *port) | |
| 862 | 885 | { |
| 863 | − struct video_device *dev = video_devdata(file); | |
| 864 | − struct qcam_device *qcam = (struct qcam_device *)dev; | |
| 886 | + struct qcam *qcam; | |
| 887 | + struct v4l2_device *v4l2_dev; | |
| 888 | + | |
| 889 | + qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL); | |
| 890 | + if (qcam == NULL) | |
| 891 | + return NULL; | |
| 892 | + | |
| 893 | + v4l2_dev = &qcam->v4l2_dev; | |
| 894 | + strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name)); | |
| 865 | 895 | |
| 866 | − return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; | |
| 896 | + if (v4l2_device_register(NULL, v4l2_dev) < 0) { | |
| 897 | + v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); | |
| 898 | + return NULL; | |
| 899 | + } | |
| 900 | + | |
| 901 | + qcam->pport = port; | |
| 902 | + qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, | |
| 903 | + NULL, 0, NULL); | |
| 904 | + if (qcam->pdev == NULL) { | |
| 905 | + v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); | |
| 906 | + kfree(qcam); | |
| 907 | + return NULL; | |
| 908 | + } | |
| 909 | + | |
| 910 | + strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name)); | |
| 911 | + qcam->vdev.v4l2_dev = v4l2_dev; | |
| 912 | + qcam->vdev.fops = &qcam_fops; | |
| 913 | + qcam->vdev.ioctl_ops = &qcam_ioctl_ops; | |
| 914 | + qcam->vdev.release = video_device_release_empty; | |
| 915 | + video_set_drvdata(&qcam->vdev, qcam); | |
| 916 | + | |
| 917 | + mutex_init(&qcam->lock); | |
| 918 | + | |
| 919 | + qcam->port_mode = (QC_ANY | QC_NOTSET); | |
| 920 | + qcam->width = 320; | |
| 921 | + qcam->height = 240; | |
| 922 | + qcam->bpp = 4; | |
| 923 | + qcam->transfer_scale = 2; | |
| 924 | + qcam->contrast = 192; | |
| 925 | + qcam->brightness = 180; | |
| 926 | + qcam->whitebal = 105; | |
| 927 | + qcam->top = 1; | |
| 928 | + qcam->left = 14; | |
| 929 | + qcam->mode = -1; | |
| 930 | + qcam->status = QC_PARAM_CHANGE; | |
| 931 | + return qcam; | |
| 867 | 932 | } |
| 868 | 933 | |
| 869 | −static int qcam_exclusive_release(struct file *file) | |
| 934 | +static int qc_calibrate(struct qcam *q) | |
| 870 | 935 | { |
| 871 | − struct video_device *dev = video_devdata(file); | |
| 872 | − struct qcam_device *qcam = (struct qcam_device *)dev; | |
| 936 | + /* | |
| 937 | + * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96 | |
| 938 | + * The white balance is an individual value for each | |
| 939 | + * quickcam. | |
| 940 | + */ | |
| 873 | 941 | |
| 874 | − clear_bit(0, &qcam->in_use); | |
| 875 | − return 0; | |
| 876 | −} | |
| 942 | + int value; | |
| 943 | + int count = 0; | |
| 877 | 944 | |
| 878 | −static const struct v4l2_file_operations qcam_fops = { | |
| 879 | − .owner = THIS_MODULE, | |
| 880 | − .open = qcam_exclusive_open, | |
| 881 | − .release = qcam_exclusive_release, | |
| 882 | − .ioctl = qcam_ioctl, | |
| 883 | − .read = qcam_read, | |
| 884 | −}; | |
| 885 | −static struct video_device qcam_template = { | |
| 886 | − .name = "Connectix Quickcam", | |
| 887 | − .fops = &qcam_fops, | |
| 888 | − .release = video_device_release_empty, | |
| 889 | −}; | |
| 945 | + qc_command(q, 27); /* AutoAdjustOffset */ | |
| 946 | + qc_command(q, 0); /* Dummy Parameter, ignored by the camera */ | |
| 890 | 947 | |
| 891 | −#define MAX_CAMS 4 | |
| 892 | −static struct qcam_device *qcams[MAX_CAMS]; | |
| 893 | −static unsigned int num_cams; | |
| 948 | + /* GetOffset (33) will read 255 until autocalibration */ | |
| 949 | + /* is finished. After that, a value of 1-254 will be */ | |
| 950 | + /* returned. */ | |
| 951 | + | |
| 952 | + do { | |
| 953 | + qc_command(q, 33); | |
| 954 | + value = qc_readparam(q); | |
| 955 | + mdelay(1); | |
| 956 | + schedule(); | |
| 957 | + count++; | |
| 958 | + } while (value == 0xff && count < 2048); | |
| 959 | + | |
| 960 | + q->whitebal = value; | |
| 961 | + return value; | |
| 962 | +} | |
| 894 | 963 | |
| 895 | 964 | static int init_bwqcam(struct parport *port) |
| 896 | 965 | { |
| 897 | − struct qcam_device *qcam; | |
| 966 | + struct qcam *qcam; | |
| 898 | 967 | |
| 899 | 968 | if (num_cams == MAX_CAMS) { |
| 900 | 969 | printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS); |
| @@ -919,7 +988,7 @@ static int init_bwqcam(struct parport *port) · 18 unmodified lines | ||
| 919 | 988 | |
| 920 | 989 | parport_release(qcam->pdev); |
| 921 | 990 | |
| 922 | − printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name); | |
| 991 | + v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name); | |
| 923 | 992 | |
| 924 | 993 | if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { |
| 925 | 994 | parport_unregister_device(qcam->pdev); |
| @@ -932,7 +1001,7 @@ static int init_bwqcam(struct parport *port) · 6 unmodified lines | ||
| 932 | 1001 | return 0; |
| 933 | 1002 | } |
| 934 | 1003 | |
| 935 | −static void close_bwqcam(struct qcam_device *qcam) | |
| 1004 | +static void close_bwqcam(struct qcam *qcam) | |
| 936 | 1005 | { |
| 937 | 1006 | video_unregister_device(&qcam->vdev); |
| 938 | 1007 | parport_unregister_device(qcam->pdev); |
| @@ -983,7 +1052,7 @@ static void bwqcam_detach(struct parport *port) · 44 unmodified lines | ||
| 983 | 1052 | { |
| 984 | 1053 | int i; |
| 985 | 1054 | for (i = 0; i < num_cams; i++) { |
| 986 | − struct qcam_device *qcam = qcams[i]; | |
| 1055 | + struct qcam *qcam = qcams[i]; | |
| 987 | 1056 | if (qcam && qcam->pdev->port == port) { |
| 988 | 1057 | qcams[i] = NULL; |
| 989 | 1058 | close_bwqcam(qcam); |
| @@ -1,69 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * Video4Linux bw-qcam driver | |
| 3 | − * | |
| 4 | − * Derived from code.. | |
| 5 | − */ | |
| 6 | − | |
| 7 | −/****************************************************************** | |
| 8 | − | |
| 9 | −Copyright (C) 1996 by Scott Laird | |
| 10 | − | |
| 11 | −Permission is hereby granted, free of charge, to any person obtaining | |
| 12 | −a copy of this software and associated documentation files (the | |
| 13 | −"Software"), to deal in the Software without restriction, including | |
| 14 | −without limitation the rights to use, copy, modify, merge, publish, | |
| 15 | −distribute, sublicense, and/or sell copies of the Software, and to | |
| 16 | −permit persons to whom the Software is furnished to do so, subject to | |
| 17 | −the following conditions: | |
| 18 | − | |
| 19 | −The above copyright notice and this permission notice shall be | |
| 20 | −included in all copies or substantial portions of the Software. | |
| 21 | − | |
| 22 | −THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 23 | −EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| 24 | −MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
| 25 | −IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 26 | −OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 27 | −ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 28 | −OTHER DEALINGS IN THE SOFTWARE. | |
| 29 | − | |
| 30 | −******************************************************************/ | |
| 31 | − | |
| 32 | −/* One from column A... */ | |
| 33 | −#define QC_NOTSET 0 | |
| 34 | −#define QC_UNIDIR 1 | |
| 35 | −#define QC_BIDIR 2 | |
| 36 | −#define QC_SERIAL 3 | |
| 37 | − | |
| 38 | −/* ... and one from column B */ | |
| 39 | −#define QC_ANY 0x00 | |
| 40 | −#define QC_FORCE_UNIDIR 0x10 | |
| 41 | −#define QC_FORCE_BIDIR 0x20 | |
| 42 | −#define QC_FORCE_SERIAL 0x30 | |
| 43 | −/* in the port_mode member */ | |
| 44 | − | |
| 45 | −#define QC_MODE_MASK 0x07 | |
| 46 | −#define QC_FORCE_MASK 0x70 | |
| 47 | − | |
| 48 | −#define MAX_HEIGHT 243 | |
| 49 | −#define MAX_WIDTH 336 | |
| 50 | − | |
| 51 | −/* Bit fields for status flags */ | |
| 52 | −#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */ | |
| 53 | − | |
| 54 | −struct qcam_device { | |
| 55 | − struct video_device vdev; | |
| 56 | − struct pardevice *pdev; | |
| 57 | − struct parport *pport; | |
| 58 | − struct mutex lock; | |
| 59 | − int width, height; | |
| 60 | − int bpp; | |
| 61 | − int mode; | |
| 62 | − int contrast, brightness, whitebal; | |
| 63 | − int port_mode; | |
| 64 | − int transfer_scale; | |
| 65 | − int top, left; | |
| 66 | − int status; | |
| 67 | − unsigned int saved_bits; | |
| 68 | − unsigned long in_use; | |
| 69 | −}; | |
| @@ -33,15 +33,17 @@ · 32 unmodified lines | ||
| 33 | 33 | #include <linux/mm.h> |
| 34 | 34 | #include <linux/parport.h> |
| 35 | 35 | #include <linux/sched.h> |
| 36 | −#include <linux/videodev.h> | |
| 37 | −#include <media/v4l2-common.h> | |
| 38 | −#include <media/v4l2-ioctl.h> | |
| 39 | 36 | #include <linux/mutex.h> |
| 40 | 37 | #include <linux/jiffies.h> |
| 41 | − | |
| 38 | +#include <linux/version.h> | |
| 39 | +#include <linux/videodev2.h> | |
| 42 | 40 | #include <asm/uaccess.h> |
| 41 | +#include <media/v4l2-device.h> | |
| 42 | +#include <media/v4l2-common.h> | |
| 43 | +#include <media/v4l2-ioctl.h> | |
| 43 | 44 | |
| 44 | −struct qcam_device { | |
| 45 | +struct qcam { | |
| 46 | + struct v4l2_device v4l2_dev; | |
| 45 | 47 | struct video_device vdev; |
| 46 | 48 | struct pardevice *pdev; |
| 47 | 49 | struct parport *pport; |
| @@ -51,7 +53,6 @@ struct qcam_device { · 3 unmodified lines | ||
| 51 | 53 | int contrast, brightness, whitebal; |
| 52 | 54 | int top, left; |
| 53 | 55 | unsigned int bidirectional; |
| 54 | − unsigned long in_use; | |
| 55 | 56 | struct mutex lock; |
| 56 | 57 | }; |
| 57 | 58 | |
| @@ -68,33 +69,45 @@ struct qcam_device { · 10 unmodified lines | ||
| 68 | 69 | #define QC_DECIMATION_2 2 |
| 69 | 70 | #define QC_DECIMATION_4 4 |
| 70 | 71 | |
| 71 | −#define BANNER "Colour QuickCam for Video4Linux v0.05" | |
| 72 | +#define BANNER "Colour QuickCam for Video4Linux v0.06" | |
| 72 | 73 | |
| 73 | 74 | static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 }; |
| 74 | 75 | static int probe = 2; |
| 75 | 76 | static int force_rgb; |
| 76 | 77 | static int video_nr = -1; |
| 77 | 78 | |
| 78 | −static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i) | |
| 79 | +/* FIXME: parport=auto would never have worked, surely? --RR */ | |
| 80 | +MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n" | |
| 81 | + "probe=<0|1|2> for camera detection method\n" | |
| 82 | + "force_rgb=<0|1> for RGB data format (default BGR)"); | |
| 83 | +module_param_array(parport, int, NULL, 0); | |
| 84 | +module_param(probe, int, 0); | |
| 85 | +module_param(force_rgb, bool, 0); | |
| 86 | +module_param(video_nr, int, 0); | |
| 87 | + | |
| 88 | +static struct qcam *qcams[MAX_CAMS]; | |
| 89 | +static unsigned int num_cams; | |
| 90 | + | |
| 91 | +static inline void qcam_set_ack(struct qcam *qcam, unsigned int i) | |
| 79 | 92 | { |
| 80 | 93 | /* note: the QC specs refer to the PCAck pin by voltage, not |
| 81 | 94 | software level. PC ports have builtin inverters. */ |
| 82 | 95 | parport_frob_control(qcam->pport, 8, i ? 8 : 0); |
| 83 | 96 | } |
| 84 | 97 | |
| 85 | −static inline unsigned int qcam_ready1(struct qcam_device *qcam) | |
| 98 | +static inline unsigned int qcam_ready1(struct qcam *qcam) | |
| 86 | 99 | { |
| 87 | 100 | return (parport_read_status(qcam->pport) & 0x8) ? 1 : 0; |
| 88 | 101 | } |
| 89 | 102 | |
| 90 | −static inline unsigned int qcam_ready2(struct qcam_device *qcam) | |
| 103 | +static inline unsigned int qcam_ready2(struct qcam *qcam) | |
| 91 | 104 | { |
| 92 | 105 | return (parport_read_data(qcam->pport) & 0x1) ? 1 : 0; |
| 93 | 106 | } |
| 94 | 107 | |
| 95 | −static unsigned int qcam_await_ready1(struct qcam_device *qcam, | |
| 96 | − int value) | |
| 108 | +static unsigned int qcam_await_ready1(struct qcam *qcam, int value) | |
| 97 | 109 | { |
| 110 | + struct v4l2_device *v4l2_dev = &qcam->v4l2_dev; | |
| 98 | 111 | unsigned long oldjiffies = jiffies; |
| 99 | 112 | unsigned int i; |
| 100 | 113 | |
| @@ -112,14 +125,15 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam, · 11 unmodified lines | ||
| 112 | 125 | } |
| 113 | 126 | |
| 114 | 127 | /* Probably somebody pulled the plug out. Not much we can do. */ |
| 115 | − printk(KERN_ERR "c-qcam: ready1 timeout (%d) %x %x\n", value, | |
| 128 | + v4l2_err(v4l2_dev, "ready1 timeout (%d) %x %x\n", value, | |
| 116 | 129 | parport_read_status(qcam->pport), |
| 117 | 130 | parport_read_control(qcam->pport)); |
| 118 | 131 | return 1; |
| 119 | 132 | } |
| 120 | 133 | |
| 121 | −static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value) | |
| 134 | +static unsigned int qcam_await_ready2(struct qcam *qcam, int value) | |
| 122 | 135 | { |
| 136 | + struct v4l2_device *v4l2_dev = &qcam->v4l2_dev; | |
| 123 | 137 | unsigned long oldjiffies = jiffies; |
| 124 | 138 | unsigned int i; |
| 125 | 139 | |
| @@ -137,14 +151,14 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value) · 11 unmodified lines | ||
| 137 | 151 | } |
| 138 | 152 | |
| 139 | 153 | /* Probably somebody pulled the plug out. Not much we can do. */ |
| 140 | − printk(KERN_ERR "c-qcam: ready2 timeout (%d) %x %x %x\n", value, | |
| 154 | + v4l2_err(v4l2_dev, "ready2 timeout (%d) %x %x %x\n", value, | |
| 141 | 155 | parport_read_status(qcam->pport), |
| 142 | 156 | parport_read_control(qcam->pport), |
| 143 | 157 | parport_read_data(qcam->pport)); |
| 144 | 158 | return 1; |
| 145 | 159 | } |
| 146 | 160 | |
| 147 | −static int qcam_read_data(struct qcam_device *qcam) | |
| 161 | +static int qcam_read_data(struct qcam *qcam) | |
| 148 | 162 | { |
| 149 | 163 | unsigned int idata; |
| 150 | 164 | |
| @@ -159,21 +173,22 @@ static int qcam_read_data(struct qcam_device *qcam) · 8 unmodified lines | ||
| 159 | 173 | return idata; |
| 160 | 174 | } |
| 161 | 175 | |
| 162 | −static int qcam_write_data(struct qcam_device *qcam, unsigned int data) | |
| 176 | +static int qcam_write_data(struct qcam *qcam, unsigned int data) | |
| 163 | 177 | { |
| 178 | + struct v4l2_device *v4l2_dev = &qcam->v4l2_dev; | |
| 164 | 179 | unsigned int idata; |
| 165 | 180 | |
| 166 | 181 | parport_write_data(qcam->pport, data); |
| 167 | 182 | idata = qcam_read_data(qcam); |
| 168 | 183 | if (data != idata) { |
| 169 | − printk(KERN_WARNING "cqcam: sent %x but received %x\n", data, | |
| 184 | + v4l2_warn(v4l2_dev, "sent %x but received %x\n", data, | |
| 170 | 185 | idata); |
| 171 | 186 | return 1; |
| 172 | 187 | } |
| 173 | 188 | return 0; |
| 174 | 189 | } |
| 175 | 190 | |
| 176 | −static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data) | |
| 191 | +static inline int qcam_set(struct qcam *qcam, unsigned int cmd, unsigned int data) | |
| 177 | 192 | { |
| 178 | 193 | if (qcam_write_data(qcam, cmd)) |
| 179 | 194 | return -1; |
| @@ -182,14 +197,14 @@ static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned · 2 unmodified lines | ||
| 182 | 197 | return 0; |
| 183 | 198 | } |
| 184 | 199 | |
| 185 | −static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd) | |
| 200 | +static inline int qcam_get(struct qcam *qcam, unsigned int cmd) | |
| 186 | 201 | { |
| 187 | 202 | if (qcam_write_data(qcam, cmd)) |
| 188 | 203 | return -1; |
| 189 | 204 | return qcam_read_data(qcam); |
| 190 | 205 | } |
| 191 | 206 | |
| 192 | −static int qc_detect(struct qcam_device *qcam) | |
| 207 | +static int qc_detect(struct qcam *qcam) | |
| 193 | 208 | { |
| 194 | 209 | unsigned int stat, ostat, i, count = 0; |
| 195 | 210 | |
| @@ -246,7 +261,7 @@ static int qc_detect(struct qcam_device *qcam) · 50 unmodified lines | ||
| 246 | 261 | return 0; |
| 247 | 262 | } |
| 248 | 263 | |
| 249 | −static void qc_reset(struct qcam_device *qcam) | |
| 264 | +static void qc_reset(struct qcam *qcam) | |
| 250 | 265 | { |
| 251 | 266 | parport_write_control(qcam->pport, 0xc); |
| 252 | 267 | parport_write_control(qcam->pport, 0x8); |
| @@ -258,55 +273,55 @@ static void qc_reset(struct qcam_device *qcam) · 5 unmodified lines | ||
| 258 | 273 | /* Reset the QuickCam and program for brightness, contrast, |
| 259 | 274 | * white-balance, and resolution. */ |
| 260 | 275 | |
| 261 | −static void qc_setup(struct qcam_device *q) | |
| 276 | +static void qc_setup(struct qcam *qcam) | |
| 262 | 277 | { |
| 263 | − qc_reset(q); | |
| 278 | + qc_reset(qcam); | |
| 264 | 279 | |
| 265 | 280 | /* Set the brightness. */ |
| 266 | − qcam_set(q, 11, q->brightness); | |
| 281 | + qcam_set(qcam, 11, qcam->brightness); | |
| 267 | 282 | |
| 268 | 283 | /* Set the height and width. These refer to the actual |
| 269 | 284 | CCD area *before* applying the selected decimation. */ |
| 270 | − qcam_set(q, 17, q->ccd_height); | |
| 271 | − qcam_set(q, 19, q->ccd_width / 2); | |
| 285 | + qcam_set(qcam, 17, qcam->ccd_height); | |
| 286 | + qcam_set(qcam, 19, qcam->ccd_width / 2); | |
| 272 | 287 | |
| 273 | 288 | /* Set top and left. */ |
| 274 | − qcam_set(q, 0xd, q->top); | |
| 275 | − qcam_set(q, 0xf, q->left); | |
| 289 | + qcam_set(qcam, 0xd, qcam->top); | |
| 290 | + qcam_set(qcam, 0xf, qcam->left); | |
| 276 | 291 | |
| 277 | 292 | /* Set contrast and white balance. */ |
| 278 | − qcam_set(q, 0x19, q->contrast); | |
| 279 | − qcam_set(q, 0x1f, q->whitebal); | |
| 293 | + qcam_set(qcam, 0x19, qcam->contrast); | |
| 294 | + qcam_set(qcam, 0x1f, qcam->whitebal); | |
| 280 | 295 | |
| 281 | 296 | /* Set the speed. */ |
| 282 | − qcam_set(q, 45, 2); | |
| 297 | + qcam_set(qcam, 45, 2); | |
| 283 | 298 | } |
| 284 | 299 | |
| 285 | 300 | /* Read some bytes from the camera and put them in the buffer. |
| 286 | 301 | nbytes should be a multiple of 3, because bidirectional mode gives |
| 287 | 302 | us three bytes at a time. */ |
| 288 | 303 | |
| 289 | −static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes) | |
| 304 | +static unsigned int qcam_read_bytes(struct qcam *qcam, unsigned char *buf, unsigned int nbytes) | |
| 290 | 305 | { |
| 291 | 306 | unsigned int bytes = 0; |
| 292 | 307 | |
| 293 | − qcam_set_ack(q, 0); | |
| 294 | − if (q->bidirectional) { | |
| 308 | + qcam_set_ack(qcam, 0); | |
| 309 | + if (qcam->bidirectional) { | |
| 295 | 310 | /* It's a bidirectional port */ |
| 296 | 311 | while (bytes < nbytes) { |
| 297 | 312 | unsigned int lo1, hi1, lo2, hi2; |
| 298 | 313 | unsigned char r, g, b; |
| 299 | 314 | |
| 300 | − if (qcam_await_ready2(q, 1)) | |
| 315 | + if (qcam_await_ready2(qcam, 1)) | |
| 301 | 316 | return bytes; |
| 302 | − lo1 = parport_read_data(q->pport) >> 1; | |
| 303 | − hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; | |
| 304 | − qcam_set_ack(q, 1); | |
| 305 | − if (qcam_await_ready2(q, 0)) | |
| 317 | + lo1 = parport_read_data(qcam->pport) >> 1; | |
| 318 | + hi1 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10; | |
| 319 | + qcam_set_ack(qcam, 1); | |
| 320 | + if (qcam_await_ready2(qcam, 0)) | |
| 306 | 321 | return bytes; |
| 307 | − lo2 = parport_read_data(q->pport) >> 1; | |
| 308 | − hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; | |
| 309 | − qcam_set_ack(q, 0); | |
| 322 | + lo2 = parport_read_data(qcam->pport) >> 1; | |
| 323 | + hi2 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10; | |
| 324 | + qcam_set_ack(qcam, 0); | |
| 310 | 325 | r = lo1 | ((hi1 & 1) << 7); |
| 311 | 326 | g = ((hi1 & 0x1e) << 3) | ((hi2 & 0x1e) >> 1); |
| 312 | 327 | b = lo2 | ((hi2 & 1) << 7); |
| @@ -328,14 +343,14 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, u · 15 unmodified lines | ||
| 328 | 343 | while (bytes < nbytes) { |
| 329 | 344 | unsigned int hi, lo; |
| 330 | 345 | |
| 331 | − if (qcam_await_ready1(q, 1)) | |
| 346 | + if (qcam_await_ready1(qcam, 1)) | |
| 332 | 347 | return bytes; |
| 333 | − hi = (parport_read_status(q->pport) & 0xf0); | |
| 334 | − qcam_set_ack(q, 1); | |
| 335 | − if (qcam_await_ready1(q, 0)) | |
| 348 | + hi = (parport_read_status(qcam->pport) & 0xf0); | |
| 349 | + qcam_set_ack(qcam, 1); | |
| 350 | + if (qcam_await_ready1(qcam, 0)) | |
| 336 | 351 | return bytes; |
| 337 | − lo = (parport_read_status(q->pport) & 0xf0); | |
| 338 | − qcam_set_ack(q, 0); | |
| 352 | + lo = (parport_read_status(qcam->pport) & 0xf0); | |
| 353 | + qcam_set_ack(qcam, 0); | |
| 339 | 354 | /* flip some bits */ |
| 340 | 355 | rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88; |
| 341 | 356 | if (i >= 2) { |
| @@ -361,10 +376,11 @@ get_fragment: · 19 unmodified lines | ||
| 361 | 376 | |
| 362 | 377 | #define BUFSZ 150 |
| 363 | 378 | |
| 364 | −static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len) | |
| 379 | +static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len) | |
| 365 | 380 | { |
| 381 | + struct v4l2_device *v4l2_dev = &qcam->v4l2_dev; | |
| 366 | 382 | unsigned lines, pixelsperline, bitsperxfer; |
| 367 | − unsigned int is_bi_dir = q->bidirectional; | |
| 383 | + unsigned int is_bi_dir = qcam->bidirectional; | |
| 368 | 384 | size_t wantlen, outptr = 0; |
| 369 | 385 | char tmpbuf[BUFSZ]; |
| 370 | 386 | |
| @@ -373,10 +389,10 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le · 2 unmodified lines | ||
| 373 | 389 | |
| 374 | 390 | /* Wait for camera to become ready */ |
| 375 | 391 | for (;;) { |
| 376 | − int i = qcam_get(q, 41); | |
| 392 | + int i = qcam_get(qcam, 41); | |
| 377 | 393 | |
| 378 | 394 | if (i == -1) { |
| 379 | − qc_setup(q); | |
| 395 | + qc_setup(qcam); | |
| 380 | 396 | return -EIO; |
| 381 | 397 | } |
| 382 | 398 | if ((i & 0x80) == 0) |
| @@ -384,25 +400,25 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le · 1 unmodified line | ||
| 384 | 400 | schedule(); |
| 385 | 401 | } |
| 386 | 402 | |
| 387 | − if (qcam_set(q, 7, (q->mode | (is_bi_dir ? 1 : 0)) + 1)) | |
| 403 | + if (qcam_set(qcam, 7, (qcam->mode | (is_bi_dir ? 1 : 0)) + 1)) | |
| 388 | 404 | return -EIO; |
| 389 | 405 | |
| 390 | − lines = q->height; | |
| 391 | − pixelsperline = q->width; | |
| 406 | + lines = qcam->height; | |
| 407 | + pixelsperline = qcam->width; | |
| 392 | 408 | bitsperxfer = (is_bi_dir) ? 24 : 8; |
| 393 | 409 | |
| 394 | 410 | if (is_bi_dir) { |
| 395 | 411 | /* Turn the port around */ |
| 396 | − parport_data_reverse(q->pport); | |
| 412 | + parport_data_reverse(qcam->pport); | |
| 397 | 413 | mdelay(3); |
| 398 | − qcam_set_ack(q, 0); | |
| 399 | − if (qcam_await_ready1(q, 1)) { | |
| 400 | − qc_setup(q); | |
| 414 | + qcam_set_ack(qcam, 0); | |
| 415 | + if (qcam_await_ready1(qcam, 1)) { | |
| 416 | + qc_setup(qcam); | |
| 401 | 417 | return -EIO; |
| 402 | 418 | } |
| 403 | − qcam_set_ack(q, 1); | |
| 404 | − if (qcam_await_ready1(q, 0)) { | |
| 405 | − qc_setup(q); | |
| 419 | + qcam_set_ack(qcam, 1); | |
| 420 | + if (qcam_await_ready1(qcam, 0)) { | |
| 421 | + qc_setup(qcam); | |
| 406 | 422 | return -EIO; |
| 407 | 423 | } |
| 408 | 424 | } |
| @@ -413,7 +429,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le · 4 unmodified lines | ||
| 413 | 429 | size_t t, s; |
| 414 | 430 | |
| 415 | 431 | s = (wantlen > BUFSZ) ? BUFSZ : wantlen; |
| 416 | − t = qcam_read_bytes(q, tmpbuf, s); | |
| 432 | + t = qcam_read_bytes(qcam, tmpbuf, s); | |
| 417 | 433 | if (outptr < len) { |
| 418 | 434 | size_t sz = len - outptr; |
| 419 | 435 | |
| @@ -432,10 +448,10 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le · 12 unmodified lines | ||
| 432 | 448 | len = outptr; |
| 433 | 449 | |
| 434 | 450 | if (wantlen) { |
| 435 | − printk(KERN_ERR "qcam: short read.\n"); | |
| 451 | + v4l2_err(v4l2_dev, "short read.\n"); | |
| 436 | 452 | if (is_bi_dir) |
| 437 | − parport_data_forward(q->pport); | |
| 438 | − qc_setup(q); | |
| 453 | + parport_data_forward(qcam->pport); | |
| 454 | + qc_setup(qcam); | |
| 439 | 455 | return len; |
| 440 | 456 | } |
| 441 | 457 | |
| @@ -443,49 +459,49 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le · 1 unmodified line | ||
| 443 | 459 | int l; |
| 444 | 460 | |
| 445 | 461 | do { |
| 446 | − l = qcam_read_bytes(q, tmpbuf, 3); | |
| 462 | + l = qcam_read_bytes(qcam, tmpbuf, 3); | |
| 447 | 463 | cond_resched(); |
| 448 | 464 | } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e)); |
| 449 | 465 | if (force_rgb) { |
| 450 | 466 | if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) |
| 451 | − printk(KERN_ERR "qcam: bad EOF\n"); | |
| 467 | + v4l2_err(v4l2_dev, "bad EOF\n"); | |
| 452 | 468 | } else { |
| 453 | 469 | if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) |
| 454 | − printk(KERN_ERR "qcam: bad EOF\n"); | |
| 470 | + v4l2_err(v4l2_dev, "bad EOF\n"); | |
| 455 | 471 | } |
| 456 | − qcam_set_ack(q, 0); | |
| 457 | − if (qcam_await_ready1(q, 1)) { | |
| 458 | − printk(KERN_ERR "qcam: no ack after EOF\n"); | |
| 459 | − parport_data_forward(q->pport); | |
| 460 | − qc_setup(q); | |
| 472 | + qcam_set_ack(qcam, 0); | |
| 473 | + if (qcam_await_ready1(qcam, 1)) { | |
| 474 | + v4l2_err(v4l2_dev, "no ack after EOF\n"); | |
| 475 | + parport_data_forward(qcam->pport); | |
| 476 | + qc_setup(qcam); | |
| 461 | 477 | return len; |
| 462 | 478 | } |
| 463 | − parport_data_forward(q->pport); | |
| 479 | + parport_data_forward(qcam->pport); | |
| 464 | 480 | mdelay(3); |
| 465 | − qcam_set_ack(q, 1); | |
| 466 | − if (qcam_await_ready1(q, 0)) { | |
| 467 | − printk(KERN_ERR "qcam: no ack to port turnaround\n"); | |
| 468 | − qc_setup(q); | |
| 481 | + qcam_set_ack(qcam, 1); | |
| 482 | + if (qcam_await_ready1(qcam, 0)) { | |
| 483 | + v4l2_err(v4l2_dev, "no ack to port turnaround\n"); | |
| 484 | + qc_setup(qcam); | |
| 469 | 485 | return len; |
| 470 | 486 | } |
| 471 | 487 | } else { |
| 472 | 488 | int l; |
| 473 | 489 | |
| 474 | 490 | do { |
| 475 | − l = qcam_read_bytes(q, tmpbuf, 1); | |
| 491 | + l = qcam_read_bytes(qcam, tmpbuf, 1); | |
| 476 | 492 | cond_resched(); |
| 477 | 493 | } while (l && tmpbuf[0] == 0x7e); |
| 478 | − l = qcam_read_bytes(q, tmpbuf + 1, 2); | |
| 494 | + l = qcam_read_bytes(qcam, tmpbuf + 1, 2); | |
| 479 | 495 | if (force_rgb) { |
| 480 | 496 | if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) |
| 481 | − printk(KERN_ERR "qcam: bad EOF\n"); | |
| 497 | + v4l2_err(v4l2_dev, "bad EOF\n"); | |
| 482 | 498 | } else { |
| 483 | 499 | if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) |
| 484 | − printk(KERN_ERR "qcam: bad EOF\n"); | |
| 500 | + v4l2_err(v4l2_dev, "bad EOF\n"); | |
| 485 | 501 | } |
| 486 | 502 | } |
| 487 | 503 | |
| 488 | − qcam_write_data(q, 0); | |
| 504 | + qcam_write_data(qcam, 0); | |
| 489 | 505 | return len; |
| 490 | 506 | } |
| 491 | 507 | |
| @@ -493,184 +509,202 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le · 1 unmodified line | ||
| 493 | 509 | * Video4linux interfacing |
| 494 | 510 | */ |
| 495 | 511 | |
| 496 | −static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |
| 512 | +static int qcam_querycap(struct file *file, void *priv, | |
| 513 | + struct v4l2_capability *vcap) | |
| 497 | 514 | { |
| 498 | − struct video_device *dev = video_devdata(file); | |
| 499 | − struct qcam_device *qcam = (struct qcam_device *)dev; | |
| 515 | + struct qcam *qcam = video_drvdata(file); | |
| 500 | 516 | |
| 501 | − switch (cmd) { | |
| 502 | − case VIDIOCGCAP: | |
| 503 | − { | |
| 504 | − struct video_capability *b = arg; | |
| 517 | + strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); | |
| 518 | + strlcpy(vcap->card, "Color Quickcam", sizeof(vcap->card)); | |
| 519 | + strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); | |
| 520 | + vcap->version = KERNEL_VERSION(0, 0, 3); | |
| 521 | + vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; | |
| 522 | + return 0; | |
| 523 | +} | |
| 505 | 524 | |
| 506 | − strcpy(b->name, "Quickcam"); | |
| 507 | − b->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; | |
| 508 | − b->channels = 1; | |
| 509 | − b->audios = 0; | |
| 510 | − b->maxwidth = 320; | |
| 511 | − b->maxheight = 240; | |
| 512 | − b->minwidth = 80; | |
| 513 | − b->minheight = 60; | |
| 514 | − return 0; | |
| 515 | − } | |
| 516 | − case VIDIOCGCHAN: | |
| 517 | − { | |
| 518 | − struct video_channel *v = arg; | |
| 519 | − | |
| 520 | − if (v->channel != 0) | |
| 521 | − return -EINVAL; | |
| 522 | − v->flags = 0; | |
| 523 | − v->tuners = 0; | |
| 524 | − /* Good question.. its composite or SVHS so.. */ | |
| 525 | − v->type = VIDEO_TYPE_CAMERA; | |
| 526 | − strcpy(v->name, "Camera"); | |
| 527 | − return 0; | |
| 528 | − } | |
| 529 | − case VIDIOCSCHAN: | |
| 530 | − { | |
| 531 | − struct video_channel *v = arg; | |
| 525 | +static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin) | |
| 526 | +{ | |
| 527 | + if (vin->index > 0) | |
| 528 | + return -EINVAL; | |
| 529 | + strlcpy(vin->name, "Camera", sizeof(vin->name)); | |
| 530 | + vin->type = V4L2_INPUT_TYPE_CAMERA; | |
| 531 | + vin->audioset = 0; | |
| 532 | + vin->tuner = 0; | |
| 533 | + vin->std = 0; | |
| 534 | + vin->status = 0; | |
| 535 | + return 0; | |
| 536 | +} | |
| 532 | 537 | |
| 533 | − if (v->channel != 0) | |
| 534 | − return -EINVAL; | |
| 535 | − return 0; | |
| 536 | − } | |
| 537 | − case VIDIOCGTUNER: | |
| 538 | − { | |
| 539 | − struct video_tuner *v = arg; | |
| 540 | − | |
| 541 | − if (v->tuner) | |
| 542 | − return -EINVAL; | |
| 543 | − memset(v, 0, sizeof(*v)); | |
| 544 | − strcpy(v->name, "Format"); | |
| 545 | − v->mode = VIDEO_MODE_AUTO; | |
| 546 | − return 0; | |
| 538 | +static int qcam_g_input(struct file *file, void *fh, unsigned int *inp) | |
| 539 | +{ | |
| 540 | + *inp = 0; | |
| 541 | + return 0; | |
| 542 | +} | |
| 543 | + | |
| 544 | +static int qcam_s_input(struct file *file, void *fh, unsigned int inp) | |
| 545 | +{ | |
| 546 | + return (inp > 0) ? -EINVAL : 0; | |
| 547 | +} | |
| 548 | + | |
| 549 | +static int qcam_queryctrl(struct file *file, void *priv, | |
| 550 | + struct v4l2_queryctrl *qc) | |
| 551 | +{ | |
| 552 | + switch (qc->id) { | |
| 553 | + case V4L2_CID_BRIGHTNESS: | |
| 554 | + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 240); | |
| 555 | + case V4L2_CID_CONTRAST: | |
| 556 | + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192); | |
| 557 | + case V4L2_CID_GAMMA: | |
| 558 | + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); | |
| 547 | 559 | } |
| 548 | − case VIDIOCSTUNER: | |
| 549 | − { | |
| 550 | − struct video_tuner *v = arg; | |
| 551 | − | |
| 552 | − if (v->tuner) | |
| 553 | − return -EINVAL; | |
| 554 | − if (v->mode != VIDEO_MODE_AUTO) | |
| 555 | − return -EINVAL; | |
| 556 | − return 0; | |
| 560 | + return -EINVAL; | |
| 561 | +} | |
| 562 | + | |
| 563 | +static int qcam_g_ctrl(struct file *file, void *priv, | |
| 564 | + struct v4l2_control *ctrl) | |
| 565 | +{ | |
| 566 | + struct qcam *qcam = video_drvdata(file); | |
| 567 | + int ret = 0; | |
| 568 | + | |
| 569 | + switch (ctrl->id) { | |
| 570 | + case V4L2_CID_BRIGHTNESS: | |
| 571 | + ctrl->value = qcam->brightness; | |
| 572 | + break; | |
| 573 | + case V4L2_CID_CONTRAST: | |
| 574 | + ctrl->value = qcam->contrast; | |
| 575 | + break; | |
| 576 | + case V4L2_CID_GAMMA: | |
| 577 | + ctrl->value = qcam->whitebal; | |
| 578 | + break; | |
| 579 | + default: | |
| 580 | + ret = -EINVAL; | |
| 581 | + break; | |
| 557 | 582 | } |
| 558 | − case VIDIOCGPICT: | |
| 559 | − { | |
| 560 | − struct video_picture *p = arg; | |
| 561 | − | |
| 562 | − p->colour = 0x8000; | |
| 563 | − p->hue = 0x8000; | |
| 564 | − p->brightness = qcam->brightness << 8; | |
| 565 | − p->contrast = qcam->contrast << 8; | |
| 566 | − p->whiteness = qcam->whitebal << 8; | |
| 567 | − p->depth = 24; | |
| 568 | − p->palette = VIDEO_PALETTE_RGB24; | |
| 569 | − return 0; | |
| 583 | + return ret; | |
| 584 | +} | |
| 585 | + | |
| 586 | +static int qcam_s_ctrl(struct file *file, void *priv, | |
| 587 | + struct v4l2_control *ctrl) | |
| 588 | +{ | |
| 589 | + struct qcam *qcam = video_drvdata(file); | |
| 590 | + int ret = 0; | |
| 591 | + | |
| 592 | + mutex_lock(&qcam->lock); | |
| 593 | + switch (ctrl->id) { | |
| 594 | + case V4L2_CID_BRIGHTNESS: | |
| 595 | + qcam->brightness = ctrl->value; | |
| 596 | + break; | |
| 597 | + case V4L2_CID_CONTRAST: | |
| 598 | + qcam->contrast = ctrl->value; | |
| 599 | + break; | |
| 600 | + case V4L2_CID_GAMMA: | |
| 601 | + qcam->whitebal = ctrl->value; | |
| 602 | + break; | |
| 603 | + default: | |
| 604 | + ret = -EINVAL; | |
| 605 | + break; | |
| 570 | 606 | } |
| 571 | − case VIDIOCSPICT: | |
| 572 | − { | |
| 573 | − struct video_picture *p = arg; | |
| 574 | − | |
| 575 | − /* | |
| 576 | − * Sanity check args | |
| 577 | − */ | |
| 578 | − if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24) | |
| 579 | − return -EINVAL; | |
| 580 | − | |
| 581 | − /* | |
| 582 | − * Now load the camera. | |
| 583 | − */ | |
| 584 | − qcam->brightness = p->brightness >> 8; | |
| 585 | − qcam->contrast = p->contrast >> 8; | |
| 586 | − qcam->whitebal = p->whiteness >> 8; | |
| 587 | − | |
| 588 | − mutex_lock(&qcam->lock); | |
| 607 | + if (ret == 0) { | |
| 589 | 608 | parport_claim_or_block(qcam->pdev); |
| 590 | 609 | qc_setup(qcam); |
| 591 | 610 | parport_release(qcam->pdev); |
| 592 | − mutex_unlock(&qcam->lock); | |
| 593 | − return 0; | |
| 594 | 611 | } |
| 595 | − case VIDIOCSWIN: | |
| 596 | − { | |
| 597 | − struct video_window *vw = arg; | |
| 598 | − | |
| 599 | − if (vw->flags) | |
| 600 | − return -EINVAL; | |
| 601 | − if (vw->clipcount) | |
| 602 | − return -EINVAL; | |
| 603 | − if (vw->height < 60 || vw->height > 240) | |
| 604 | − return -EINVAL; | |
| 605 | − if (vw->width < 80 || vw->width > 320) | |
| 606 | − return -EINVAL; | |
| 607 | − | |
| 608 | − qcam->width = 80; | |
| 609 | − qcam->height = 60; | |
| 610 | − qcam->mode = QC_DECIMATION_4; | |
| 612 | + mutex_unlock(&qcam->lock); | |
| 613 | + return ret; | |
| 614 | +} | |
| 611 | 615 | |
| 612 | − if (vw->width >= 160 && vw->height >= 120) { | |
| 613 | − qcam->width = 160; | |
| 614 | − qcam->height = 120; | |
| 615 | − qcam->mode = QC_DECIMATION_2; | |
| 616 | − } | |
| 617 | − if (vw->width >= 320 && vw->height >= 240) { | |
| 618 | − qcam->width = 320; | |
| 619 | − qcam->height = 240; | |
| 620 | − qcam->mode = QC_DECIMATION_1; | |
| 621 | − } | |
| 622 | − qcam->mode |= QC_MILLIONS; | |
| 623 | −#if 0 | |
| 624 | − if (vw->width >= 640 && vw->height >= 480) { | |
| 625 | − qcam->width = 640; | |
| 626 | − qcam->height = 480; | |
| 627 | − qcam->mode = QC_BILLIONS | QC_DECIMATION_1; | |
| 628 | − } | |
| 629 | −#endif | |
| 630 | − /* Ok we figured out what to use from our | |
| 631 | − wide choice */ | |
| 632 | − mutex_lock(&qcam->lock); | |
| 633 | − parport_claim_or_block(qcam->pdev); | |
| 634 | − qc_setup(qcam); | |
| 635 | − parport_release(qcam->pdev); | |
| 636 | − mutex_unlock(&qcam->lock); | |
| 637 | − return 0; | |
| 638 | − } | |
| 639 | − case VIDIOCGWIN: | |
| 640 | − { | |
| 641 | − struct video_window *vw = arg; | |
| 642 | − memset(vw, 0, sizeof(*vw)); | |
| 643 | − vw->width = qcam->width; | |
| 644 | − vw->height = qcam->height; | |
| 645 | − return 0; | |
| 616 | +static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | |
| 617 | +{ | |
| 618 | + struct qcam *qcam = video_drvdata(file); | |
| 619 | + struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
| 620 | + | |
| 621 | + pix->width = qcam->width; | |
| 622 | + pix->height = qcam->height; | |
| 623 | + pix->pixelformat = V4L2_PIX_FMT_RGB24; | |
| 624 | + pix->field = V4L2_FIELD_NONE; | |
| 625 | + pix->bytesperline = 3 * qcam->width; | |
| 626 | + pix->sizeimage = 3 * qcam->width * qcam->height; | |
| 627 | + /* Just a guess */ | |
| 628 | + pix->colorspace = V4L2_COLORSPACE_SRGB; | |
| 629 | + return 0; | |
| 630 | +} | |
| 631 | + | |
| 632 | +static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | |
| 633 | +{ | |
| 634 | + struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
| 635 | + | |
| 636 | + if (pix->height < 60 || pix->width < 80) { | |
| 637 | + pix->height = 60; | |
| 638 | + pix->width = 80; | |
| 639 | + } else if (pix->height < 120 || pix->width < 160) { | |
| 640 | + pix->height = 120; | |
| 641 | + pix->width = 160; | |
| 642 | + } else { | |
| 643 | + pix->height = 240; | |
| 644 | + pix->width = 320; | |
| 646 | 645 | } |
| 647 | − case VIDIOCKEY: | |
| 648 | − return 0; | |
| 649 | − case VIDIOCCAPTURE: | |
| 650 | − case VIDIOCGFBUF: | |
| 651 | − case VIDIOCSFBUF: | |
| 652 | − case VIDIOCGFREQ: | |
| 653 | − case VIDIOCSFREQ: | |
| 654 | − case VIDIOCGAUDIO: | |
| 655 | − case VIDIOCSAUDIO: | |
| 656 | − return -EINVAL; | |
| 646 | + pix->pixelformat = V4L2_PIX_FMT_RGB24; | |
| 647 | + pix->field = V4L2_FIELD_NONE; | |
| 648 | + pix->bytesperline = 3 * pix->width; | |
| 649 | + pix->sizeimage = 3 * pix->width * pix->height; | |
| 650 | + /* Just a guess */ | |
| 651 | + pix->colorspace = V4L2_COLORSPACE_SRGB; | |
| 652 | + return 0; | |
| 653 | +} | |
| 654 | + | |
| 655 | +static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | |
| 656 | +{ | |
| 657 | + struct qcam *qcam = video_drvdata(file); | |
| 658 | + struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
| 659 | + int ret = qcam_try_fmt_vid_cap(file, fh, fmt); | |
| 660 | + | |
| 661 | + if (ret) | |
| 662 | + return ret; | |
| 663 | + switch (pix->height) { | |
| 664 | + case 60: | |
| 665 | + qcam->mode = QC_DECIMATION_4; | |
| 666 | + break; | |
| 667 | + case 120: | |
| 668 | + qcam->mode = QC_DECIMATION_2; | |
| 669 | + break; | |
| 657 | 670 | default: |
| 658 | − return -ENOIOCTLCMD; | |
| 671 | + qcam->mode = QC_DECIMATION_1; | |
| 672 | + break; | |
| 659 | 673 | } |
| 674 | + | |
| 675 | + mutex_lock(&qcam->lock); | |
| 676 | + qcam->mode |= QC_MILLIONS; | |
| 677 | + qcam->height = pix->height; | |
| 678 | + qcam->width = pix->width; | |
| 679 | + parport_claim_or_block(qcam->pdev); | |
| 680 | + qc_setup(qcam); | |
| 681 | + parport_release(qcam->pdev); | |
| 682 | + mutex_unlock(&qcam->lock); | |
| 660 | 683 | return 0; |
| 661 | 684 | } |
| 662 | 685 | |
| 663 | −static long qcam_ioctl(struct file *file, | |
| 664 | − unsigned int cmd, unsigned long arg) | |
| 686 | +static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) | |
| 665 | 687 | { |
| 666 | − return video_usercopy(file, cmd, arg, qcam_do_ioctl); | |
| 688 | + static struct v4l2_fmtdesc formats[] = { | |
| 689 | + { 0, 0, 0, | |
| 690 | + "RGB 8:8:8", V4L2_PIX_FMT_RGB24, | |
| 691 | + { 0, 0, 0, 0 } | |
| 692 | + }, | |
| 693 | + }; | |
| 694 | + enum v4l2_buf_type type = fmt->type; | |
| 695 | + | |
| 696 | + if (fmt->index > 0) | |
| 697 | + return -EINVAL; | |
| 698 | + | |
| 699 | + *fmt = formats[fmt->index]; | |
| 700 | + fmt->type = type; | |
| 701 | + return 0; | |
| 667 | 702 | } |
| 668 | 703 | |
| 669 | 704 | static ssize_t qcam_read(struct file *file, char __user *buf, |
| 670 | 705 | size_t count, loff_t *ppos) |
| 671 | 706 | { |
| 672 | − struct video_device *v = video_devdata(file); | |
| 673 | − struct qcam_device *qcam = (struct qcam_device *)v; | |
| 707 | + struct qcam *qcam = video_drvdata(file); | |
| 674 | 708 | int len; |
| 675 | 709 | |
| 676 | 710 | mutex_lock(&qcam->lock); |
| @@ -682,81 +716,80 @@ static ssize_t qcam_read(struct file *file, char __user *buf, · 5 unmodified lines | ||
| 682 | 716 | return len; |
| 683 | 717 | } |
| 684 | 718 | |
| 685 | −static int qcam_exclusive_open(struct file *file) | |
| 686 | −{ | |
| 687 | − struct video_device *dev = video_devdata(file); | |
| 688 | − struct qcam_device *qcam = (struct qcam_device *)dev; | |
| 689 | − | |
| 690 | − return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; | |
| 691 | −} | |
| 692 | − | |
| 693 | −static int qcam_exclusive_release(struct file *file) | |
| 694 | −{ | |
| 695 | − struct video_device *dev = video_devdata(file); | |
| 696 | − struct qcam_device *qcam = (struct qcam_device *)dev; | |
| 697 | − | |
| 698 | − clear_bit(0, &qcam->in_use); | |
| 699 | − return 0; | |
| 700 | −} | |
| 701 | − | |
| 702 | −/* video device template */ | |
| 703 | 719 | static const struct v4l2_file_operations qcam_fops = { |
| 704 | 720 | .owner = THIS_MODULE, |
| 705 | − .open = qcam_exclusive_open, | |
| 706 | − .release = qcam_exclusive_release, | |
| 707 | − .ioctl = qcam_ioctl, | |
| 721 | + .ioctl = video_ioctl2, | |
| 708 | 722 | .read = qcam_read, |
| 709 | 723 | }; |
| 710 | 724 | |
| 711 | −static struct video_device qcam_template = { | |
| 712 | − .name = "Colour QuickCam", | |
| 713 | − .fops = &qcam_fops, | |
| 714 | − .release = video_device_release_empty, | |
| 725 | +static const struct v4l2_ioctl_ops qcam_ioctl_ops = { | |
| 726 | + .vidioc_querycap = qcam_querycap, | |
| 727 | + .vidioc_g_input = qcam_g_input, | |
| 728 | + .vidioc_s_input = qcam_s_input, | |
| 729 | + .vidioc_enum_input = qcam_enum_input, | |
| 730 | + .vidioc_queryctrl = qcam_queryctrl, | |
| 731 | + .vidioc_g_ctrl = qcam_g_ctrl, | |
| 732 | + .vidioc_s_ctrl = qcam_s_ctrl, | |
| 733 | + .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, | |
| 734 | + .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, | |
| 735 | + .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, | |
| 736 | + .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, | |
| 715 | 737 | }; |
| 716 | 738 | |
| 717 | 739 | /* Initialize the QuickCam driver control structure. */ |
| 718 | 740 | |
| 719 | −static struct qcam_device *qcam_init(struct parport *port) | |
| 741 | +static struct qcam *qcam_init(struct parport *port) | |
| 720 | 742 | { |
| 721 | − struct qcam_device *q; | |
| 743 | + struct qcam *qcam; | |
| 744 | + struct v4l2_device *v4l2_dev; | |
| 722 | 745 | |
| 723 | − q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); | |
| 724 | − if (q == NULL) | |
| 746 | + qcam = kzalloc(sizeof(*qcam), GFP_KERNEL); | |
| 747 | + if (qcam == NULL) | |
| 725 | 748 | return NULL; |
| 726 | 749 | |
| 727 | − q->pport = port; | |
| 728 | − q->pdev = parport_register_device(port, "c-qcam", NULL, NULL, | |
| 750 | + v4l2_dev = &qcam->v4l2_dev; | |
| 751 | + strlcpy(v4l2_dev->name, "c-qcam", sizeof(v4l2_dev->name)); | |
| 752 | + | |
| 753 | + if (v4l2_device_register(NULL, v4l2_dev) < 0) { | |
| 754 | + v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); | |
| 755 | + return NULL; | |
| 756 | + } | |
| 757 | + | |
| 758 | + qcam->pport = port; | |
| 759 | + qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL, | |
| 729 | 760 | NULL, 0, NULL); |
| 730 | 761 | |
| 731 | − q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0; | |
| 762 | + qcam->bidirectional = (qcam->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0; | |
| 732 | 763 | |
| 733 | − if (q->pdev == NULL) { | |
| 734 | − printk(KERN_ERR "c-qcam: couldn't register for %s.\n", | |
| 735 | − port->name); | |
| 736 | − kfree(q); | |
| 764 | + if (qcam->pdev == NULL) { | |
| 765 | + v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); | |
| 766 | + kfree(qcam); | |
| 737 | 767 | return NULL; |
| 738 | 768 | } |
| 739 | 769 | |
| 740 | − memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); | |
| 741 | − | |
| 742 | − mutex_init(&q->lock); | |
| 743 | − q->width = q->ccd_width = 320; | |
| 744 | − q->height = q->ccd_height = 240; | |
| 745 | − q->mode = QC_MILLIONS | QC_DECIMATION_1; | |
| 746 | − q->contrast = 192; | |
| 747 | − q->brightness = 240; | |
| 748 | − q->whitebal = 128; | |
| 749 | − q->top = 1; | |
| 750 | − q->left = 14; | |
| 751 | − return q; | |
| 770 | + strlcpy(qcam->vdev.name, "Colour QuickCam", sizeof(qcam->vdev.name)); | |
| 771 | + qcam->vdev.v4l2_dev = v4l2_dev; | |
| 772 | + qcam->vdev.fops = &qcam_fops; | |
| 773 | + qcam->vdev.ioctl_ops = &qcam_ioctl_ops; | |
| 774 | + qcam->vdev.release = video_device_release_empty; | |
| 775 | + video_set_drvdata(&qcam->vdev, qcam); | |
| 776 | + | |
| 777 | + mutex_init(&qcam->lock); | |
| 778 | + qcam->width = qcam->ccd_width = 320; | |
| 779 | + qcam->height = qcam->ccd_height = 240; | |
| 780 | + qcam->mode = QC_MILLIONS | QC_DECIMATION_1; | |
| 781 | + qcam->contrast = 192; | |
| 782 | + qcam->brightness = 240; | |
| 783 | + qcam->whitebal = 128; | |
| 784 | + qcam->top = 1; | |
| 785 | + qcam->left = 14; | |
| 786 | + return qcam; | |
| 752 | 787 | } |
| 753 | 788 | |
| 754 | −static struct qcam_device *qcams[MAX_CAMS]; | |
| 755 | −static unsigned int num_cams; | |
| 756 | − | |
| 757 | 789 | static int init_cqcam(struct parport *port) |
| 758 | 790 | { |
| 759 | − struct qcam_device *qcam; | |
| 791 | + struct qcam *qcam; | |
| 792 | + struct v4l2_device *v4l2_dev; | |
| 760 | 793 | |
| 761 | 794 | if (parport[0] != -1) { |
| 762 | 795 | /* The user gave specific instructions */ |
| @@ -777,6 +810,8 @@ static int init_cqcam(struct parport *port) · 14 unmodified lines | ||
| 777 | 810 | if (qcam == NULL) |
| 778 | 811 | return -ENODEV; |
| 779 | 812 | |
| 813 | + v4l2_dev = &qcam->v4l2_dev; | |
| 814 | + | |
| 780 | 815 | parport_claim_or_block(qcam->pdev); |
| 781 | 816 | |
| 782 | 817 | qc_reset(qcam); |
| @@ -793,14 +828,14 @@ static int init_cqcam(struct parport *port) · 10 unmodified lines | ||
| 793 | 828 | parport_release(qcam->pdev); |
| 794 | 829 | |
| 795 | 830 | if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { |
| 796 | − printk(KERN_ERR "Unable to register Colour QuickCam on %s\n", | |
| 831 | + v4l2_err(v4l2_dev, "Unable to register Colour QuickCam on %s\n", | |
| 797 | 832 | qcam->pport->name); |
| 798 | 833 | parport_unregister_device(qcam->pdev); |
| 799 | 834 | kfree(qcam); |
| 800 | 835 | return -ENODEV; |
| 801 | 836 | } |
| 802 | 837 | |
| 803 | − printk(KERN_INFO "%s: Colour QuickCam found on %s\n", | |
| 838 | + v4l2_info(v4l2_dev, "%s: Colour QuickCam found on %s\n", | |
| 804 | 839 | video_device_node_name(&qcam->vdev), qcam->pport->name); |
| 805 | 840 | |
| 806 | 841 | qcams[num_cams++] = qcam; |
| @@ -808,7 +843,7 @@ static int init_cqcam(struct parport *port) · 1 unmodified line | ||
| 808 | 843 | return 0; |
| 809 | 844 | } |
| 810 | 845 | |
| 811 | −static void close_cqcam(struct qcam_device *qcam) | |
| 846 | +static void close_cqcam(struct qcam *qcam) | |
| 812 | 847 | { |
| 813 | 848 | video_unregister_device(&qcam->vdev); |
| 814 | 849 | parport_unregister_device(qcam->pdev); |
| @@ -833,7 +868,7 @@ static struct parport_driver cqcam_driver = { · 18 unmodified lines | ||
| 833 | 868 | |
| 834 | 869 | static int __init cqcam_init(void) |
| 835 | 870 | { |
| 836 | − printk(BANNER "\n"); | |
| 871 | + printk(KERN_INFO BANNER "\n"); | |
| 837 | 872 | |
| 838 | 873 | return parport_register_driver(&cqcam_driver); |
| 839 | 874 | } |
| @@ -852,14 +887,5 @@ MODULE_AUTHOR("Philip Blundell <philb@gnu.org>"); · 12 unmodified lines | ||
| 852 | 887 | MODULE_DESCRIPTION(BANNER); |
| 853 | 888 | MODULE_LICENSE("GPL"); |
| 854 | 889 | |
| 855 | −/* FIXME: parport=auto would never have worked, surely? --RR */ | |
| 856 | −MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n" | |
| 857 | − "probe=<0|1|2> for camera detection method\n" | |
| 858 | − "force_rgb=<0|1> for RGB data format (default BGR)"); | |
| 859 | −module_param_array(parport, int, NULL, 0); | |
| 860 | −module_param(probe, int, 0); | |
| 861 | −module_param(force_rgb, bool, 0); | |
| 862 | −module_param(video_nr, int, 0); | |
| 863 | − | |
| 864 | 890 | module_init(cqcam_init); |
| 865 | 891 | module_exit(cqcam_cleanup); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * ALSA interface to cx18 PCM capture streams |
| 3 | 3 | * |
| 4 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 4 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 5 | 5 | * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> |
| 6 | 6 | * |
| 7 | 7 | * Portions of this work were sponsored by ONELAN Limited. |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * ALSA mixer controls for the |
| 3 | 3 | * ALSA interface to cx18 PCM capture streams |
| 4 | 4 | * |
| 5 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * ALSA mixer controls for the |
| 3 | 3 | * ALSA interface to cx18 PCM capture streams |
| 4 | 4 | * |
| 5 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * ALSA PCM device for the |
| 3 | 3 | * ALSA interface to cx18 PCM capture streams |
| 4 | 4 | * |
| 5 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> |
| 7 | 7 | * |
| 8 | 8 | * Portions of this work were sponsored by ONELAN Limited. |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * ALSA PCM device for the |
| 3 | 3 | * ALSA interface to cx18 PCM capture streams |
| 4 | 4 | * |
| 5 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * ALSA interface to cx18 PCM capture streams |
| 3 | 3 | * |
| 4 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 4 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 5 | 5 | * |
| 6 | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | 7 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from cx25840-audio.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or |
| 10 | 10 | * modify it under the terms of the GNU General Public License |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from cx25840-core.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or |
| 10 | 10 | * 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) · 1010 unmodified lines | ||
| 1021 | 1021 | return -EINVAL; |
| 1022 | 1022 | } |
| 1023 | 1023 | |
| 1024 | −static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 1025 | −{ | |
| 1026 | − if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | |
| 1027 | − return -EINVAL; | |
| 1028 | − return cx18_av_g_sliced_fmt(sd, &fmt->fmt.sliced); | |
| 1029 | −} | |
| 1030 | − | |
| 1031 | −static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 1024 | +static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) | |
| 1032 | 1025 | { |
| 1033 | 1026 | struct cx18_av_state *state = to_cx18_av_state(sd); |
| 1034 | 1027 | struct cx18 *cx = v4l2_get_subdevdata(sd); |
| 1035 | − | |
| 1036 | − struct v4l2_pix_format *pix; | |
| 1037 | 1028 | int HSC, VSC, Vsrc, Hsrc, filter, Vlines; |
| 1038 | 1029 | int is_50Hz = !(state->std & V4L2_STD_525_60); |
| 1039 | 1030 | |
| 1040 | − switch (fmt->type) { | |
| 1041 | − case V4L2_BUF_TYPE_VIDEO_CAPTURE: | |
| 1042 | − pix = &(fmt->fmt.pix); | |
| 1031 | + if (fmt->code != V4L2_MBUS_FMT_FIXED) | |
| 1032 | + return -EINVAL; | |
| 1043 | 1033 | |
| 1044 | − Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4; | |
| 1045 | − Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4; | |
| 1034 | + fmt->field = V4L2_FIELD_INTERLACED; | |
| 1035 | + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; | |
| 1046 | 1036 | |
| 1047 | − Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4; | |
| 1048 | − Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4; | |
| 1037 | + Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4; | |
| 1038 | + Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4; | |
| 1049 | 1039 | |
| 1050 | − /* | |
| 1051 | − * This adjustment reflects the excess of vactive, set in | |
| 1052 | − * cx18_av_std_setup(), above standard values: | |
| 1053 | − * | |
| 1054 | − * 480 + 1 for 60 Hz systems | |
| 1055 | − * 576 + 3 for 50 Hz systems | |
| 1056 | − */ | |
| 1057 | − Vlines = pix->height + (is_50Hz ? 3 : 1); | |
| 1058 | − | |
| 1059 | − /* | |
| 1060 | − * Invalid height and width scaling requests are: | |
| 1061 | − * 1. width less than 1/16 of the source width | |
| 1062 | − * 2. width greater than the source width | |
| 1063 | − * 3. height less than 1/8 of the source height | |
| 1064 | − * 4. height greater than the source height | |
| 1065 | − */ | |
| 1066 | − if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || | |
| 1067 | − (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { | |
| 1068 | − CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n", | |
| 1069 | − pix->width, pix->height); | |
| 1070 | − return -ERANGE; | |
| 1071 | − } | |
| 1040 | + Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4; | |
| 1041 | + Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4; | |
| 1072 | 1042 | |
| 1073 | − HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20); | |
| 1074 | − VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); | |
| 1075 | − VSC &= 0x1fff; | |
| 1043 | + /* | |
| 1044 | + * This adjustment reflects the excess of vactive, set in | |
| 1045 | + * cx18_av_std_setup(), above standard values: | |
| 1046 | + * | |
| 1047 | + * 480 + 1 for 60 Hz systems | |
| 1048 | + * 576 + 3 for 50 Hz systems | |
| 1049 | + */ | |
| 1050 | + Vlines = fmt->height + (is_50Hz ? 3 : 1); | |
| 1076 | 1051 | |
| 1077 | − if (pix->width >= 385) | |
| 1078 | − filter = 0; | |
| 1079 | − else if (pix->width > 192) | |
| 1080 | − filter = 1; | |
| 1081 | − else if (pix->width > 96) | |
| 1082 | − filter = 2; | |
| 1083 | − else | |
| 1084 | − filter = 3; | |
| 1052 | + /* | |
| 1053 | + * Invalid height and width scaling requests are: | |
| 1054 | + * 1. width less than 1/16 of the source width | |
| 1055 | + * 2. width greater than the source width | |
| 1056 | + * 3. height less than 1/8 of the source height | |
| 1057 | + * 4. height greater than the source height | |
| 1058 | + */ | |
| 1059 | + if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) || | |
| 1060 | + (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { | |
| 1061 | + CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n", | |
| 1062 | + fmt->width, fmt->height); | |
| 1063 | + return -ERANGE; | |
| 1064 | + } | |
| 1085 | 1065 | |
| 1086 | − CX18_DEBUG_INFO_DEV(sd, | |
| 1087 | − "decoder set size %dx%d -> scale %ux%u\n", | |
| 1088 | − pix->width, pix->height, HSC, VSC); | |
| 1089 | − | |
| 1090 | − /* HSCALE=HSC */ | |
| 1091 | − cx18_av_write(cx, 0x418, HSC & 0xff); | |
| 1092 | − cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff); | |
| 1093 | − cx18_av_write(cx, 0x41a, HSC >> 16); | |
| 1094 | − /* VSCALE=VSC */ | |
| 1095 | − cx18_av_write(cx, 0x41c, VSC & 0xff); | |
| 1096 | − cx18_av_write(cx, 0x41d, VSC >> 8); | |
| 1097 | − /* VS_INTRLACE=1 VFILT=filter */ | |
| 1098 | − cx18_av_write(cx, 0x41e, 0x8 | filter); | |
| 1099 | − break; | |
| 1066 | + HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20); | |
| 1067 | + VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); | |
| 1068 | + VSC &= 0x1fff; | |
| 1100 | 1069 | |
| 1101 | − default: | |
| 1102 | − return -EINVAL; | |
| 1103 | − } | |
| 1070 | + if (fmt->width >= 385) | |
| 1071 | + filter = 0; | |
| 1072 | + else if (fmt->width > 192) | |
| 1073 | + filter = 1; | |
| 1074 | + else if (fmt->width > 96) | |
| 1075 | + filter = 2; | |
| 1076 | + else | |
| 1077 | + filter = 3; | |
| 1078 | + | |
| 1079 | + CX18_DEBUG_INFO_DEV(sd, | |
| 1080 | + "decoder set size %dx%d -> scale %ux%u\n", | |
| 1081 | + fmt->width, fmt->height, HSC, VSC); | |
| 1082 | + | |
| 1083 | + /* HSCALE=HSC */ | |
| 1084 | + cx18_av_write(cx, 0x418, HSC & 0xff); | |
| 1085 | + cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff); | |
| 1086 | + cx18_av_write(cx, 0x41a, HSC >> 16); | |
| 1087 | + /* VSCALE=VSC */ | |
| 1088 | + cx18_av_write(cx, 0x41c, VSC & 0xff); | |
| 1089 | + cx18_av_write(cx, 0x41d, VSC >> 8); | |
| 1090 | + /* VS_INTRLACE=1 VFILT=filter */ | |
| 1091 | + cx18_av_write(cx, 0x41e, 0x8 | filter); | |
| 1104 | 1092 | return 0; |
| 1105 | 1093 | } |
| 1106 | 1094 | |
| @@ -1398,8 +1386,7 @@ static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = { · 291 unmodified lines | ||
| 1398 | 1386 | static const struct v4l2_subdev_video_ops cx18_av_video_ops = { |
| 1399 | 1387 | .s_routing = cx18_av_s_video_routing, |
| 1400 | 1388 | .s_stream = cx18_av_s_stream, |
| 1401 | − .g_fmt = cx18_av_g_fmt, | |
| 1402 | − .s_fmt = cx18_av_s_fmt, | |
| 1389 | + .s_mbus_fmt = cx18_av_s_mbus_fmt, | |
| 1403 | 1390 | }; |
| 1404 | 1391 | |
| 1405 | 1392 | static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = { |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from cx25840-core.h |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or |
| 10 | 10 | * modify it under the terms of the GNU General Public License |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 ADEC firmware functions |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or |
| 8 | 8 | * modify it under the terms of the GNU General Public License |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-cards.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-cards.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * 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) · 296 unmodified lines | ||
| 297 | 297 | if (p.video_encoding != cx->params.video_encoding) { |
| 298 | 298 | int is_mpeg1 = p.video_encoding == |
| 299 | 299 | V4L2_MPEG_VIDEO_ENCODING_MPEG_1; |
| 300 | − struct v4l2_format fmt; | |
| 300 | + struct v4l2_mbus_framefmt fmt; | |
| 301 | 301 | |
| 302 | 302 | /* fix videodecoder resolution */ |
| 303 | − fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |
| 304 | − fmt.fmt.pix.width = cx->params.width | |
| 305 | − / (is_mpeg1 ? 2 : 1); | |
| 306 | − fmt.fmt.pix.height = cx->params.height; | |
| 307 | − v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt); | |
| 303 | + fmt.width = cx->params.width / (is_mpeg1 ? 2 : 1); | |
| 304 | + fmt.height = cx->params.height; | |
| 305 | + fmt.code = V4L2_MBUS_FMT_FIXED; | |
| 306 | + v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt); | |
| 308 | 307 | } |
| 309 | 308 | priv.cx = cx; |
| 310 | 309 | priv.s = &cx->streams[id->type]; |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-driver.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-driver.h |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 functions for DVB support |
| 3 | 3 | * |
| 4 | 4 | * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-fileops.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 firmware functions |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-gpio.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-gpio.h |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-i2c.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 driver PCI memory mapped IO access routines |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 driver PCI memory mapped IO access routines |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -28,7 +28,7 @@ · 19 unmodified lines | ||
| 28 | 28 | /* |
| 29 | 29 | * Readback and retry of MMIO access for reliability: |
| 30 | 30 | * The concept was suggested by Steve Toth <stoth@linuxtv.org>. |
| 31 | − * The implmentation is the fault of Andy Walls <awalls@radix.net>. | |
| 31 | + * The implmentation is the fault of Andy Walls <awalls@md.metrocast.net>. | |
| 32 | 32 | * |
| 33 | 33 | * *write* functions are implied to retry the mmio unless suffixed with _noretry |
| 34 | 34 | * *read* functions never retry the mmio (it never helps to do so) |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-ioctl.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * 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, · 263 unmodified lines | ||
| 274 | 274 | { |
| 275 | 275 | struct cx18_open_id *id = fh; |
| 276 | 276 | struct cx18 *cx = id->cx; |
| 277 | + struct v4l2_mbus_framefmt mbus_fmt; | |
| 277 | 278 | int ret; |
| 278 | 279 | int w, h; |
| 279 | 280 | |
| @@ -293,9 +294,10 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, · 13 unmodified lines | ||
| 293 | 294 | if (atomic_read(&cx->ana_capturing) > 0) |
| 294 | 295 | return -EBUSY; |
| 295 | 296 | |
| 296 | − cx->params.width = w; | |
| 297 | − cx->params.height = h; | |
| 298 | − v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); | |
| 297 | + mbus_fmt.width = cx->params.width = w; | |
| 298 | + mbus_fmt.height = cx->params.height = h; | |
| 299 | + mbus_fmt.code = V4L2_MBUS_FMT_FIXED; | |
| 300 | + v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt); | |
| 299 | 301 | return cx18_g_fmt_vid_cap(file, fh, fmt); |
| 300 | 302 | } |
| 301 | 303 | |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-ioctl.h |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 interrupt handling |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 interrupt handling |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 mailbox functions |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 mailbox functions |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-queue.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-queue.h |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 System Control Block initialization |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * cx18 System Control Block initialization |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 5 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 5 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 6 | 6 | * |
| 7 | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | 8 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-streams.c |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Derived from ivtv-streams.h |
| 5 | 5 | * |
| 6 | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
| 7 | − * Copyright (C) 2008 Andy Walls <awalls@radix.net> | |
| 7 | + * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> | |
| 8 | 8 | * |
| 9 | 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | 10 | * 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, · 992 unmodified lines | ||
| 993 | 993 | struct cx231xx *dev = fh->dev; |
| 994 | 994 | int rc; |
| 995 | 995 | struct cx231xx_fmt *fmt; |
| 996 | + struct v4l2_mbus_framefmt mbus_fmt; | |
| 996 | 997 | |
| 997 | 998 | rc = check_dev(dev); |
| 998 | 999 | if (rc < 0) |
| @@ -1026,7 +1027,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, · 27 unmodified lines | ||
| 1026 | 1027 | dev->format = fmt; |
| 1027 | 1028 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); |
| 1028 | 1029 | |
| 1029 | − call_all(dev, video, s_fmt, f); | |
| 1030 | + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); | |
| 1031 | + call_all(dev, video, s_mbus_fmt, &mbus_fmt); | |
| 1032 | + v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); | |
| 1030 | 1033 | |
| 1031 | 1034 | /* Set the correct alternate setting for this resolution */ |
| 1032 | 1035 | cx231xx_resolution_set(dev); |
| @@ -1113,7 +1113,6 @@ invalid: · 1112 unmodified lines | ||
| 1113 | 1113 | void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) |
| 1114 | 1114 | { |
| 1115 | 1115 | int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; |
| 1116 | − int temporal = p->video_temporal_filter; | |
| 1117 | 1116 | |
| 1118 | 1117 | /* Stream */ |
| 1119 | 1118 | printk(KERN_INFO "%s: Stream: %s", |
| @@ -1179,14 +1178,11 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) · 59 unmodified lines | ||
| 1179 | 1178 | V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), |
| 1180 | 1179 | p->video_spatial_filter); |
| 1181 | 1180 | |
| 1182 | − if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480)) | |
| 1183 | − temporal = 0; | |
| 1184 | − | |
| 1185 | 1181 | printk(KERN_INFO "%s: Temporal Filter: %s, %d\n", |
| 1186 | 1182 | prefix, |
| 1187 | 1183 | cx2341x_menu_item(p, |
| 1188 | 1184 | V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), |
| 1189 | − temporal); | |
| 1185 | + p->video_temporal_filter); | |
| 1190 | 1186 | printk(KERN_INFO |
| 1191 | 1187 | "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", |
| 1192 | 1188 | prefix, |
| @@ -991,6 +991,8 @@ static int dvb_register(struct cx23885_tsport *port) · 990 unmodified lines | ||
| 991 | 991 | ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, |
| 992 | 992 | &dev->pci->dev, adapter_nr, 0, |
| 993 | 993 | cx23885_dvb_fe_ioctl_override); |
| 994 | + if (!ret) | |
| 995 | + return ret; | |
| 994 | 996 | |
| 995 | 997 | /* init CI & MAC */ |
| 996 | 998 | switch (dev->board) { |
| @@ -365,7 +365,17 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) · 364 unmodified lines | ||
| 365 | 365 | |
| 366 | 366 | memset(&info, 0, sizeof(struct i2c_board_info)); |
| 367 | 367 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); |
| 368 | − i2c_new_probed_device(&bus->i2c_adap, &info, addr_list); | |
| 368 | + /* | |
| 369 | + * We can't call i2c_new_probed_device() because it uses | |
| 370 | + * quick writes for probing and the IR receiver device only | |
| 371 | + * replies to reads. | |
| 372 | + */ | |
| 373 | + if (i2c_smbus_xfer(&bus->i2c_adap, addr_list[0], 0, | |
| 374 | + I2C_SMBUS_READ, 0, I2C_SMBUS_QUICK, | |
| 375 | + NULL) >= 0) { | |
| 376 | + info.addr = addr_list[0]; | |
| 377 | + i2c_new_device(&bus->i2c_adap, &info); | |
| 378 | + } | |
| 369 | 379 | } |
| 370 | 380 | |
| 371 | 381 | return bus->i2c_rc; |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * |
| 6 | 6 | * Most of this file is |
| 7 | 7 | * |
| 8 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 8 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 9 | 9 | * |
| 10 | 10 | * However, the cx23885_input_{init,fini} functions contained herein are |
| 11 | 11 | * derived from Linux kernel files linux/media/video/.../...-input.c marked as: |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * |
| 4 | 4 | * Infrared remote control input device |
| 5 | 5 | * |
| 6 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 6 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 7 | 7 | * |
| 8 | 8 | * This program is free software; you can redistribute it and/or |
| 9 | 9 | * modify it under the terms of the GNU General Public License |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * |
| 4 | 4 | * Various common ioctl() support functions |
| 5 | 5 | * |
| 6 | − * Copyright (c) 2009 Andy Walls <awalls@radix.net> | |
| 6 | + * Copyright (c) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 7 | 7 | * |
| 8 | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | 9 | * it under the terms of the GNU General Public License as published by |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * |
| 4 | 4 | * Various common ioctl() support functions |
| 5 | 5 | * |
| 6 | − * Copyright (c) 2009 Andy Walls <awalls@radix.net> | |
| 6 | + * Copyright (c) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 7 | 7 | * |
| 8 | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | 9 | * it under the terms of the GNU General Public License as published by |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * |
| 4 | 4 | * Infrared device support routines - non-input, non-vl42_subdev routines |
| 5 | 5 | * |
| 6 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 6 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 7 | 7 | * |
| 8 | 8 | * This program is free software; you can redistribute it and/or |
| 9 | 9 | * modify it under the terms of the GNU General Public License |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * |
| 4 | 4 | * Infrared device support routines - non-input, non-vl42_subdev routines |
| 5 | 5 | * |
| 6 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 6 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 7 | 7 | * |
| 8 | 8 | * This program is free software; you can redistribute it and/or |
| 9 | 9 | * 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, · 975 unmodified lines | ||
| 976 | 976 | { |
| 977 | 977 | struct cx23885_fh *fh = priv; |
| 978 | 978 | struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; |
| 979 | + struct v4l2_mbus_framefmt mbus_fmt; | |
| 979 | 980 | int err; |
| 980 | 981 | |
| 981 | 982 | dprintk(2, "%s()\n", __func__); |
| @@ -989,7 +990,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, · 7 unmodified lines | ||
| 989 | 990 | fh->vidq.field = f->fmt.pix.field; |
| 990 | 991 | dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, |
| 991 | 992 | fh->width, fh->height, fh->vidq.field); |
| 992 | − call_all(dev, video, s_fmt, f); | |
| 993 | + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); | |
| 994 | + call_all(dev, video, s_mbus_fmt, &mbus_fmt); | |
| 995 | + v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); | |
| 993 | 996 | return 0; |
| 994 | 997 | } |
| 995 | 998 | |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * |
| 4 | 4 | * CX23888 Integrated Consumer Infrared Controller |
| 5 | 5 | * |
| 6 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 6 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 7 | 7 | * |
| 8 | 8 | * This program is free software; you can redistribute it and/or |
| 9 | 9 | * modify it under the terms of the GNU General Public License |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * |
| 4 | 4 | * CX23888 Integrated Consumer Infrared Controller |
| 5 | 5 | * |
| 6 | − * Copyright (C) 2009 Andy Walls <awalls@radix.net> | |
| 6 | + * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | |
| 7 | 7 | * |
| 8 | 8 | * This program is free software; you can redistribute it and/or |
| 9 | 9 | * 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) · 1013 unmodified lines | ||
| 1014 | 1014 | |
| 1015 | 1015 | /* ----------------------------------------------------------------------- */ |
| 1016 | 1016 | |
| 1017 | −static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 1018 | −{ | |
| 1019 | − switch (fmt->type) { | |
| 1020 | − case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | |
| 1021 | − return cx25840_g_sliced_fmt(sd, &fmt->fmt.sliced); | |
| 1022 | − default: | |
| 1023 | − return -EINVAL; | |
| 1024 | − } | |
| 1025 | − return 0; | |
| 1026 | −} | |
| 1027 | − | |
| 1028 | −static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 1017 | +static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) | |
| 1029 | 1018 | { |
| 1030 | 1019 | struct cx25840_state *state = to_state(sd); |
| 1031 | 1020 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 1032 | − struct v4l2_pix_format *pix; | |
| 1033 | 1021 | int HSC, VSC, Vsrc, Hsrc, filter, Vlines; |
| 1034 | 1022 | int is_50Hz = !(state->std & V4L2_STD_525_60); |
| 1035 | 1023 | |
| 1036 | − switch (fmt->type) { | |
| 1037 | − case V4L2_BUF_TYPE_VIDEO_CAPTURE: | |
| 1038 | − pix = &(fmt->fmt.pix); | |
| 1039 | − | |
| 1040 | − Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; | |
| 1041 | − Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; | |
| 1042 | − | |
| 1043 | − Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; | |
| 1044 | − Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; | |
| 1024 | + if (fmt->code != V4L2_MBUS_FMT_FIXED) | |
| 1025 | + return -EINVAL; | |
| 1045 | 1026 | |
| 1046 | − Vlines = pix->height + (is_50Hz ? 4 : 7); | |
| 1027 | + fmt->field = V4L2_FIELD_INTERLACED; | |
| 1028 | + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; | |
| 1047 | 1029 | |
| 1048 | − if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || | |
| 1049 | − (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { | |
| 1050 | − v4l_err(client, "%dx%d is not a valid size!\n", | |
| 1051 | − pix->width, pix->height); | |
| 1052 | − return -ERANGE; | |
| 1053 | − } | |
| 1030 | + Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; | |
| 1031 | + Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; | |
| 1054 | 1032 | |
| 1055 | − HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20); | |
| 1056 | − VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); | |
| 1057 | − VSC &= 0x1fff; | |
| 1033 | + Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; | |
| 1034 | + Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; | |
| 1058 | 1035 | |
| 1059 | − if (pix->width >= 385) | |
| 1060 | − filter = 0; | |
| 1061 | − else if (pix->width > 192) | |
| 1062 | − filter = 1; | |
| 1063 | − else if (pix->width > 96) | |
| 1064 | − filter = 2; | |
| 1065 | − else | |
| 1066 | − filter = 3; | |
| 1067 | − | |
| 1068 | − v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n", | |
| 1069 | − pix->width, pix->height, HSC, VSC); | |
| 1070 | − | |
| 1071 | − /* HSCALE=HSC */ | |
| 1072 | − cx25840_write(client, 0x418, HSC & 0xff); | |
| 1073 | − cx25840_write(client, 0x419, (HSC >> 8) & 0xff); | |
| 1074 | − cx25840_write(client, 0x41a, HSC >> 16); | |
| 1075 | − /* VSCALE=VSC */ | |
| 1076 | − cx25840_write(client, 0x41c, VSC & 0xff); | |
| 1077 | − cx25840_write(client, 0x41d, VSC >> 8); | |
| 1078 | − /* VS_INTRLACE=1 VFILT=filter */ | |
| 1079 | − cx25840_write(client, 0x41e, 0x8 | filter); | |
| 1080 | − break; | |
| 1036 | + Vlines = fmt->height + (is_50Hz ? 4 : 7); | |
| 1081 | 1037 | |
| 1082 | − default: | |
| 1083 | − return -EINVAL; | |
| 1038 | + if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) || | |
| 1039 | + (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { | |
| 1040 | + v4l_err(client, "%dx%d is not a valid size!\n", | |
| 1041 | + fmt->width, fmt->height); | |
| 1042 | + return -ERANGE; | |
| 1084 | 1043 | } |
| 1085 | 1044 | |
| 1045 | + HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20); | |
| 1046 | + VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); | |
| 1047 | + VSC &= 0x1fff; | |
| 1048 | + | |
| 1049 | + if (fmt->width >= 385) | |
| 1050 | + filter = 0; | |
| 1051 | + else if (fmt->width > 192) | |
| 1052 | + filter = 1; | |
| 1053 | + else if (fmt->width > 96) | |
| 1054 | + filter = 2; | |
| 1055 | + else | |
| 1056 | + filter = 3; | |
| 1057 | + | |
| 1058 | + v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n", | |
| 1059 | + fmt->width, fmt->height, HSC, VSC); | |
| 1060 | + | |
| 1061 | + /* HSCALE=HSC */ | |
| 1062 | + cx25840_write(client, 0x418, HSC & 0xff); | |
| 1063 | + cx25840_write(client, 0x419, (HSC >> 8) & 0xff); | |
| 1064 | + cx25840_write(client, 0x41a, HSC >> 16); | |
| 1065 | + /* VSCALE=VSC */ | |
| 1066 | + cx25840_write(client, 0x41c, VSC & 0xff); | |
| 1067 | + cx25840_write(client, 0x41d, VSC >> 8); | |
| 1068 | + /* VS_INTRLACE=1 VFILT=filter */ | |
| 1069 | + cx25840_write(client, 0x41e, 0x8 | filter); | |
| 1086 | 1070 | return 0; |
| 1087 | 1071 | } |
| 1088 | 1072 | |
| @@ -1627,8 +1611,7 @@ static const struct v4l2_subdev_audio_ops cx25840_audio_ops = { · 538 unmodified lines | ||
| 1627 | 1611 | |
| 1628 | 1612 | static const struct v4l2_subdev_video_ops cx25840_video_ops = { |
| 1629 | 1613 | .s_routing = cx25840_s_video_routing, |
| 1630 | − .g_fmt = cx25840_g_fmt, | |
| 1631 | − .s_fmt = cx25840_s_fmt, | |
| 1614 | + .s_mbus_fmt = cx25840_s_mbus_fmt, | |
| 1632 | 1615 | .s_stream = cx25840_s_stream, |
| 1633 | 1616 | }; |
| 1634 | 1617 | |
| @@ -188,10 +188,24 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) · 187 unmodified lines | ||
| 188 | 188 | 0x18, 0x6b, 0x71, |
| 189 | 189 | I2C_CLIENT_END |
| 190 | 190 | }; |
| 191 | + const unsigned short *addrp; | |
| 191 | 192 | |
| 192 | 193 | memset(&info, 0, sizeof(struct i2c_board_info)); |
| 193 | 194 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); |
| 194 | − i2c_new_probed_device(&core->i2c_adap, &info, addr_list); | |
| 195 | + /* | |
| 196 | + * We can't call i2c_new_probed_device() because it uses | |
| 197 | + * quick writes for probing and at least some R receiver | |
| 198 | + * devices only reply to reads. | |
| 199 | + */ | |
| 200 | + for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) { | |
| 201 | + if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0, | |
| 202 | + I2C_SMBUS_READ, 0, | |
| 203 | + I2C_SMBUS_QUICK, NULL) >= 0) { | |
| 204 | + info.addr = *addrp; | |
| 205 | + i2c_new_device(&core->i2c_adap, &info); | |
| 206 | + break; | |
| 207 | + } | |
| 208 | + } | |
| 195 | 209 | } |
| 196 | 210 | return core->i2c_rc; |
| 197 | 211 | } |
| @@ -1186,8 +1186,7 @@ int em28xx_register_extension(struct em28xx_ops *ops) · 1185 unmodified lines | ||
| 1186 | 1186 | mutex_lock(&em28xx_devlist_mutex); |
| 1187 | 1187 | list_add_tail(&ops->next, &em28xx_extension_devlist); |
| 1188 | 1188 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
| 1189 | − if (dev) | |
| 1190 | − ops->init(dev); | |
| 1189 | + ops->init(dev); | |
| 1191 | 1190 | } |
| 1192 | 1191 | printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); |
| 1193 | 1192 | mutex_unlock(&em28xx_devlist_mutex); |
| @@ -1201,10 +1200,8 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) · 7 unmodified lines | ||
| 1201 | 1200 | |
| 1202 | 1201 | mutex_lock(&em28xx_devlist_mutex); |
| 1203 | 1202 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
| 1204 | − if (dev) | |
| 1205 | − ops->fini(dev); | |
| 1203 | + ops->fini(dev); | |
| 1206 | 1204 | } |
| 1207 | − | |
| 1208 | 1205 | printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); |
| 1209 | 1206 | list_del(&ops->next); |
| 1210 | 1207 | mutex_unlock(&em28xx_devlist_mutex); |
| @@ -1453,9 +1453,7 @@ static const struct usb_device_id device_table[] __devinitconst = { · 1452 unmodified lines | ||
| 1453 | 1453 | {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, |
| 1454 | 1454 | {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, |
| 1455 | 1455 | {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, |
| 1456 | −#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | |
| 1457 | 1456 | {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, |
| 1458 | −#endif | |
| 1459 | 1457 | {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, |
| 1460 | 1458 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
| 1461 | 1459 | {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, |
| @@ -3022,16 +3022,18 @@ static const __devinitdata struct usb_device_id device_table[] = { · 3021 unmodified lines | ||
| 3022 | 3022 | /* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */ |
| 3023 | 3023 | /* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */ |
| 3024 | 3024 | /* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */ |
| 3025 | + {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)}, | |
| 3025 | 3026 | {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)}, |
| 3026 | 3027 | /* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */ |
| 3027 | 3028 | /* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */ |
| 3029 | +/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */ | |
| 3028 | 3030 | {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)}, |
| 3029 | 3031 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
| 3030 | 3032 | {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)}, |
| 3031 | 3033 | {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)}, |
| 3032 | 3034 | #endif |
| 3033 | 3035 | {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/ |
| 3034 | −/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */ | |
| 3036 | +/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, * / GC0305*/ | |
| 3035 | 3037 | /* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */ |
| 3036 | 3038 | {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/ |
| 3037 | 3039 | {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/ |
| @@ -3058,6 +3060,7 @@ static const __devinitdata struct usb_device_id device_table[] = { · 20 unmodified lines | ||
| 3058 | 3060 | {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)}, |
| 3059 | 3061 | {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)}, |
| 3060 | 3062 | {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/ |
| 3063 | + /* or GC0305 / GC0307 */ | |
| 3061 | 3064 | {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ |
| 3062 | 3065 | {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ |
| 3063 | 3066 | {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/ |
| @@ -366,7 +366,7 @@ static int hdpvr_open(struct file *file) · 365 unmodified lines | ||
| 366 | 366 | |
| 367 | 367 | dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file)); |
| 368 | 368 | if (!dev) { |
| 369 | − v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n"); | |
| 369 | + pr_err("open failing with with ENODEV\n"); | |
| 370 | 370 | retval = -ENODEV; |
| 371 | 371 | goto err; |
| 372 | 372 | } |
| @@ -267,13 +267,13 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) · 266 unmodified lines | ||
| 267 | 267 | if (p.video_encoding != itv->params.video_encoding) { |
| 268 | 268 | int is_mpeg1 = p.video_encoding == |
| 269 | 269 | V4L2_MPEG_VIDEO_ENCODING_MPEG_1; |
| 270 | − struct v4l2_format fmt; | |
| 270 | + struct v4l2_mbus_framefmt fmt; | |
| 271 | 271 | |
| 272 | 272 | /* fix videodecoder resolution */ |
| 273 | − fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |
| 274 | − fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1); | |
| 275 | − fmt.fmt.pix.height = itv->params.height; | |
| 276 | − v4l2_subdev_call(itv->sd_video, video, s_fmt, &fmt); | |
| 273 | + fmt.width = itv->params.width / (is_mpeg1 ? 2 : 1); | |
| 274 | + fmt.height = itv->params.height; | |
| 275 | + fmt.code = V4L2_MBUS_FMT_FIXED; | |
| 276 | + v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt); | |
| 277 | 277 | } |
| 278 | 278 | err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); |
| 279 | 279 | 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) · 822 unmodified lines | ||
| 823 | 823 | |
| 824 | 824 | IVTV_DEBUG_FILE("close() of %s\n", s->name); |
| 825 | 825 | |
| 826 | + if (id->type == IVTV_DEC_STREAM_TYPE_YUV && | |
| 827 | + test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) { | |
| 828 | + /* Restore registers we've changed & clean up any mess */ | |
| 829 | + ivtv_yuv_close(itv); | |
| 830 | + } | |
| 831 | + | |
| 826 | 832 | /* Stop decoding */ |
| 827 | 833 | if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { |
| 828 | 834 | 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) · 3 unmodified lines | ||
| 832 | 838 | } |
| 833 | 839 | clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); |
| 834 | 840 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); |
| 835 | − if (id->type == IVTV_DEC_STREAM_TYPE_YUV && test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) { | |
| 836 | − /* Restore registers we've changed & clean up any mess we've made */ | |
| 837 | − ivtv_yuv_close(itv); | |
| 838 | − } | |
| 841 | + | |
| 839 | 842 | if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames) |
| 840 | 843 | itv->output_mode = OUT_NONE; |
| 841 | 844 | |
| @@ -569,6 +569,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f · 568 unmodified lines | ||
| 569 | 569 | struct ivtv_open_id *id = fh; |
| 570 | 570 | struct ivtv *itv = id->itv; |
| 571 | 571 | struct cx2341x_mpeg_params *p = &itv->params; |
| 572 | + struct v4l2_mbus_framefmt mbus_fmt; | |
| 572 | 573 | int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); |
| 573 | 574 | int w = fmt->fmt.pix.width; |
| 574 | 575 | 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 · 11 unmodified lines | ||
| 586 | 587 | p->height = h; |
| 587 | 588 | if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) |
| 588 | 589 | fmt->fmt.pix.width /= 2; |
| 589 | − v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); | |
| 590 | + mbus_fmt.width = fmt->fmt.pix.width; | |
| 591 | + mbus_fmt.height = h; | |
| 592 | + mbus_fmt.code = V4L2_MBUS_FMT_FIXED; | |
| 593 | + v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt); | |
| 590 | 594 | return ivtv_g_fmt_vid_cap(file, fh, fmt); |
| 591 | 595 | } |
| 592 | 596 | |
| @@ -618,12 +618,17 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) · 617 unmodified lines | ||
| 618 | 618 | struct ivtv *itv = s->itv; |
| 619 | 619 | struct cx2341x_mpeg_params *p = &itv->params; |
| 620 | 620 | int datatype; |
| 621 | + u16 width; | |
| 622 | + u16 height; | |
| 621 | 623 | |
| 622 | 624 | if (s->vdev == NULL) |
| 623 | 625 | return -EINVAL; |
| 624 | 626 | |
| 625 | 627 | IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); |
| 626 | 628 | |
| 629 | + width = p->width; | |
| 630 | + height = p->height; | |
| 631 | + | |
| 627 | 632 | /* set audio mode to left/stereo for dual/stereo mode. */ |
| 628 | 633 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); |
| 629 | 634 | |
| @@ -646,7 +651,14 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) · 16 unmodified lines | ||
| 646 | 651 | 2 = yuv_from_host */ |
| 647 | 652 | switch (s->type) { |
| 648 | 653 | case IVTV_DEC_STREAM_TYPE_YUV: |
| 649 | − datatype = itv->output_mode == OUT_PASSTHROUGH ? 1 : 2; | |
| 654 | + if (itv->output_mode == OUT_PASSTHROUGH) { | |
| 655 | + datatype = 1; | |
| 656 | + } else { | |
| 657 | + /* Fake size to avoid switching video standard */ | |
| 658 | + datatype = 2; | |
| 659 | + width = 720; | |
| 660 | + height = itv->is_out_50hz ? 576 : 480; | |
| 661 | + } | |
| 650 | 662 | IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype); |
| 651 | 663 | break; |
| 652 | 664 | case IVTV_DEC_STREAM_TYPE_MPG: |
| @@ -655,9 +667,13 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) · 2 unmodified lines | ||
| 655 | 667 | break; |
| 656 | 668 | } |
| 657 | 669 | if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, |
| 658 | − p->width, p->height, p->audio_properties)) { | |
| 670 | + width, height, p->audio_properties)) { | |
| 659 | 671 | IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); |
| 660 | 672 | } |
| 673 | + | |
| 674 | + /* Decoder sometimes dies here, so wait a moment */ | |
| 675 | + ivtv_msleep_timeout(10, 0); | |
| 676 | + | |
| 661 | 677 | return 0; |
| 662 | 678 | } |
| 663 | 679 | |
| @@ -697,6 +713,9 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) · 33 unmodified lines | ||
| 697 | 713 | /* start playback */ |
| 698 | 714 | ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0); |
| 699 | 715 | |
| 716 | + /* Let things settle before we actually start */ | |
| 717 | + ivtv_msleep_timeout(10, 0); | |
| 718 | + | |
| 700 | 719 | /* Clear the following Interrupt mask bits for decoding */ |
| 701 | 720 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE); |
| 702 | 721 | IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask); |
| @@ -1066,7 +1066,11 @@ static int ivtvfb_init_io(struct ivtv *itv) · 1065 unmodified lines | ||
| 1066 | 1066 | } |
| 1067 | 1067 | mutex_unlock(&itv->serialize_lock); |
| 1068 | 1068 | |
| 1069 | − ivtvfb_get_framebuffer(itv, &oi->video_rbase, &oi->video_buffer_size); | |
| 1069 | + if (ivtvfb_get_framebuffer(itv, &oi->video_rbase, | |
| 1070 | + &oi->video_buffer_size) < 0) { | |
| 1071 | + IVTVFB_ERR("Firmware failed to respond\n"); | |
| 1072 | + return -EIO; | |
| 1073 | + } | |
| 1070 | 1074 | |
| 1071 | 1075 | /* The osd buffer size depends on the number of video buffers allocated |
| 1072 | 1076 | 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) · 85 unmodified lines | ||
| 1158 | 1162 | } |
| 1159 | 1163 | |
| 1160 | 1164 | /* Find & setup the OSD buffer */ |
| 1161 | − if ((rc = ivtvfb_init_io(itv))) | |
| 1165 | + rc = ivtvfb_init_io(itv); | |
| 1166 | + if (rc) { | |
| 1167 | + ivtvfb_release_buffers(itv); | |
| 1162 | 1168 | return rc; |
| 1169 | + } | |
| 1163 | 1170 | |
| 1164 | 1171 | /* Set the startup video mode information */ |
| 1165 | 1172 | if ((rc = ivtvfb_init_vidmode(itv))) { |
| @@ -1210,6 +1217,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p) · 44 unmodified lines | ||
| 1210 | 1217 | { |
| 1211 | 1218 | struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); |
| 1212 | 1219 | struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); |
| 1220 | + struct osd_info *oi = itv->osd_info; | |
| 1213 | 1221 | |
| 1214 | 1222 | if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { |
| 1215 | 1223 | if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { |
| @@ -1218,7 +1226,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p) · 2 unmodified lines | ||
| 1218 | 1226 | return 0; |
| 1219 | 1227 | } |
| 1220 | 1228 | IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); |
| 1221 | − ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); | |
| 1229 | + ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); | |
| 1222 | 1230 | ivtvfb_release_buffers(itv); |
| 1223 | 1231 | itv->osd_video_pbase = 0; |
| 1224 | 1232 | } |
| @@ -701,13 +701,13 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { · 700 unmodified lines | ||
| 701 | 701 | #endif |
| 702 | 702 | }; |
| 703 | 703 | |
| 704 | −static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 704 | +static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 705 | 705 | enum v4l2_mbus_pixelcode *code) |
| 706 | 706 | { |
| 707 | 707 | struct i2c_client *client = sd->priv; |
| 708 | 708 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
| 709 | 709 | |
| 710 | − if ((unsigned int)index >= mt9m001->num_fmts) | |
| 710 | + if (index >= mt9m001->num_fmts) | |
| 711 | 711 | return -EINVAL; |
| 712 | 712 | |
| 713 | 713 | *code = mt9m001->fmts[index].code; |
| @@ -999,10 +999,10 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { · 998 unmodified lines | ||
| 999 | 999 | #endif |
| 1000 | 1000 | }; |
| 1001 | 1001 | |
| 1002 | −static int mt9m111_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 1002 | +static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 1003 | 1003 | enum v4l2_mbus_pixelcode *code) |
| 1004 | 1004 | { |
| 1005 | − if ((unsigned int)index >= ARRAY_SIZE(mt9m111_colour_fmts)) | |
| 1005 | + if (index >= ARRAY_SIZE(mt9m111_colour_fmts)) | |
| 1006 | 1006 | return -EINVAL; |
| 1007 | 1007 | |
| 1008 | 1008 | *code = mt9m111_colour_fmts[index].code; |
| @@ -798,7 +798,7 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { · 797 unmodified lines | ||
| 798 | 798 | #endif |
| 799 | 799 | }; |
| 800 | 800 | |
| 801 | −static int mt9t031_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 801 | +static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 802 | 802 | enum v4l2_mbus_pixelcode *code) |
| 803 | 803 | { |
| 804 | 804 | if (index) |
| @@ -1017,10 +1017,10 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd, · 1016 unmodified lines | ||
| 1017 | 1017 | return 0; |
| 1018 | 1018 | } |
| 1019 | 1019 | |
| 1020 | −static int mt9t112_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 1020 | +static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 1021 | 1021 | enum v4l2_mbus_pixelcode *code) |
| 1022 | 1022 | { |
| 1023 | − if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts)) | |
| 1023 | + if (index >= ARRAY_SIZE(mt9t112_cfmts)) | |
| 1024 | 1024 | return -EINVAL; |
| 1025 | 1025 | |
| 1026 | 1026 | *code = mt9t112_cfmts[index].code; |
| @@ -392,27 +392,25 @@ static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) · 391 unmodified lines | ||
| 392 | 392 | return 0; |
| 393 | 393 | } |
| 394 | 394 | |
| 395 | −static int mt9v011_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) | |
| 395 | +static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, | |
| 396 | + enum v4l2_mbus_pixelcode *code) | |
| 396 | 397 | { |
| 397 | − if (fmt->index > 0) | |
| 398 | + if (index > 0) | |
| 398 | 399 | return -EINVAL; |
| 399 | 400 | |
| 400 | − fmt->flags = 0; | |
| 401 | − strcpy(fmt->description, "8 bpp Bayer GRGR..BGBG"); | |
| 402 | − fmt->pixelformat = V4L2_PIX_FMT_SGRBG8; | |
| 403 | − | |
| 401 | + *code = V4L2_MBUS_FMT_SGRBG8_1X8; | |
| 404 | 402 | return 0; |
| 405 | 403 | } |
| 406 | 404 | |
| 407 | −static int mt9v011_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 405 | +static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) | |
| 408 | 406 | { |
| 409 | − struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
| 410 | − | |
| 411 | − if (pix->pixelformat != V4L2_PIX_FMT_SGRBG8) | |
| 407 | + if (fmt->code != V4L2_MBUS_FMT_SGRBG8_1X8) | |
| 412 | 408 | return -EINVAL; |
| 413 | 409 | |
| 414 | − v4l_bound_align_image(&pix->width, 48, 639, 1, | |
| 415 | − &pix->height, 32, 480, 1, 0); | |
| 410 | + v4l_bound_align_image(&fmt->width, 48, 639, 1, | |
| 411 | + &fmt->height, 32, 480, 1, 0); | |
| 412 | + fmt->field = V4L2_FIELD_NONE; | |
| 413 | + fmt->colorspace = V4L2_COLORSPACE_SRGB; | |
| 416 | 414 | |
| 417 | 415 | return 0; |
| 418 | 416 | } |
| @@ -455,18 +453,17 @@ static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) · 36 unmodified lines | ||
| 455 | 453 | return 0; |
| 456 | 454 | } |
| 457 | 455 | |
| 458 | −static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 456 | +static int mt9v011_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) | |
| 459 | 457 | { |
| 460 | − struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
| 461 | 458 | struct mt9v011 *core = to_mt9v011(sd); |
| 462 | 459 | int rc; |
| 463 | 460 | |
| 464 | − rc = mt9v011_try_fmt(sd, fmt); | |
| 461 | + rc = mt9v011_try_mbus_fmt(sd, fmt); | |
| 465 | 462 | if (rc < 0) |
| 466 | 463 | return -EINVAL; |
| 467 | 464 | |
| 468 | − core->width = pix->width; | |
| 469 | − core->height = pix->height; | |
| 465 | + core->width = fmt->width; | |
| 466 | + core->height = fmt->height; | |
| 470 | 467 | |
| 471 | 468 | set_res(sd); |
| 472 | 469 | |
| @@ -549,9 +546,9 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = { · 76 unmodified lines | ||
| 549 | 546 | }; |
| 550 | 547 | |
| 551 | 548 | static const struct v4l2_subdev_video_ops mt9v011_video_ops = { |
| 552 | − .enum_fmt = mt9v011_enum_fmt, | |
| 553 | − .try_fmt = mt9v011_try_fmt, | |
| 554 | − .s_fmt = mt9v011_s_fmt, | |
| 549 | + .enum_mbus_fmt = mt9v011_enum_mbus_fmt, | |
| 550 | + .try_mbus_fmt = mt9v011_try_mbus_fmt, | |
| 551 | + .s_mbus_fmt = mt9v011_s_mbus_fmt, | |
| 555 | 552 | .g_parm = mt9v011_g_parm, |
| 556 | 553 | .s_parm = mt9v011_s_parm, |
| 557 | 554 | }; |
| @@ -838,13 +838,13 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { · 837 unmodified lines | ||
| 838 | 838 | #endif |
| 839 | 839 | }; |
| 840 | 840 | |
| 841 | −static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 841 | +static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 842 | 842 | enum v4l2_mbus_pixelcode *code) |
| 843 | 843 | { |
| 844 | 844 | struct i2c_client *client = sd->priv; |
| 845 | 845 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
| 846 | 846 | |
| 847 | − if ((unsigned int)index >= mt9v022->num_fmts) | |
| 847 | + if (index >= mt9v022->num_fmts) | |
| 848 | 848 | return -EINVAL; |
| 849 | 849 | |
| 850 | 850 | *code = mt9v022->fmts[index].code; |
| @@ -672,7 +672,7 @@ static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) · 671 unmodified lines | ||
| 672 | 672 | fmt->packing == SOC_MBUS_PACKING_EXTEND16); |
| 673 | 673 | } |
| 674 | 674 | |
| 675 | −static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, | |
| 675 | +static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int idx, | |
| 676 | 676 | struct soc_camera_format_xlate *xlate) |
| 677 | 677 | { |
| 678 | 678 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| @@ -689,7 +689,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, · 10 unmodified lines | ||
| 689 | 689 | fmt = soc_mbus_get_fmtdesc(code); |
| 690 | 690 | if (!fmt) { |
| 691 | 691 | dev_err(icd->dev.parent, |
| 692 | − "Invalid format code #%d: %d\n", idx, code); | |
| 692 | + "Invalid format code #%u: %d\n", idx, code); | |
| 693 | 693 | return 0; |
| 694 | 694 | } |
| 695 | 695 | |
| @@ -2371,12 +2371,11 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) · 2370 unmodified lines | ||
| 2371 | 2371 | |
| 2372 | 2372 | for (k = 0; k < pdev->num_resources; k++) { |
| 2373 | 2373 | |
| 2374 | − vout = kmalloc(sizeof(struct omap_vout_device), GFP_KERNEL); | |
| 2374 | + vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL); | |
| 2375 | 2375 | if (!vout) { |
| 2376 | 2376 | dev_err(&pdev->dev, ": could not allocate memory\n"); |
| 2377 | 2377 | return -ENOMEM; |
| 2378 | 2378 | } |
| 2379 | − memset(vout, 0, sizeof(struct omap_vout_device)); | |
| 2380 | 2379 | |
| 2381 | 2380 | vout->vid = k; |
| 2382 | 2381 | vid_dev->vouts[k] = vout; |
| @@ -1092,10 +1092,10 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { · 1091 unmodified lines | ||
| 1092 | 1092 | #endif |
| 1093 | 1093 | }; |
| 1094 | 1094 | |
| 1095 | −static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 1095 | +static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 1096 | 1096 | enum v4l2_mbus_pixelcode *code) |
| 1097 | 1097 | { |
| 1098 | − if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts)) | |
| 1098 | + if (index >= ARRAY_SIZE(ov772x_cfmts)) | |
| 1099 | 1099 | return -EINVAL; |
| 1100 | 1100 | |
| 1101 | 1101 | *code = ov772x_cfmts[index].code; |
| @@ -614,10 +614,10 @@ static int ov9640_try_fmt(struct v4l2_subdev *sd, · 613 unmodified lines | ||
| 614 | 614 | return 0; |
| 615 | 615 | } |
| 616 | 616 | |
| 617 | −static int ov9640_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 617 | +static int ov9640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 618 | 618 | enum v4l2_mbus_pixelcode *code) |
| 619 | 619 | { |
| 620 | − if ((unsigned int)index >= ARRAY_SIZE(ov9640_codes)) | |
| 620 | + if (index >= ARRAY_SIZE(ov9640_codes)) | |
| 621 | 621 | return -EINVAL; |
| 622 | 622 | |
| 623 | 623 | *code = ov9640_codes[index]; |
| @@ -117,6 +117,7 @@ static const struct pvr2_device_desc pvr2_device_24xxx = { · 116 unmodified lines | ||
| 117 | 117 | static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = { |
| 118 | 118 | { .module_id = PVR2_CLIENT_ID_CX25840 }, |
| 119 | 119 | { .module_id = PVR2_CLIENT_ID_TUNER }, |
| 120 | + { .module_id = PVR2_CLIENT_ID_DEMOD }, | |
| 120 | 121 | }; |
| 121 | 122 | |
| 122 | 123 | static const struct pvr2_device_desc pvr2_device_gotview_2 = { |
| @@ -177,6 +177,11 @@ struct pvr2_device_desc { · 176 unmodified lines | ||
| 177 | 177 | unsigned int flag_has_composite:1; /* Has composite input */ |
| 178 | 178 | unsigned int flag_has_svideo:1; /* Has s-video input */ |
| 179 | 179 | unsigned int flag_fx2_16kb:1; /* 16KB FX2 firmware OK here */ |
| 180 | + | |
| 181 | + /* If this driver is considered experimental, i.e. not all aspects | |
| 182 | + are working correctly and/or it is untested, mark that fact | |
| 183 | + with this flag. */ | |
| 184 | + unsigned int flag_is_experimental:1; | |
| 180 | 185 | }; |
| 181 | 186 | |
| 182 | 187 | extern struct usb_device_id pvr2_device_table[]; |
| @@ -2459,6 +2459,19 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, · 2458 unmodified lines | ||
| 2459 | 2459 | hdw,hdw_desc->description); |
| 2460 | 2460 | pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s", |
| 2461 | 2461 | hdw_desc->description); |
| 2462 | + if (hdw_desc->flag_is_experimental) { | |
| 2463 | + pvr2_trace(PVR2_TRACE_INFO, "**********"); | |
| 2464 | + pvr2_trace(PVR2_TRACE_INFO, | |
| 2465 | + "WARNING: Support for this device (%s) is" | |
| 2466 | + " experimental.", hdw_desc->description); | |
| 2467 | + pvr2_trace(PVR2_TRACE_INFO, | |
| 2468 | + "Important functionality might not be" | |
| 2469 | + " entirely working."); | |
| 2470 | + pvr2_trace(PVR2_TRACE_INFO, | |
| 2471 | + "Please consider contacting the driver author to" | |
| 2472 | + " help with further stabilization of the driver."); | |
| 2473 | + pvr2_trace(PVR2_TRACE_INFO, "**********"); | |
| 2474 | + } | |
| 2462 | 2475 | if (!hdw) goto fail; |
| 2463 | 2476 | |
| 2464 | 2477 | init_timer(&hdw->quiescent_timer); |
| @@ -3056,14 +3069,14 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) · 591 unmodified lines | ||
| 3056 | 3069 | } |
| 3057 | 3070 | |
| 3058 | 3071 | if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) { |
| 3059 | − struct v4l2_format fmt; | |
| 3072 | + struct v4l2_mbus_framefmt fmt; | |
| 3060 | 3073 | memset(&fmt, 0, sizeof(fmt)); |
| 3061 | − fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |
| 3062 | − fmt.fmt.pix.width = hdw->res_hor_val; | |
| 3063 | − fmt.fmt.pix.height = hdw->res_ver_val; | |
| 3074 | + fmt.width = hdw->res_hor_val; | |
| 3075 | + fmt.height = hdw->res_ver_val; | |
| 3076 | + fmt.code = V4L2_MBUS_FMT_FIXED; | |
| 3064 | 3077 | pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)", |
| 3065 | − fmt.fmt.pix.width, fmt.fmt.pix.height); | |
| 3066 | − v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt); | |
| 3078 | + fmt.width, fmt.height); | |
| 3079 | + v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_mbus_fmt, &fmt); | |
| 3067 | 3080 | } |
| 3068 | 3081 | |
| 3069 | 3082 | if (hdw->srate_dirty || hdw->force_dirty) { |
| @@ -4084,12 +4097,20 @@ void pvr2_hdw_device_reset(struct pvr2_hdw *hdw) · 1014 unmodified lines | ||
| 4084 | 4097 | |
| 4085 | 4098 | void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) |
| 4086 | 4099 | { |
| 4087 | − char da[1]; | |
| 4100 | + char *da; | |
| 4088 | 4101 | unsigned int pipe; |
| 4089 | 4102 | int ret; |
| 4090 | 4103 | |
| 4091 | 4104 | if (!hdw->usb_dev) return; |
| 4092 | 4105 | |
| 4106 | + da = kmalloc(16, GFP_KERNEL); | |
| 4107 | + | |
| 4108 | + if (da == NULL) { | |
| 4109 | + pvr2_trace(PVR2_TRACE_ERROR_LEGS, | |
| 4110 | + "Unable to allocate memory to control CPU reset"); | |
| 4111 | + return; | |
| 4112 | + } | |
| 4113 | + | |
| 4093 | 4114 | pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val); |
| 4094 | 4115 | |
| 4095 | 4116 | da[0] = val ? 0x01 : 0x00; |
| @@ -4103,6 +4124,8 @@ void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) · 7 unmodified lines | ||
| 4103 | 4124 | "cpureset_assert(%d) error=%d",val,ret); |
| 4104 | 4125 | pvr2_hdw_render_useless(hdw); |
| 4105 | 4126 | } |
| 4127 | + | |
| 4128 | + kfree(da); | |
| 4106 | 4129 | } |
| 4107 | 4130 | |
| 4108 | 4131 | |
| @@ -153,12 +153,12 @@ static void __exit pvr_exit(void) · 152 unmodified lines | ||
| 153 | 153 | |
| 154 | 154 | usb_deregister(&pvr_driver); |
| 155 | 155 | |
| 156 | + pvr2_context_global_done(); | |
| 157 | + | |
| 156 | 158 | #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS |
| 157 | 159 | pvr2_sysfs_class_destroy(class_ptr); |
| 158 | 160 | #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ |
| 159 | 161 | |
| 160 | − pvr2_context_global_done(); | |
| 161 | − | |
| 162 | 162 | pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete"); |
| 163 | 163 | } |
| 164 | 164 | |
| @@ -74,7 +74,7 @@ struct pvr2_sysfs_ctl_item { · 73 unmodified lines | ||
| 74 | 74 | int ctl_id; |
| 75 | 75 | struct pvr2_sysfs *chptr; |
| 76 | 76 | struct pvr2_sysfs_ctl_item *item_next; |
| 77 | − struct attribute *attr_gen[7]; | |
| 77 | + struct attribute *attr_gen[8]; | |
| 78 | 78 | struct attribute_group grp; |
| 79 | 79 | int created_ok; |
| 80 | 80 | char name[80]; |
| @@ -511,6 +511,7 @@ static void pvr2_sysfs_release(struct device *class_dev) · 430 unmodified lines | ||
| 511 | 511 | |
| 512 | 512 | static void class_dev_destroy(struct pvr2_sysfs *sfp) |
| 513 | 513 | { |
| 514 | + struct device *dev; | |
| 514 | 515 | if (!sfp->class_dev) return; |
| 515 | 516 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC |
| 516 | 517 | pvr2_sysfs_tear_down_debugifc(sfp); |
| @@ -542,6 +543,9 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp) · 25 unmodified lines | ||
| 542 | 543 | } |
| 543 | 544 | pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); |
| 544 | 545 | dev_set_drvdata(sfp->class_dev, NULL); |
| 546 | + dev = sfp->class_dev->parent; | |
| 547 | + sfp->class_dev->parent = NULL; | |
| 548 | + put_device(dev); | |
| 545 | 549 | device_unregister(sfp->class_dev); |
| 546 | 550 | sfp->class_dev = NULL; |
| 547 | 551 | } |
| @@ -631,10 +635,11 @@ static void class_dev_create(struct pvr2_sysfs *sfp, · 83 unmodified lines | ||
| 631 | 635 | pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); |
| 632 | 636 | |
| 633 | 637 | class_dev->class = &class_ptr->class; |
| 638 | + | |
| 634 | 639 | dev_set_name(class_dev, "%s", |
| 635 | 640 | pvr2_hdw_get_device_identifier(sfp->channel.hdw)); |
| 636 | 641 | |
| 637 | − class_dev->parent = &usb_dev->dev; | |
| 642 | + class_dev->parent = get_device(&usb_dev->dev); | |
| 638 | 643 | |
| 639 | 644 | sfp->class_dev = class_dev; |
| 640 | 645 | dev_set_drvdata(class_dev, sfp); |
| @@ -775,7 +780,8 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) · 134 unmodified lines | ||
| 775 | 780 | struct pvr2_sysfs_class *clp; |
| 776 | 781 | clp = kzalloc(sizeof(*clp),GFP_KERNEL); |
| 777 | 782 | if (!clp) return clp; |
| 778 | − pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp); | |
| 783 | + pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p", | |
| 784 | + clp); | |
| 779 | 785 | clp->class.name = "pvrusb2"; |
| 780 | 786 | clp->class.class_release = pvr2_sysfs_class_release; |
| 781 | 787 | clp->class.dev_release = pvr2_sysfs_release; |
| @@ -791,6 +797,7 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) · 9 unmodified lines | ||
| 791 | 797 | |
| 792 | 798 | void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) |
| 793 | 799 | { |
| 800 | + pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp); | |
| 794 | 801 | class_unregister(&clp->class); |
| 795 | 802 | } |
| 796 | 803 | |
| @@ -883,6 +883,17 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) · 882 unmodified lines | ||
| 883 | 883 | { |
| 884 | 884 | struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw; |
| 885 | 885 | enum pvr2_config cfg = dip->config; |
| 886 | + char msg[80]; | |
| 887 | + unsigned int mcnt; | |
| 888 | + | |
| 889 | + /* Construct the unregistration message *before* we actually | |
| 890 | + perform the unregistration step. By doing it this way we don't | |
| 891 | + have to worry about potentially touching deleted resources. */ | |
| 892 | + mcnt = scnprintf(msg, sizeof(msg) - 1, | |
| 893 | + "pvrusb2: unregistered device %s [%s]", | |
| 894 | + video_device_node_name(&dip->devbase), | |
| 895 | + pvr2_config_get_name(cfg)); | |
| 896 | + msg[mcnt] = 0; | |
| 886 | 897 | |
| 887 | 898 | pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1); |
| 888 | 899 | |
| @@ -894,9 +905,7 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) · 5 unmodified lines | ||
| 894 | 905 | are gone. */ |
| 895 | 906 | video_unregister_device(&dip->devbase); |
| 896 | 907 | |
| 897 | − printk(KERN_INFO "pvrusb2: unregistered device %s [%s]\n", | |
| 898 | − video_device_node_name(&dip->devbase), | |
| 899 | − pvr2_config_get_name(cfg)); | |
| 908 | + printk(KERN_INFO "%s\n", msg); | |
| 900 | 909 | |
| 901 | 910 | } |
| 902 | 911 | |
| @@ -1247,7 +1247,7 @@ static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) · 1246 unmodified lines | ||
| 1247 | 1247 | fmt->packing == SOC_MBUS_PACKING_EXTEND16); |
| 1248 | 1248 | } |
| 1249 | 1249 | |
| 1250 | −static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, | |
| 1250 | +static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int idx, | |
| 1251 | 1251 | struct soc_camera_format_xlate *xlate) |
| 1252 | 1252 | { |
| 1253 | 1253 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| @@ -1264,7 +1264,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, · 10 unmodified lines | ||
| 1264 | 1264 | |
| 1265 | 1265 | fmt = soc_mbus_get_fmtdesc(code); |
| 1266 | 1266 | if (!fmt) { |
| 1267 | − dev_err(dev, "Invalid format code #%d: %d\n", idx, code); | |
| 1267 | + dev_err(dev, "Invalid format code #%u: %d\n", idx, code); | |
| 1268 | 1268 | return 0; |
| 1269 | 1269 | } |
| 1270 | 1270 | |
| @@ -481,10 +481,10 @@ static int reg_write_multiple(struct i2c_client *client, · 480 unmodified lines | ||
| 481 | 481 | return 0; |
| 482 | 482 | } |
| 483 | 483 | |
| 484 | −static int rj54n1_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 484 | +static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 485 | 485 | enum v4l2_mbus_pixelcode *code) |
| 486 | 486 | { |
| 487 | − if ((unsigned int)index >= ARRAY_SIZE(rj54n1_colour_fmts)) | |
| 487 | + if (index >= ARRAY_SIZE(rj54n1_colour_fmts)) | |
| 488 | 488 | return -EINVAL; |
| 489 | 489 | |
| 490 | 490 | *code = rj54n1_colour_fmts[index].code; |
| @@ -1117,13 +1117,6 @@ static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f · 1116 unmodified lines | ||
| 1117 | 1117 | return 0; |
| 1118 | 1118 | } |
| 1119 | 1119 | |
| 1120 | −static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 1121 | −{ | |
| 1122 | − if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | |
| 1123 | − return -EINVAL; | |
| 1124 | − return saa711x_g_sliced_fmt(sd, &fmt->fmt.sliced); | |
| 1125 | −} | |
| 1126 | − | |
| 1127 | 1120 | static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt) |
| 1128 | 1121 | { |
| 1129 | 1122 | saa711x_set_lcr(sd, NULL); |
| @@ -1136,12 +1129,13 @@ static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f · 6 unmodified lines | ||
| 1136 | 1129 | return 0; |
| 1137 | 1130 | } |
| 1138 | 1131 | |
| 1139 | −static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 1132 | +static int saa711x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) | |
| 1140 | 1133 | { |
| 1141 | − if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | |
| 1134 | + if (fmt->code != V4L2_MBUS_FMT_FIXED) | |
| 1142 | 1135 | return -EINVAL; |
| 1143 | − | |
| 1144 | − return saa711x_set_size(sd, fmt->fmt.pix.width, fmt->fmt.pix.height); | |
| 1136 | + fmt->field = V4L2_FIELD_INTERLACED; | |
| 1137 | + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; | |
| 1138 | + return saa711x_set_size(sd, fmt->width, fmt->height); | |
| 1145 | 1139 | } |
| 1146 | 1140 | |
| 1147 | 1141 | /* Decode the sliced VBI data stream as created by the saa7115. |
| @@ -1556,8 +1550,7 @@ static const struct v4l2_subdev_audio_ops saa711x_audio_ops = { · 408 unmodified lines | ||
| 1556 | 1550 | static const struct v4l2_subdev_video_ops saa711x_video_ops = { |
| 1557 | 1551 | .s_routing = saa711x_s_routing, |
| 1558 | 1552 | .s_crystal_freq = saa711x_s_crystal_freq, |
| 1559 | − .g_fmt = saa711x_g_fmt, | |
| 1560 | − .s_fmt = saa711x_s_fmt, | |
| 1553 | + .s_mbus_fmt = saa711x_s_mbus_fmt, | |
| 1561 | 1554 | .s_stream = saa711x_s_stream, |
| 1562 | 1555 | .querystd = saa711x_querystd, |
| 1563 | 1556 | .g_input_status = saa711x_g_input_status, |
| @@ -645,13 +645,6 @@ static int saa7127_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f · 644 unmodified lines | ||
| 645 | 645 | return 0; |
| 646 | 646 | } |
| 647 | 647 | |
| 648 | −static int saa7127_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 649 | −{ | |
| 650 | − if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | |
| 651 | − return -EINVAL; | |
| 652 | − return saa7127_g_sliced_fmt(sd, &fmt->fmt.sliced); | |
| 653 | −} | |
| 654 | − | |
| 655 | 648 | static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data) |
| 656 | 649 | { |
| 657 | 650 | switch (data->id) { |
| @@ -731,7 +724,6 @@ static const struct v4l2_subdev_core_ops saa7127_core_ops = { · 73 unmodified lines | ||
| 731 | 724 | }; |
| 732 | 725 | |
| 733 | 726 | static const struct v4l2_subdev_video_ops saa7127_video_ops = { |
| 734 | − .g_fmt = saa7127_g_fmt, | |
| 735 | 727 | .s_std_output = saa7127_s_std_output, |
| 736 | 728 | .s_routing = saa7127_s_routing, |
| 737 | 729 | .s_stream = saa7127_s_stream, |
| @@ -846,24 +846,28 @@ static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_control · 845 unmodified lines | ||
| 846 | 846 | return 0; |
| 847 | 847 | } |
| 848 | 848 | |
| 849 | −static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |
| 849 | +static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) | |
| 850 | 850 | { |
| 851 | 851 | struct saa6752hs_state *h = to_state(sd); |
| 852 | 852 | |
| 853 | 853 | if (h->video_format == SAA6752HS_VF_UNKNOWN) |
| 854 | 854 | h->video_format = SAA6752HS_VF_D1; |
| 855 | − f->fmt.pix.width = | |
| 856 | − v4l2_format_table[h->video_format].fmt.pix.width; | |
| 857 | − f->fmt.pix.height = | |
| 858 | − v4l2_format_table[h->video_format].fmt.pix.height; | |
| 855 | + f->width = v4l2_format_table[h->video_format].fmt.pix.width; | |
| 856 | + f->height = v4l2_format_table[h->video_format].fmt.pix.height; | |
| 857 | + f->code = V4L2_MBUS_FMT_FIXED; | |
| 858 | + f->field = V4L2_FIELD_INTERLACED; | |
| 859 | + f->colorspace = V4L2_COLORSPACE_SMPTE170M; | |
| 859 | 860 | return 0; |
| 860 | 861 | } |
| 861 | 862 | |
| 862 | −static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |
| 863 | +static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) | |
| 863 | 864 | { |
| 864 | 865 | struct saa6752hs_state *h = to_state(sd); |
| 865 | 866 | int dist_352, dist_480, dist_720; |
| 866 | 867 | |
| 868 | + if (f->code != V4L2_MBUS_FMT_FIXED) | |
| 869 | + return -EINVAL; | |
| 870 | + | |
| 867 | 871 | /* |
| 868 | 872 | FIXME: translate and round width/height into EMPRESS |
| 869 | 873 | subsample type: |
| @@ -876,28 +880,30 @@ static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) · 6 unmodified lines | ||
| 876 | 880 | D1 | 720x576 | 720x480 |
| 877 | 881 | */ |
| 878 | 882 | |
| 879 | − dist_352 = abs(f->fmt.pix.width - 352); | |
| 880 | − dist_480 = abs(f->fmt.pix.width - 480); | |
| 881 | − dist_720 = abs(f->fmt.pix.width - 720); | |
| 883 | + dist_352 = abs(f->width - 352); | |
| 884 | + dist_480 = abs(f->width - 480); | |
| 885 | + dist_720 = abs(f->width - 720); | |
| 882 | 886 | if (dist_720 < dist_480) { |
| 883 | − f->fmt.pix.width = 720; | |
| 884 | − f->fmt.pix.height = 576; | |
| 887 | + f->width = 720; | |
| 888 | + f->height = 576; | |
| 885 | 889 | h->video_format = SAA6752HS_VF_D1; |
| 886 | 890 | } else if (dist_480 < dist_352) { |
| 887 | − f->fmt.pix.width = 480; | |
| 888 | − f->fmt.pix.height = 576; | |
| 891 | + f->width = 480; | |
| 892 | + f->height = 576; | |
| 889 | 893 | h->video_format = SAA6752HS_VF_2_3_D1; |
| 890 | 894 | } else { |
| 891 | − f->fmt.pix.width = 352; | |
| 892 | − if (abs(f->fmt.pix.height - 576) < | |
| 893 | − abs(f->fmt.pix.height - 288)) { | |
| 894 | − f->fmt.pix.height = 576; | |
| 895 | + f->width = 352; | |
| 896 | + if (abs(f->height - 576) < | |
| 897 | + abs(f->height - 288)) { | |
| 898 | + f->height = 576; | |
| 895 | 899 | h->video_format = SAA6752HS_VF_1_2_D1; |
| 896 | 900 | } else { |
| 897 | − f->fmt.pix.height = 288; | |
| 901 | + f->height = 288; | |
| 898 | 902 | h->video_format = SAA6752HS_VF_SIF; |
| 899 | 903 | } |
| 900 | 904 | } |
| 905 | + f->field = V4L2_FIELD_INTERLACED; | |
| 906 | + f->colorspace = V4L2_COLORSPACE_SMPTE170M; | |
| 901 | 907 | return 0; |
| 902 | 908 | } |
| 903 | 909 | |
| @@ -932,8 +938,8 @@ static const struct v4l2_subdev_core_ops saa6752hs_core_ops = { · 28 unmodified lines | ||
| 932 | 938 | }; |
| 933 | 939 | |
| 934 | 940 | static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { |
| 935 | − .s_fmt = saa6752hs_s_fmt, | |
| 936 | − .g_fmt = saa6752hs_g_fmt, | |
| 941 | + .s_mbus_fmt = saa6752hs_s_mbus_fmt, | |
| 942 | + .g_mbus_fmt = saa6752hs_g_mbus_fmt, | |
| 937 | 943 | }; |
| 938 | 944 | |
| 939 | 945 | static const struct v4l2_subdev_ops saa6752hs_ops = { |
| @@ -3897,6 +3897,40 @@ struct saa7134_board saa7134_boards[] = { · 3896 unmodified lines | ||
| 3897 | 3897 | .gpio = 0x01, |
| 3898 | 3898 | }, |
| 3899 | 3899 | }, |
| 3900 | + [SAA7134_BOARD_AVERMEDIA_M733A] = { | |
| 3901 | + .name = "Avermedia PCI M733A", | |
| 3902 | + .audio_clock = 0x00187de7, | |
| 3903 | + .tuner_type = TUNER_PHILIPS_TDA8290, | |
| 3904 | + .radio_type = UNSET, | |
| 3905 | + .tuner_addr = ADDR_UNSET, | |
| 3906 | + .radio_addr = ADDR_UNSET, | |
| 3907 | + .tuner_config = 0, | |
| 3908 | + .gpiomask = 0x020200000, | |
| 3909 | + .inputs = {{ | |
| 3910 | + .name = name_tv, | |
| 3911 | + .vmux = 1, | |
| 3912 | + .amux = TV, | |
| 3913 | + .tv = 1, | |
| 3914 | + }, { | |
| 3915 | + .name = name_comp1, | |
| 3916 | + .vmux = 3, | |
| 3917 | + .amux = LINE1, | |
| 3918 | + }, { | |
| 3919 | + .name = name_svideo, | |
| 3920 | + .vmux = 8, | |
| 3921 | + .amux = LINE1, | |
| 3922 | + } }, | |
| 3923 | + .radio = { | |
| 3924 | + .name = name_radio, | |
| 3925 | + .amux = TV, | |
| 3926 | + .gpio = 0x00200000, | |
| 3927 | + }, | |
| 3928 | + .mute = { | |
| 3929 | + .name = name_mute, | |
| 3930 | + .amux = TV, | |
| 3931 | + .gpio = 0x01, | |
| 3932 | + }, | |
| 3933 | + }, | |
| 3900 | 3934 | [SAA7134_BOARD_BEHOLD_401] = { |
| 3901 | 3935 | /* Beholder Intl. Ltd. 2008 */ |
| 3902 | 3936 | /*Dmitry Belimov <d.belimov@gmail.com> */ |
| @@ -5820,6 +5854,18 @@ struct pci_device_id saa7134_pci_tbl[] = { · 1917 unmodified lines | ||
| 5820 | 5854 | .subvendor = 0x1461, /* Avermedia Technologies Inc */ |
| 5821 | 5855 | .subdevice = 0xf11d, |
| 5822 | 5856 | .driver_data = SAA7134_BOARD_AVERMEDIA_M135A, |
| 5857 | + }, { | |
| 5858 | + .vendor = PCI_VENDOR_ID_PHILIPS, | |
| 5859 | + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | |
| 5860 | + .subvendor = 0x1461, /* Avermedia Technologies Inc */ | |
| 5861 | + .subdevice = 0x4155, | |
| 5862 | + .driver_data = SAA7134_BOARD_AVERMEDIA_M733A, | |
| 5863 | + }, { | |
| 5864 | + .vendor = PCI_VENDOR_ID_PHILIPS, | |
| 5865 | + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | |
| 5866 | + .subvendor = 0x1461, /* Avermedia Technologies Inc */ | |
| 5867 | + .subdevice = 0x4255, | |
| 5868 | + .driver_data = SAA7134_BOARD_AVERMEDIA_M733A, | |
| 5823 | 5869 | }, { |
| 5824 | 5870 | .vendor = PCI_VENDOR_ID_PHILIPS, |
| 5825 | 5871 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
| @@ -6786,6 +6832,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev, · 960 unmodified lines | ||
| 6786 | 6832 | switch (dev->board) { |
| 6787 | 6833 | case SAA7134_BOARD_HAUPPAUGE_HVR1150: |
| 6788 | 6834 | case SAA7134_BOARD_HAUPPAUGE_HVR1120: |
| 6835 | + case SAA7134_BOARD_AVERMEDIA_M733A: | |
| 6789 | 6836 | /* tda8290 + tda18271 */ |
| 6790 | 6837 | ret = saa7134_tda8290_18271_callback(dev, command, arg); |
| 6791 | 6838 | break; |
| @@ -7087,6 +7134,14 @@ int saa7134_board_init1(struct saa7134_dev *dev) · 295 unmodified lines | ||
| 7087 | 7134 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0000C000, 0x0000C000); |
| 7088 | 7135 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000C000, 0x0000C000); |
| 7089 | 7136 | break; |
| 7137 | + case SAA7134_BOARD_AVERMEDIA_M733A: | |
| 7138 | + saa7134_set_gpio(dev, 1, 1); | |
| 7139 | + msleep(10); | |
| 7140 | + saa7134_set_gpio(dev, 1, 0); | |
| 7141 | + msleep(10); | |
| 7142 | + saa7134_set_gpio(dev, 1, 1); | |
| 7143 | + dev->has_remote = SAA7134_REMOTE_GPIO; | |
| 7144 | + break; | |
| 7090 | 7145 | } |
| 7091 | 7146 | return 0; |
| 7092 | 7147 | } |
| @@ -223,9 +223,11 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv, · 222 unmodified lines | ||
| 223 | 223 | struct v4l2_format *f) |
| 224 | 224 | { |
| 225 | 225 | struct saa7134_dev *dev = file->private_data; |
| 226 | + struct v4l2_mbus_framefmt mbus_fmt; | |
| 226 | 227 | |
| 227 | − saa_call_all(dev, video, g_fmt, f); | |
| 228 | + saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt); | |
| 228 | 229 | |
| 230 | + v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); | |
| 229 | 231 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
| 230 | 232 | f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; |
| 231 | 233 | |
| @@ -236,8 +238,11 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv, · 4 unmodified lines | ||
| 236 | 238 | struct v4l2_format *f) |
| 237 | 239 | { |
| 238 | 240 | struct saa7134_dev *dev = file->private_data; |
| 241 | + struct v4l2_mbus_framefmt mbus_fmt; | |
| 239 | 242 | |
| 240 | − saa_call_all(dev, video, s_fmt, f); | |
| 243 | + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); | |
| 244 | + saa_call_all(dev, video, s_mbus_fmt, &mbus_fmt); | |
| 245 | + v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); | |
| 241 | 246 | |
| 242 | 247 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
| 243 | 248 | f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; |
| @@ -141,8 +141,8 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) · 140 unmodified lines | ||
| 141 | 141 | struct saa7134_dev *dev = ir->c->adapter->algo_data; |
| 142 | 142 | |
| 143 | 143 | if (dev == NULL) { |
| 144 | − dprintk("get_key_flydvb_trio: " | |
| 145 | − "gir->c->adapter->algo_data is NULL!\n"); | |
| 144 | + i2cdprintk("get_key_flydvb_trio: " | |
| 145 | + "ir->c->adapter->algo_data is NULL!\n"); | |
| 146 | 146 | return -EIO; |
| 147 | 147 | } |
| 148 | 148 | |
| @@ -195,8 +195,8 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, · 46 unmodified lines | ||
| 195 | 195 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ |
| 196 | 196 | struct saa7134_dev *dev = ir->c->adapter->algo_data; |
| 197 | 197 | if (dev == NULL) { |
| 198 | − dprintk("get_key_msi_tvanywhere_plus: " | |
| 199 | − "gir->c->adapter->algo_data is NULL!\n"); | |
| 198 | + i2cdprintk("get_key_msi_tvanywhere_plus: " | |
| 199 | + "ir->c->adapter->algo_data is NULL!\n"); | |
| 200 | 200 | return -EIO; |
| 201 | 201 | } |
| 202 | 202 | |
| @@ -657,12 +657,19 @@ int saa7134_input_init1(struct saa7134_dev *dev) · 454 unmodified lines | ||
| 657 | 657 | saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); |
| 658 | 658 | break; |
| 659 | 659 | case SAA7134_BOARD_AVERMEDIA_M135A: |
| 660 | − ir_codes = RC_MAP_AVERMEDIA_M135A_RM_JX; | |
| 660 | + ir_codes = RC_MAP_AVERMEDIA_M135A; | |
| 661 | 661 | mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ |
| 662 | 662 | mask_keyup = 0x0040000; |
| 663 | 663 | mask_keycode = 0xffff; |
| 664 | 664 | raw_decode = 1; |
| 665 | 665 | break; |
| 666 | + case SAA7134_BOARD_AVERMEDIA_M733A: | |
| 667 | + ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6; | |
| 668 | + mask_keydown = 0x0040000; | |
| 669 | + mask_keyup = 0x0040000; | |
| 670 | + mask_keycode = 0xffff; | |
| 671 | + raw_decode = 1; | |
| 672 | + break; | |
| 666 | 673 | case SAA7134_BOARD_AVERMEDIA_777: |
| 667 | 674 | case SAA7134_BOARD_AVERMEDIA_A16AR: |
| 668 | 675 | ir_codes = RC_MAP_AVERMEDIA; |
| @@ -815,7 +822,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) · 146 unmodified lines | ||
| 815 | 822 | mask_keyup = 0x020000; |
| 816 | 823 | polling = 50; /* ms */ |
| 817 | 824 | break; |
| 818 | − break; | |
| 819 | 825 | } |
| 820 | 826 | if (NULL == ir_codes) { |
| 821 | 827 | printk("%s: Oops: IR config error [card=%d]\n", |
| @@ -303,6 +303,7 @@ struct saa7134_format { · 302 unmodified lines | ||
| 303 | 303 | #define SAA7134_BOARD_HAWELL_HW_404M7 177 |
| 304 | 304 | #define SAA7134_BOARD_BEHOLD_H7 178 |
| 305 | 305 | #define SAA7134_BOARD_BEHOLD_A7 179 |
| 306 | +#define SAA7134_BOARD_AVERMEDIA_M733A 180 | |
| 306 | 307 | |
| 307 | 308 | #define SAA7134_MAXBOARDS 32 |
| 308 | 309 | #define SAA7134_INPUT_MAX 8 |
| @@ -1199,28 +1199,32 @@ static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register * · 1198 unmodified lines | ||
| 1199 | 1199 | } |
| 1200 | 1200 | #endif |
| 1201 | 1201 | |
| 1202 | −static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 1202 | +static int saa717x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) | |
| 1203 | 1203 | { |
| 1204 | − struct v4l2_pix_format *pix; | |
| 1205 | 1204 | int prescale, h_scale, v_scale; |
| 1206 | 1205 | |
| 1207 | − pix = &fmt->fmt.pix; | |
| 1208 | 1206 | v4l2_dbg(1, debug, sd, "decoder set size\n"); |
| 1209 | 1207 | |
| 1208 | + if (fmt->code != V4L2_MBUS_FMT_FIXED) | |
| 1209 | + return -EINVAL; | |
| 1210 | + | |
| 1210 | 1211 | /* FIXME need better bounds checking here */ |
| 1211 | − if (pix->width < 1 || pix->width > 1440) | |
| 1212 | + if (fmt->width < 1 || fmt->width > 1440) | |
| 1212 | 1213 | return -EINVAL; |
| 1213 | − if (pix->height < 1 || pix->height > 960) | |
| 1214 | + if (fmt->height < 1 || fmt->height > 960) | |
| 1214 | 1215 | return -EINVAL; |
| 1215 | 1216 | |
| 1217 | + fmt->field = V4L2_FIELD_INTERLACED; | |
| 1218 | + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; | |
| 1219 | + | |
| 1216 | 1220 | /* scaling setting */ |
| 1217 | 1221 | /* NTSC and interlace only */ |
| 1218 | − prescale = SAA717X_NTSC_WIDTH / pix->width; | |
| 1222 | + prescale = SAA717X_NTSC_WIDTH / fmt->width; | |
| 1219 | 1223 | if (prescale == 0) |
| 1220 | 1224 | prescale = 1; |
| 1221 | − h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / pix->width; | |
| 1225 | + h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / fmt->width; | |
| 1222 | 1226 | /* interlace */ |
| 1223 | − v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / pix->height; | |
| 1227 | + v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / fmt->height; | |
| 1224 | 1228 | |
| 1225 | 1229 | /* Horizontal prescaling etc */ |
| 1226 | 1230 | set_h_prescale(sd, 0, prescale); |
| @@ -1241,19 +1245,19 @@ static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) · 14 unmodified lines | ||
| 1241 | 1245 | /* set video output size */ |
| 1242 | 1246 | /* video number of pixels at output */ |
| 1243 | 1247 | /* TASK A */ |
| 1244 | − saa717x_write(sd, 0x5C, (u8)(pix->width & 0xFF)); | |
| 1245 | − saa717x_write(sd, 0x5D, (u8)((pix->width >> 8) & 0xFF)); | |
| 1248 | + saa717x_write(sd, 0x5C, (u8)(fmt->width & 0xFF)); | |
| 1249 | + saa717x_write(sd, 0x5D, (u8)((fmt->width >> 8) & 0xFF)); | |
| 1246 | 1250 | /* TASK B */ |
| 1247 | − saa717x_write(sd, 0x9C, (u8)(pix->width & 0xFF)); | |
| 1248 | − saa717x_write(sd, 0x9D, (u8)((pix->width >> 8) & 0xFF)); | |
| 1251 | + saa717x_write(sd, 0x9C, (u8)(fmt->width & 0xFF)); | |
| 1252 | + saa717x_write(sd, 0x9D, (u8)((fmt->width >> 8) & 0xFF)); | |
| 1249 | 1253 | |
| 1250 | 1254 | /* video number of lines at output */ |
| 1251 | 1255 | /* TASK A */ |
| 1252 | − saa717x_write(sd, 0x5E, (u8)(pix->height & 0xFF)); | |
| 1253 | − saa717x_write(sd, 0x5F, (u8)((pix->height >> 8) & 0xFF)); | |
| 1256 | + saa717x_write(sd, 0x5E, (u8)(fmt->height & 0xFF)); | |
| 1257 | + saa717x_write(sd, 0x5F, (u8)((fmt->height >> 8) & 0xFF)); | |
| 1254 | 1258 | /* TASK B */ |
| 1255 | − saa717x_write(sd, 0x9E, (u8)(pix->height & 0xFF)); | |
| 1256 | − saa717x_write(sd, 0x9F, (u8)((pix->height >> 8) & 0xFF)); | |
| 1259 | + saa717x_write(sd, 0x9E, (u8)(fmt->height & 0xFF)); | |
| 1260 | + saa717x_write(sd, 0x9F, (u8)((fmt->height >> 8) & 0xFF)); | |
| 1257 | 1261 | return 0; |
| 1258 | 1262 | } |
| 1259 | 1263 | |
| @@ -1403,7 +1407,7 @@ static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = { · 143 unmodified lines | ||
| 1403 | 1407 | |
| 1404 | 1408 | static const struct v4l2_subdev_video_ops saa717x_video_ops = { |
| 1405 | 1409 | .s_routing = saa717x_s_video_routing, |
| 1406 | − .s_fmt = saa717x_s_fmt, | |
| 1410 | + .s_mbus_fmt = saa717x_s_mbus_fmt, | |
| 1407 | 1411 | .s_stream = saa717x_s_stream, |
| 1408 | 1412 | }; |
| 1409 | 1413 | |
| @@ -878,7 +878,7 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt) · 877 unmodified lines | ||
| 878 | 878 | |
| 879 | 879 | static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); |
| 880 | 880 | |
| 881 | −static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, | |
| 881 | +static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx, | |
| 882 | 882 | struct soc_camera_format_xlate *xlate) |
| 883 | 883 | { |
| 884 | 884 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| @@ -897,7 +897,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, · 12 unmodified lines | ||
| 897 | 897 | fmt = soc_mbus_get_fmtdesc(code); |
| 898 | 898 | if (!fmt) { |
| 899 | 899 | dev_err(icd->dev.parent, |
| 900 | − "Invalid format code #%d: %d\n", idx, code); | |
| 900 | + "Invalid format code #%u: %d\n", idx, code); | |
| 901 | 901 | return -EINVAL; |
| 902 | 902 | } |
| 903 | 903 | |
| @@ -62,8 +62,8 @@ static const struct usb_device_id sn9c102_id_table[] = { · 61 unmodified lines | ||
| 62 | 62 | #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE |
| 63 | 63 | { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, |
| 64 | 64 | /* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */ |
| 65 | −#endif | |
| 66 | 65 | { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), }, |
| 66 | +#endif | |
| 67 | 67 | { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, |
| 68 | 68 | /* SN9C103 */ |
| 69 | 69 | { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, |
| @@ -200,7 +200,8 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) · 199 unmodified lines | ||
| 200 | 200 | { |
| 201 | 201 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| 202 | 202 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
| 203 | − int i, fmts = 0, raw_fmts = 0, ret; | |
| 203 | + unsigned int i, fmts = 0, raw_fmts = 0; | |
| 204 | + int ret; | |
| 204 | 205 | enum v4l2_mbus_pixelcode code; |
| 205 | 206 | |
| 206 | 207 | while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) |
| @@ -71,7 +71,7 @@ static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd, · 70 unmodified lines | ||
| 71 | 71 | |
| 72 | 72 | static struct v4l2_subdev_core_ops platform_subdev_core_ops; |
| 73 | 73 | |
| 74 | −static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 74 | +static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 75 | 75 | enum v4l2_mbus_pixelcode *code) |
| 76 | 76 | { |
| 77 | 77 | struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); |
| @@ -88,9 +88,6 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable); · 87 unmodified lines | ||
| 88 | 88 | * @pdata: Board specific |
| 89 | 89 | * @ver: Chip version |
| 90 | 90 | * @streaming: TVP5146/47 decoder streaming - enabled or disabled. |
| 91 | − * @pix: Current pixel format | |
| 92 | − * @num_fmts: Number of formats | |
| 93 | − * @fmt_list: Format list | |
| 94 | 91 | * @current_std: Current standard |
| 95 | 92 | * @num_stds: Number of standards |
| 96 | 93 | * @std_list: Standards list |
| @@ -105,13 +102,9 @@ struct tvp514x_decoder { · 8 unmodified lines | ||
| 105 | 102 | int ver; |
| 106 | 103 | int streaming; |
| 107 | 104 | |
| 108 | − struct v4l2_pix_format pix; | |
| 109 | − int num_fmts; | |
| 110 | − const struct v4l2_fmtdesc *fmt_list; | |
| 111 | − | |
| 112 | 105 | enum tvp514x_std current_std; |
| 113 | 106 | int num_stds; |
| 114 | − struct tvp514x_std_info *std_list; | |
| 107 | + const struct tvp514x_std_info *std_list; | |
| 115 | 108 | /* Input and Output Routing parameters */ |
| 116 | 109 | u32 input; |
| 117 | 110 | u32 output; |
| @@ -202,28 +195,13 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = { · 84 unmodified lines | ||
| 202 | 195 | {TOK_TERM, 0, 0}, |
| 203 | 196 | }; |
| 204 | 197 | |
| 205 | −/** | |
| 206 | − * List of image formats supported by TVP5146/47 decoder | |
| 207 | − * Currently we are using 8 bit mode only, but can be | |
| 208 | − * extended to 10/20 bit mode. | |
| 209 | − */ | |
| 210 | −static const struct v4l2_fmtdesc tvp514x_fmt_list[] = { | |
| 211 | − { | |
| 212 | − .index = 0, | |
| 213 | − .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, | |
| 214 | − .flags = 0, | |
| 215 | − .description = "8-bit UYVY 4:2:2 Format", | |
| 216 | − .pixelformat = V4L2_PIX_FMT_UYVY, | |
| 217 | − }, | |
| 218 | −}; | |
| 219 | − | |
| 220 | 198 | /** |
| 221 | 199 | * Supported standards - |
| 222 | 200 | * |
| 223 | 201 | * Currently supports two standards only, need to add support for rest of the |
| 224 | 202 | * modes, like SECAM, etc... |
| 225 | 203 | */ |
| 226 | −static struct tvp514x_std_info tvp514x_std_list[] = { | |
| 204 | +static const struct tvp514x_std_info tvp514x_std_list[] = { | |
| 227 | 205 | /* Standard: STD_NTSC_MJ */ |
| 228 | 206 | [STD_NTSC_MJ] = { |
| 229 | 207 | .width = NTSC_NUM_ACTIVE_PIXELS, |
| @@ -366,13 +344,13 @@ static int tvp514x_write_regs(struct v4l2_subdev *sd, · 136 unmodified lines | ||
| 366 | 344 | } |
| 367 | 345 | |
| 368 | 346 | /** |
| 369 | − * tvp514x_get_current_std() : Get the current standard detected by TVP5146/47 | |
| 347 | + * tvp514x_query_current_std() : Query the current standard detected by TVP5146/47 | |
| 370 | 348 | * @sd: ptr to v4l2_subdev struct |
| 371 | 349 | * |
| 372 | − * Get current standard detected by TVP5146/47, STD_INVALID if there is no | |
| 350 | + * Returns the current standard detected by TVP5146/47, STD_INVALID if there is no | |
| 373 | 351 | * standard detected. |
| 374 | 352 | */ |
| 375 | −static enum tvp514x_std tvp514x_get_current_std(struct v4l2_subdev *sd) | |
| 353 | +static enum tvp514x_std tvp514x_query_current_std(struct v4l2_subdev *sd) | |
| 376 | 354 | { |
| 377 | 355 | u8 std, std_status; |
| 378 | 356 | |
| @@ -518,7 +496,7 @@ static int tvp514x_detect(struct v4l2_subdev *sd, · 139 unmodified lines | ||
| 518 | 496 | * @std_id: standard V4L2 std_id ioctl enum |
| 519 | 497 | * |
| 520 | 498 | * Returns the current standard detected by TVP5146/47. If no active input is |
| 521 | − * detected, returns -EINVAL | |
| 499 | + * detected then *std_id is set to 0 and the function returns 0. | |
| 522 | 500 | */ |
| 523 | 501 | static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) |
| 524 | 502 | { |
| @@ -530,10 +508,12 @@ static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) · 5 unmodified lines | ||
| 530 | 508 | if (std_id == NULL) |
| 531 | 509 | return -EINVAL; |
| 532 | 510 | |
| 533 | − /* get the current standard */ | |
| 534 | − current_std = tvp514x_get_current_std(sd); | |
| 511 | + *std_id = V4L2_STD_UNKNOWN; | |
| 512 | + | |
| 513 | + /* query the current standard */ | |
| 514 | + current_std = tvp514x_query_current_std(sd); | |
| 535 | 515 | if (current_std == STD_INVALID) |
| 536 | − return -EINVAL; | |
| 516 | + return 0; | |
| 537 | 517 | |
| 538 | 518 | input_sel = decoder->input; |
| 539 | 519 | |
| @@ -575,12 +555,11 @@ static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) · 35 unmodified lines | ||
| 575 | 555 | /* check whether signal is locked */ |
| 576 | 556 | sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1); |
| 577 | 557 | if (lock_mask != (sync_lock_status & lock_mask)) |
| 578 | − return -EINVAL; /* No input detected */ | |
| 558 | + return 0; /* No input detected */ | |
| 579 | 559 | |
| 580 | − decoder->current_std = current_std; | |
| 581 | 560 | *std_id = decoder->std_list[current_std].standard.id; |
| 582 | 561 | |
| 583 | − v4l2_dbg(1, debug, sd, "Current STD: %s", | |
| 562 | + v4l2_dbg(1, debug, sd, "Current STD: %s\n", | |
| 584 | 563 | decoder->std_list[current_std].standard.name); |
| 585 | 564 | return 0; |
| 586 | 565 | } |
| @@ -614,7 +593,7 @@ static int tvp514x_s_std(struct v4l2_subdev *sd, v4l2_std_id std_id) · 27 unmodified lines | ||
| 614 | 593 | decoder->tvp514x_regs[REG_VIDEO_STD].val = |
| 615 | 594 | decoder->std_list[i].video_std; |
| 616 | 595 | |
| 617 | − v4l2_dbg(1, debug, sd, "Standard set to: %s", | |
| 596 | + v4l2_dbg(1, debug, sd, "Standard set to: %s\n", | |
| 618 | 597 | decoder->std_list[i].standard.name); |
| 619 | 598 | return 0; |
| 620 | 599 | } |
| @@ -637,7 +616,6 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd, · 16 unmodified lines | ||
| 637 | 616 | int err; |
| 638 | 617 | enum tvp514x_input input_sel; |
| 639 | 618 | enum tvp514x_output output_sel; |
| 640 | − enum tvp514x_std current_std = STD_INVALID; | |
| 641 | 619 | u8 sync_lock_status, lock_mask; |
| 642 | 620 | int try_count = LOCK_RETRY_COUNT; |
| 643 | 621 | |
| @@ -721,11 +699,6 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd, · 77 unmodified lines | ||
| 721 | 699 | /* Allow decoder to sync up with new input */ |
| 722 | 700 | msleep(LOCK_RETRY_DELAY); |
| 723 | 701 | |
| 724 | − /* get the current standard for future reference */ | |
| 725 | − current_std = tvp514x_get_current_std(sd); | |
| 726 | − if (current_std == STD_INVALID) | |
| 727 | − continue; | |
| 728 | − | |
| 729 | 702 | sync_lock_status = tvp514x_read_reg(sd, |
| 730 | 703 | REG_STATUS1); |
| 731 | 704 | if (lock_mask == (sync_lock_status & lock_mask)) |
| @@ -733,15 +706,13 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd, · 1 unmodified line | ||
| 733 | 706 | break; |
| 734 | 707 | } |
| 735 | 708 | |
| 736 | − if ((current_std == STD_INVALID) || (try_count < 0)) | |
| 709 | + if (try_count < 0) | |
| 737 | 710 | return -EINVAL; |
| 738 | 711 | |
| 739 | − decoder->current_std = current_std; | |
| 740 | 712 | decoder->input = input; |
| 741 | 713 | decoder->output = output; |
| 742 | 714 | |
| 743 | − v4l2_dbg(1, debug, sd, "Input set to: %d, std : %d", | |
| 744 | − input_sel, current_std); | |
| 715 | + v4l2_dbg(1, debug, sd, "Input set to: %d\n", input_sel); | |
| 745 | 716 | |
| 746 | 717 | return 0; |
| 747 | 718 | } |
| @@ -794,7 +765,7 @@ tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl) · 46 unmodified lines | ||
| 794 | 765 | return err; |
| 795 | 766 | } |
| 796 | 767 | |
| 797 | − v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d", | |
| 768 | + v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d\n", | |
| 798 | 769 | qctrl->name, qctrl->minimum, qctrl->maximum, |
| 799 | 770 | qctrl->default_value); |
| 800 | 771 | |
| @@ -851,7 +822,7 @@ tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) · 50 unmodified lines | ||
| 851 | 822 | return -EINVAL; |
| 852 | 823 | } |
| 853 | 824 | |
| 854 | − v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d", | |
| 825 | + v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d\n", | |
| 855 | 826 | ctrl->id, ctrl->value); |
| 856 | 827 | return 0; |
| 857 | 828 | } |
| @@ -951,7 +922,7 @@ tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) · 93 unmodified lines | ||
| 951 | 922 | return err; |
| 952 | 923 | } |
| 953 | 924 | |
| 954 | − v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d", | |
| 925 | + v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n", | |
| 955 | 926 | ctrl->id, ctrl->value); |
| 956 | 927 | |
| 957 | 928 | return err; |
| @@ -967,44 +938,33 @@ tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) · 9 unmodified lines | ||
| 967 | 938 | static int |
| 968 | 939 | tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) |
| 969 | 940 | { |
| 970 | − struct tvp514x_decoder *decoder = to_decoder(sd); | |
| 971 | − int index; | |
| 972 | − | |
| 973 | − if (fmt == NULL) | |
| 974 | − return -EINVAL; | |
| 975 | − | |
| 976 | − index = fmt->index; | |
| 977 | − if ((index >= decoder->num_fmts) || (index < 0)) | |
| 978 | − /* Index out of bound */ | |
| 941 | + if (fmt == NULL || fmt->index) | |
| 979 | 942 | return -EINVAL; |
| 980 | 943 | |
| 981 | 944 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 982 | 945 | /* only capture is supported */ |
| 983 | 946 | return -EINVAL; |
| 984 | 947 | |
| 985 | − memcpy(fmt, &decoder->fmt_list[index], | |
| 986 | − sizeof(struct v4l2_fmtdesc)); | |
| 987 | − | |
| 988 | − v4l2_dbg(1, debug, sd, "Current FMT: index - %d (%s)", | |
| 989 | − decoder->fmt_list[index].index, | |
| 990 | − decoder->fmt_list[index].description); | |
| 948 | + /* only one format */ | |
| 949 | + fmt->flags = 0; | |
| 950 | + strlcpy(fmt->description, "8-bit UYVY 4:2:2 Format", | |
| 951 | + sizeof(fmt->description)); | |
| 952 | + fmt->pixelformat = V4L2_PIX_FMT_UYVY; | |
| 991 | 953 | return 0; |
| 992 | 954 | } |
| 993 | 955 | |
| 994 | 956 | /** |
| 995 | − * tvp514x_try_fmt_cap() - V4L2 decoder interface handler for try_fmt | |
| 957 | + * tvp514x_fmt_cap() - V4L2 decoder interface handler for try/s/g_fmt | |
| 996 | 958 | * @sd: pointer to standard V4L2 sub-device structure |
| 997 | 959 | * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure |
| 998 | 960 | * |
| 999 | − * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This | |
| 1000 | − * ioctl is used to negotiate the image capture size and pixel format | |
| 1001 | − * without actually making it take effect. | |
| 961 | + * Implement the VIDIOC_TRY/S/G_FMT ioctl for the CAPTURE buffer type. This | |
| 962 | + * ioctl is used to negotiate the image capture size and pixel format. | |
| 1002 | 963 | */ |
| 1003 | 964 | static int |
| 1004 | −tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) | |
| 965 | +tvp514x_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) | |
| 1005 | 966 | { |
| 1006 | 967 | struct tvp514x_decoder *decoder = to_decoder(sd); |
| 1007 | − int ifmt; | |
| 1008 | 968 | struct v4l2_pix_format *pix; |
| 1009 | 969 | enum tvp514x_std current_std; |
| 1010 | 970 | |
| @@ -1012,105 +972,29 @@ tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) · 1 unmodified line | ||
| 1012 | 972 | return -EINVAL; |
| 1013 | 973 | |
| 1014 | 974 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 1015 | − /* only capture is supported */ | |
| 1016 | − f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |
| 975 | + return -EINVAL; | |
| 1017 | 976 | |
| 1018 | 977 | pix = &f->fmt.pix; |
| 1019 | 978 | |
| 1020 | 979 | /* Calculate height and width based on current standard */ |
| 1021 | − current_std = tvp514x_get_current_std(sd); | |
| 1022 | − if (current_std == STD_INVALID) | |
| 1023 | − return -EINVAL; | |
| 980 | + current_std = decoder->current_std; | |
| 1024 | 981 | |
| 1025 | − decoder->current_std = current_std; | |
| 982 | + pix->pixelformat = V4L2_PIX_FMT_UYVY; | |
| 1026 | 983 | pix->width = decoder->std_list[current_std].width; |
| 1027 | 984 | pix->height = decoder->std_list[current_std].height; |
| 1028 | − | |
| 1029 | − for (ifmt = 0; ifmt < decoder->num_fmts; ifmt++) { | |
| 1030 | − if (pix->pixelformat == | |
| 1031 | − decoder->fmt_list[ifmt].pixelformat) | |
| 1032 | − break; | |
| 1033 | − } | |
| 1034 | − if (ifmt == decoder->num_fmts) | |
| 1035 | − /* None of the format matched, select default */ | |
| 1036 | − ifmt = 0; | |
| 1037 | − pix->pixelformat = decoder->fmt_list[ifmt].pixelformat; | |
| 1038 | − | |
| 1039 | 985 | pix->field = V4L2_FIELD_INTERLACED; |
| 1040 | 986 | pix->bytesperline = pix->width * 2; |
| 1041 | 987 | pix->sizeimage = pix->bytesperline * pix->height; |
| 1042 | 988 | pix->colorspace = V4L2_COLORSPACE_SMPTE170M; |
| 1043 | 989 | pix->priv = 0; |
| 1044 | 990 | |
| 1045 | − v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d" | |
| 1046 | − "Width - %d, Height - %d", | |
| 1047 | − decoder->fmt_list[ifmt].description, pix->bytesperline, | |
| 991 | + v4l2_dbg(1, debug, sd, "FMT: bytesperline - %d" | |
| 992 | + "Width - %d, Height - %d\n", | |
| 993 | + pix->bytesperline, | |
| 1048 | 994 | pix->width, pix->height); |
| 1049 | 995 | return 0; |
| 1050 | 996 | } |
| 1051 | 997 | |
| 1052 | −/** | |
| 1053 | − * tvp514x_s_fmt_cap() - V4L2 decoder interface handler for s_fmt | |
| 1054 | − * @sd: pointer to standard V4L2 sub-device structure | |
| 1055 | − * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure | |
| 1056 | − * | |
| 1057 | − * If the requested format is supported, configures the HW to use that | |
| 1058 | − * format, returns error code if format not supported or HW can't be | |
| 1059 | − * correctly configured. | |
| 1060 | − */ | |
| 1061 | −static int | |
| 1062 | −tvp514x_s_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) | |
| 1063 | −{ | |
| 1064 | − struct tvp514x_decoder *decoder = to_decoder(sd); | |
| 1065 | − struct v4l2_pix_format *pix; | |
| 1066 | − int rval; | |
| 1067 | − | |
| 1068 | − if (f == NULL) | |
| 1069 | − return -EINVAL; | |
| 1070 | − | |
| 1071 | − if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | |
| 1072 | − /* only capture is supported */ | |
| 1073 | − return -EINVAL; | |
| 1074 | − | |
| 1075 | − pix = &f->fmt.pix; | |
| 1076 | − rval = tvp514x_try_fmt_cap(sd, f); | |
| 1077 | − if (rval) | |
| 1078 | − return rval; | |
| 1079 | − | |
| 1080 | − decoder->pix = *pix; | |
| 1081 | − | |
| 1082 | − return rval; | |
| 1083 | −} | |
| 1084 | − | |
| 1085 | −/** | |
| 1086 | − * tvp514x_g_fmt_cap() - V4L2 decoder interface handler for tvp514x_g_fmt_cap | |
| 1087 | − * @sd: pointer to standard V4L2 sub-device structure | |
| 1088 | − * @f: pointer to standard V4L2 v4l2_format structure | |
| 1089 | − * | |
| 1090 | − * Returns the decoder's current pixel format in the v4l2_format | |
| 1091 | − * parameter. | |
| 1092 | − */ | |
| 1093 | −static int | |
| 1094 | −tvp514x_g_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) | |
| 1095 | −{ | |
| 1096 | − struct tvp514x_decoder *decoder = to_decoder(sd); | |
| 1097 | − | |
| 1098 | − if (f == NULL) | |
| 1099 | − return -EINVAL; | |
| 1100 | − | |
| 1101 | − if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | |
| 1102 | − /* only capture is supported */ | |
| 1103 | − return -EINVAL; | |
| 1104 | − | |
| 1105 | − f->fmt.pix = decoder->pix; | |
| 1106 | − | |
| 1107 | − v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d" | |
| 1108 | − "Width - %d, Height - %d", | |
| 1109 | − decoder->pix.bytesperline, | |
| 1110 | − decoder->pix.width, decoder->pix.height); | |
| 1111 | − return 0; | |
| 1112 | −} | |
| 1113 | − | |
| 1114 | 998 | /** |
| 1115 | 999 | * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm |
| 1116 | 1000 | * @sd: pointer to standard V4L2 sub-device structure |
| @@ -1132,15 +1016,8 @@ tvp514x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) · 15 unmodified lines | ||
| 1132 | 1016 | /* only capture is supported */ |
| 1133 | 1017 | return -EINVAL; |
| 1134 | 1018 | |
| 1135 | − memset(a, 0, sizeof(*a)); | |
| 1136 | − a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |
| 1137 | − | |
| 1138 | 1019 | /* get the current standard */ |
| 1139 | − current_std = tvp514x_get_current_std(sd); | |
| 1140 | − if (current_std == STD_INVALID) | |
| 1141 | − return -EINVAL; | |
| 1142 | − | |
| 1143 | − decoder->current_std = current_std; | |
| 1020 | + current_std = decoder->current_std; | |
| 1144 | 1021 | |
| 1145 | 1022 | cparm = &a->parm.capture; |
| 1146 | 1023 | cparm->capability = V4L2_CAP_TIMEPERFRAME; |
| @@ -1175,11 +1052,7 @@ tvp514x_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) · 28 unmodified lines | ||
| 1175 | 1052 | timeperframe = &a->parm.capture.timeperframe; |
| 1176 | 1053 | |
| 1177 | 1054 | /* get the current standard */ |
| 1178 | − current_std = tvp514x_get_current_std(sd); | |
| 1179 | − if (current_std == STD_INVALID) | |
| 1180 | − return -EINVAL; | |
| 1181 | − | |
| 1182 | − decoder->current_std = current_std; | |
| 1055 | + current_std = decoder->current_std; | |
| 1183 | 1056 | |
| 1184 | 1057 | *timeperframe = |
| 1185 | 1058 | decoder->std_list[current_std].standard.frameperiod; |
| @@ -1259,9 +1132,9 @@ static const struct v4l2_subdev_video_ops tvp514x_video_ops = { · 73 unmodified lines | ||
| 1259 | 1132 | .s_routing = tvp514x_s_routing, |
| 1260 | 1133 | .querystd = tvp514x_querystd, |
| 1261 | 1134 | .enum_fmt = tvp514x_enum_fmt_cap, |
| 1262 | − .g_fmt = tvp514x_g_fmt_cap, | |
| 1263 | − .try_fmt = tvp514x_try_fmt_cap, | |
| 1264 | − .s_fmt = tvp514x_s_fmt_cap, | |
| 1135 | + .g_fmt = tvp514x_fmt_cap, | |
| 1136 | + .try_fmt = tvp514x_fmt_cap, | |
| 1137 | + .s_fmt = tvp514x_fmt_cap, | |
| 1265 | 1138 | .g_parm = tvp514x_g_parm, |
| 1266 | 1139 | .s_parm = tvp514x_s_parm, |
| 1267 | 1140 | .s_stream = tvp514x_s_stream, |
| @@ -1274,22 +1147,6 @@ static const struct v4l2_subdev_ops tvp514x_ops = { · 6 unmodified lines | ||
| 1274 | 1147 | |
| 1275 | 1148 | static struct tvp514x_decoder tvp514x_dev = { |
| 1276 | 1149 | .streaming = 0, |
| 1277 | − | |
| 1278 | − .fmt_list = tvp514x_fmt_list, | |
| 1279 | − .num_fmts = ARRAY_SIZE(tvp514x_fmt_list), | |
| 1280 | − | |
| 1281 | − .pix = { | |
| 1282 | − /* Default to NTSC 8-bit YUV 422 */ | |
| 1283 | − .width = NTSC_NUM_ACTIVE_PIXELS, | |
| 1284 | − .height = NTSC_NUM_ACTIVE_LINES, | |
| 1285 | − .pixelformat = V4L2_PIX_FMT_UYVY, | |
| 1286 | − .field = V4L2_FIELD_INTERLACED, | |
| 1287 | − .bytesperline = NTSC_NUM_ACTIVE_PIXELS * 2, | |
| 1288 | − .sizeimage = | |
| 1289 | − NTSC_NUM_ACTIVE_PIXELS * 2 * NTSC_NUM_ACTIVE_LINES, | |
| 1290 | − .colorspace = V4L2_COLORSPACE_SMPTE170M, | |
| 1291 | − }, | |
| 1292 | − | |
| 1293 | 1150 | .current_std = STD_NTSC_MJ, |
| 1294 | 1151 | .std_list = tvp514x_std_list, |
| 1295 | 1152 | .num_stds = ARRAY_SIZE(tvp514x_std_list), |
| @@ -934,17 +934,6 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f · 933 unmodified lines | ||
| 934 | 934 | return 0; |
| 935 | 935 | } |
| 936 | 936 | |
| 937 | −static int tvp5150_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 938 | −{ | |
| 939 | − switch (fmt->type) { | |
| 940 | − case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | |
| 941 | − return tvp5150_s_sliced_fmt(sd, &fmt->fmt.sliced); | |
| 942 | − | |
| 943 | − default: | |
| 944 | − return -EINVAL; | |
| 945 | − } | |
| 946 | −} | |
| 947 | − | |
| 948 | 937 | static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi) |
| 949 | 938 | { |
| 950 | 939 | int i, mask = 0; |
| @@ -960,13 +949,6 @@ static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f · 9 unmodified lines | ||
| 960 | 949 | return 0; |
| 961 | 950 | } |
| 962 | 951 | |
| 963 | −static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |
| 964 | −{ | |
| 965 | − if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | |
| 966 | − return -EINVAL; | |
| 967 | − return tvp5150_g_sliced_fmt(sd, &fmt->fmt.sliced); | |
| 968 | −} | |
| 969 | − | |
| 970 | 952 | static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, |
| 971 | 953 | struct v4l2_dbg_chip_ident *chip) |
| 972 | 954 | { |
| @@ -1054,8 +1036,6 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = { · 81 unmodified lines | ||
| 1054 | 1036 | |
| 1055 | 1037 | static const struct v4l2_subdev_video_ops tvp5150_video_ops = { |
| 1056 | 1038 | .s_routing = tvp5150_s_routing, |
| 1057 | − .g_fmt = tvp5150_g_fmt, | |
| 1058 | − .s_fmt = tvp5150_s_fmt, | |
| 1059 | 1039 | }; |
| 1060 | 1040 | |
| 1061 | 1041 | static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { |
| @@ -903,7 +903,7 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { · 902 unmodified lines | ||
| 903 | 903 | #endif |
| 904 | 904 | }; |
| 905 | 905 | |
| 906 | −static int tw9910_enum_fmt(struct v4l2_subdev *sd, int index, | |
| 906 | +static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |
| 907 | 907 | enum v4l2_mbus_pixelcode *code) |
| 908 | 908 | { |
| 909 | 909 | if (index) |
| @@ -1671,8 +1671,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) · 1670 unmodified lines | ||
| 1671 | 1671 | PDEBUG(DBG_PROBE, ""); |
| 1672 | 1672 | |
| 1673 | 1673 | if (usbvision == NULL) { |
| 1674 | − dev_err(&usbvision->dev->dev, | |
| 1675 | − "%s: usb_get_intfdata() failed\n", __func__); | |
| 1674 | + pr_err("%s: usb_get_intfdata() failed\n", __func__); | |
| 1676 | 1675 | return; |
| 1677 | 1676 | } |
| 1678 | 1677 | |
| @@ -2,7 +2,8 @@ config VIDEO_TM6000 · 1 unmodified line | ||
| 2 | 2 | tristate "TV Master TM5600/6000/6010 driver" |
| 3 | 3 | depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL |
| 4 | 4 | select VIDEO_TUNER |
| 5 | − select TUNER_XC2028 | |
| 5 | + select MEDIA_TUNER_XC2028 | |
| 6 | + select MEDIA_TUNER_XC5000 | |
| 6 | 7 | select VIDEOBUF_VMALLOC |
| 7 | 8 | help |
| 8 | 9 | Support for TM5600/TM6000/TM6010 USB Device |
| @@ -410,5 +410,28 @@ error: · 409 unmodified lines | ||
| 410 | 410 | snd_card_free(card); |
| 411 | 411 | return rc; |
| 412 | 412 | } |
| 413 | −EXPORT_SYMBOL_GPL(tm6000_audio_init); | |
| 414 | 413 | |
| 414 | +static int tm6000_audio_fini(struct tm6000_core *dev) | |
| 415 | +{ | |
| 416 | + return 0; | |
| 417 | +} | |
| 418 | + | |
| 419 | +struct tm6000_ops audio_ops = { | |
| 420 | + .id = TM6000_AUDIO, | |
| 421 | + .name = "TM6000 Audio Extension", | |
| 422 | + .init = tm6000_audio_init, | |
| 423 | + .fini = tm6000_audio_fini, | |
| 424 | +}; | |
| 425 | + | |
| 426 | +static int __init tm6000_alsa_register(void) | |
| 427 | +{ | |
| 428 | + return tm6000_register_extension(&audio_ops); | |
| 429 | +} | |
| 430 | + | |
| 431 | +static void __exit tm6000_alsa_unregister(void) | |
| 432 | +{ | |
| 433 | + tm6000_unregister_extension(&audio_ops); | |
| 434 | +} | |
| 435 | + | |
| 436 | +module_init(tm6000_alsa_register); | |
| 437 | +module_exit(tm6000_alsa_unregister); | |
| @@ -363,13 +363,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg) · 362 unmodified lines | ||
| 363 | 363 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, |
| 364 | 364 | 0x02, arg); |
| 365 | 365 | msleep(10); |
| 366 | − rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, | |
| 367 | − TM6000_GPIO_CLK, 0); | |
| 368 | − if (rc < 0) | |
| 369 | − return rc; | |
| 370 | − msleep(10); | |
| 371 | − rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, | |
| 372 | − TM6000_GPIO_CLK, 1); | |
| 366 | + rc = tm6000_i2c_reset(dev, 10); | |
| 373 | 367 | break; |
| 374 | 368 | case XC2028_TUNER_RESET: |
| 375 | 369 | /* Reset codes during load firmware */ |
| @@ -423,14 +417,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg) · 47 unmodified lines | ||
| 423 | 417 | break; |
| 424 | 418 | |
| 425 | 419 | case 2: |
| 426 | − rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, | |
| 427 | − TM6000_GPIO_CLK, 0); | |
| 428 | − if (rc < 0) | |
| 429 | − return rc; | |
| 430 | − msleep(100); | |
| 431 | − rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, | |
| 432 | − TM6000_GPIO_CLK, 1); | |
| 433 | − msleep(100); | |
| 420 | + rc = tm6000_i2c_reset(dev, 100); | |
| 434 | 421 | break; |
| 435 | 422 | } |
| 436 | 423 | } |
| @@ -563,7 +550,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev) · 126 unmodified lines | ||
| 563 | 550 | |
| 564 | 551 | switch (dev->tuner_type) { |
| 565 | 552 | case TUNER_XC2028: |
| 566 | − tun_setup.tuner_callback = tm6000_tuner_callback;; | |
| 553 | + tun_setup.tuner_callback = tm6000_tuner_callback; | |
| 567 | 554 | break; |
| 568 | 555 | case TUNER_XC5000: |
| 569 | 556 | tun_setup.tuner_callback = tm6000_xc5000_callback; |
| @@ -692,6 +679,10 @@ static int tm6000_init_dev(struct tm6000_core *dev) · 122 unmodified lines | ||
| 692 | 679 | if (rc < 0) |
| 693 | 680 | goto err; |
| 694 | 681 | |
| 682 | + tm6000_add_into_devlist(dev); | |
| 683 | + | |
| 684 | + tm6000_init_extension(dev); | |
| 685 | + | |
| 695 | 686 | if (dev->caps.has_dvb) { |
| 696 | 687 | dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL); |
| 697 | 688 | if (!dev->dvb) { |
| @@ -921,6 +912,25 @@ static void tm6000_usb_disconnect(struct usb_interface *interface) · 223 unmodified lines | ||
| 921 | 912 | } |
| 922 | 913 | #endif |
| 923 | 914 | |
| 915 | + if (dev->gpio.power_led) { | |
| 916 | + switch (dev->model) { | |
| 917 | + case TM6010_BOARD_HAUPPAUGE_900H: | |
| 918 | + case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE: | |
| 919 | + case TM6010_BOARD_TWINHAN_TU501: | |
| 920 | + /* Power led off */ | |
| 921 | + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, | |
| 922 | + dev->gpio.power_led, 0x01); | |
| 923 | + msleep(15); | |
| 924 | + break; | |
| 925 | + case TM6010_BOARD_BEHOLD_WANDER: | |
| 926 | + case TM6010_BOARD_BEHOLD_VOYAGER: | |
| 927 | + /* Power led off */ | |
| 928 | + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, | |
| 929 | + dev->gpio.power_led, 0x00); | |
| 930 | + msleep(15); | |
| 931 | + break; | |
| 932 | + } | |
| 933 | + } | |
| 924 | 934 | tm6000_v4l2_unregister(dev); |
| 925 | 935 | |
| 926 | 936 | tm6000_i2c_unregister(dev); |
| @@ -931,6 +941,9 @@ static void tm6000_usb_disconnect(struct usb_interface *interface) · 4 unmodified lines | ||
| 931 | 941 | |
| 932 | 942 | usb_put_dev(dev->udev); |
| 933 | 943 | |
| 944 | + tm6000_remove_from_devlist(dev); | |
| 945 | + tm6000_close_extension(dev); | |
| 946 | + | |
| 934 | 947 | mutex_unlock(&dev->lock); |
| 935 | 948 | kfree(dev); |
| 936 | 949 | } |
| @@ -153,6 +153,22 @@ int tm6000_get_reg32 (struct tm6000_core *dev, u8 req, u16 value, u16 index) · 152 unmodified lines | ||
| 153 | 153 | return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24; |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | +int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep) | |
| 157 | +{ | |
| 158 | + int rc; | |
| 159 | + | |
| 160 | + rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 0); | |
| 161 | + if (rc < 0) | |
| 162 | + return rc; | |
| 163 | + | |
| 164 | + msleep(tsleep); | |
| 165 | + | |
| 166 | + rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1); | |
| 167 | + msleep(tsleep); | |
| 168 | + | |
| 169 | + return rc; | |
| 170 | +} | |
| 171 | + | |
| 156 | 172 | void tm6000_set_fourcc_format(struct tm6000_core *dev) |
| 157 | 173 | { |
| 158 | 174 | if (dev->dev_type == TM6010) { |
| @@ -323,6 +339,12 @@ int tm6000_init_analog_mode (struct tm6000_core *dev) · 164 unmodified lines | ||
| 323 | 339 | tm6000_set_standard (dev, &dev->norm); |
| 324 | 340 | tm6000_set_audio_bitrate (dev,48000); |
| 325 | 341 | |
| 342 | + /* switch dvb led off */ | |
| 343 | + if (dev->gpio.dvb_led) { | |
| 344 | + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, | |
| 345 | + dev->gpio.dvb_led, 0x01); | |
| 346 | + } | |
| 347 | + | |
| 326 | 348 | return 0; |
| 327 | 349 | } |
| 328 | 350 | |
| @@ -375,6 +397,13 @@ int tm6000_init_digital_mode (struct tm6000_core *dev) · 46 unmodified lines | ||
| 375 | 397 | tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00); |
| 376 | 398 | msleep(100); |
| 377 | 399 | } |
| 400 | + | |
| 401 | + /* switch dvb led on */ | |
| 402 | + if (dev->gpio.dvb_led) { | |
| 403 | + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, | |
| 404 | + dev->gpio.dvb_led, 0x00); | |
| 405 | + } | |
| 406 | + | |
| 378 | 407 | return 0; |
| 379 | 408 | } |
| 380 | 409 | |
| @@ -600,3 +629,95 @@ printk("Original value=%d\n",val); · 219 unmodified lines | ||
| 600 | 629 | return val; |
| 601 | 630 | } |
| 602 | 631 | EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); |
| 632 | + | |
| 633 | +static LIST_HEAD(tm6000_devlist); | |
| 634 | +static DEFINE_MUTEX(tm6000_devlist_mutex); | |
| 635 | + | |
| 636 | +/* | |
| 637 | + * tm6000_realease_resource() | |
| 638 | + */ | |
| 639 | + | |
| 640 | +void tm6000_remove_from_devlist(struct tm6000_core *dev) | |
| 641 | +{ | |
| 642 | + mutex_lock(&tm6000_devlist_mutex); | |
| 643 | + list_del(&dev->devlist); | |
| 644 | + mutex_unlock(&tm6000_devlist_mutex); | |
| 645 | +}; | |
| 646 | + | |
| 647 | +void tm6000_add_into_devlist(struct tm6000_core *dev) | |
| 648 | +{ | |
| 649 | + mutex_lock(&tm6000_devlist_mutex); | |
| 650 | + list_add_tail(&dev->devlist, &tm6000_devlist); | |
| 651 | + mutex_unlock(&tm6000_devlist_mutex); | |
| 652 | +}; | |
| 653 | + | |
| 654 | +/* | |
| 655 | + * Extension interface | |
| 656 | + */ | |
| 657 | + | |
| 658 | +static LIST_HEAD(tm6000_extension_devlist); | |
| 659 | +static DEFINE_MUTEX(tm6000_extension_devlist_lock); | |
| 660 | + | |
| 661 | +int tm6000_register_extension(struct tm6000_ops *ops) | |
| 662 | +{ | |
| 663 | + struct tm6000_core *dev = NULL; | |
| 664 | + | |
| 665 | + mutex_lock(&tm6000_devlist_mutex); | |
| 666 | + mutex_lock(&tm6000_extension_devlist_lock); | |
| 667 | + list_add_tail(&ops->next, &tm6000_extension_devlist); | |
| 668 | + list_for_each_entry(dev, &tm6000_devlist, devlist) { | |
| 669 | + if (dev) | |
| 670 | + ops->init(dev); | |
| 671 | + } | |
| 672 | + printk(KERN_INFO "tm6000: Initialized (%s) extension\n", ops->name); | |
| 673 | + mutex_unlock(&tm6000_extension_devlist_lock); | |
| 674 | + mutex_unlock(&tm6000_devlist_mutex); | |
| 675 | + return 0; | |
| 676 | +} | |
| 677 | +EXPORT_SYMBOL(tm6000_register_extension); | |
| 678 | + | |
| 679 | +void tm6000_unregister_extension(struct tm6000_ops *ops) | |
| 680 | +{ | |
| 681 | + struct tm6000_core *dev = NULL; | |
| 682 | + | |
| 683 | + mutex_lock(&tm6000_devlist_mutex); | |
| 684 | + list_for_each_entry(dev, &tm6000_devlist, devlist) { | |
| 685 | + if (dev) | |
| 686 | + ops->fini(dev); | |
| 687 | + } | |
| 688 | + | |
| 689 | + mutex_lock(&tm6000_extension_devlist_lock); | |
| 690 | + printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name); | |
| 691 | + list_del(&ops->next); | |
| 692 | + mutex_unlock(&tm6000_extension_devlist_lock); | |
| 693 | + mutex_unlock(&tm6000_devlist_mutex); | |
| 694 | +} | |
| 695 | +EXPORT_SYMBOL(tm6000_unregister_extension); | |
| 696 | + | |
| 697 | +void tm6000_init_extension(struct tm6000_core *dev) | |
| 698 | +{ | |
| 699 | + struct tm6000_ops *ops = NULL; | |
| 700 | + | |
| 701 | + mutex_lock(&tm6000_extension_devlist_lock); | |
| 702 | + if (!list_empty(&tm6000_extension_devlist)) { | |
| 703 | + list_for_each_entry(ops, &tm6000_extension_devlist, next) { | |
| 704 | + if (ops->init) | |
| 705 | + ops->init(dev); | |
| 706 | + } | |
| 707 | + } | |
| 708 | + mutex_unlock(&tm6000_extension_devlist_lock); | |
| 709 | +} | |
| 710 | + | |
| 711 | +void tm6000_close_extension(struct tm6000_core *dev) | |
| 712 | +{ | |
| 713 | + struct tm6000_ops *ops = NULL; | |
| 714 | + | |
| 715 | + mutex_lock(&tm6000_extension_devlist_lock); | |
| 716 | + if (!list_empty(&tm6000_extension_devlist)) { | |
| 717 | + list_for_each_entry(ops, &tm6000_extension_devlist, next) { | |
| 718 | + if (ops->fini) | |
| 719 | + ops->fini(dev); | |
| 720 | + } | |
| 721 | + } | |
| 722 | + mutex_unlock(&tm6000_extension_devlist_lock); | |
| 723 | +} | |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <media/tuner.h> |
| 29 | 29 | |
| 30 | 30 | #include "tuner-xc2028.h" |
| 31 | +#include "xc5000.h" | |
| 31 | 32 | |
| 32 | 33 | static void inline print_err_status (struct tm6000_core *dev, |
| 33 | 34 | int packet, int status) |
| @@ -100,7 +101,10 @@ int tm6000_start_stream(struct tm6000_core *dev) · 66 unmodified lines | ||
| 100 | 101 | |
| 101 | 102 | printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__); |
| 102 | 103 | |
| 103 | − tm6000_init_digital_mode(dev); | |
| 104 | + if (dev->mode != TM6000_MODE_DIGITAL) { | |
| 105 | + tm6000_init_digital_mode(dev); | |
| 106 | + dev->mode = TM6000_MODE_DIGITAL; | |
| 107 | + } | |
| 104 | 108 | |
| 105 | 109 | dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); |
| 106 | 110 | if(dvb->bulk_urb == NULL) { |
| @@ -254,27 +258,55 @@ int tm6000_dvb_register(struct tm6000_core *dev) · 147 unmodified lines | ||
| 254 | 258 | dvb->adapter.priv = dev; |
| 255 | 259 | |
| 256 | 260 | if (dvb->frontend) { |
| 257 | − struct xc2028_config cfg = { | |
| 258 | − .i2c_adap = &dev->i2c_adap, | |
| 259 | − .i2c_addr = dev->tuner_addr, | |
| 260 | − }; | |
| 261 | − | |
| 262 | − dvb->frontend->callback = tm6000_tuner_callback; | |
| 263 | − ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); | |
| 264 | − if (ret < 0) { | |
| 265 | − printk(KERN_ERR | |
| 266 | − "tm6000: couldn't register frontend\n"); | |
| 267 | − goto adapter_err; | |
| 268 | − } | |
| 269 | − | |
| 270 | − if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { | |
| 271 | − printk(KERN_ERR "tm6000: couldn't register " | |
| 272 | − "frontend (xc3028)\n"); | |
| 273 | − ret = -EINVAL; | |
| 274 | − goto frontend_err; | |
| 261 | + switch (dev->tuner_type) { | |
| 262 | + case TUNER_XC2028: { | |
| 263 | + struct xc2028_config cfg = { | |
| 264 | + .i2c_adap = &dev->i2c_adap, | |
| 265 | + .i2c_addr = dev->tuner_addr, | |
| 266 | + }; | |
| 267 | + | |
| 268 | + dvb->frontend->callback = tm6000_tuner_callback; | |
| 269 | + ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); | |
| 270 | + if (ret < 0) { | |
| 271 | + printk(KERN_ERR | |
| 272 | + "tm6000: couldn't register frontend\n"); | |
| 273 | + goto adapter_err; | |
| 274 | + } | |
| 275 | + | |
| 276 | + if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { | |
| 277 | + printk(KERN_ERR "tm6000: couldn't register " | |
| 278 | + "frontend (xc3028)\n"); | |
| 279 | + ret = -EINVAL; | |
| 280 | + goto frontend_err; | |
| 281 | + } | |
| 282 | + printk(KERN_INFO "tm6000: XC2028/3028 asked to be " | |
| 283 | + "attached to frontend!\n"); | |
| 284 | + break; | |
| 285 | + } | |
| 286 | + case TUNER_XC5000: { | |
| 287 | + struct xc5000_config cfg = { | |
| 288 | + .i2c_address = dev->tuner_addr, | |
| 289 | + }; | |
| 290 | + | |
| 291 | + dvb->frontend->callback = tm6000_xc5000_callback; | |
| 292 | + ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); | |
| 293 | + if (ret < 0) { | |
| 294 | + printk(KERN_ERR | |
| 295 | + "tm6000: couldn't register frontend\n"); | |
| 296 | + goto adapter_err; | |
| 297 | + } | |
| 298 | + | |
| 299 | + if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) { | |
| 300 | + printk(KERN_ERR "tm6000: couldn't register " | |
| 301 | + "frontend (xc5000)\n"); | |
| 302 | + ret = -EINVAL; | |
| 303 | + goto frontend_err; | |
| 304 | + } | |
| 305 | + printk(KERN_INFO "tm6000: XC5000 asked to be " | |
| 306 | + "attached to frontend!\n"); | |
| 307 | + break; | |
| 308 | + } | |
| 275 | 309 | } |
| 276 | − printk(KERN_INFO "tm6000: XC2028/3028 asked to be " | |
| 277 | − "attached to frontend!\n"); | |
| 278 | 310 | } else { |
| 279 | 311 | printk(KERN_ERR "tm6000: no frontend found\n"); |
| 280 | 312 | } |
| @@ -48,7 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | #define TM6000_MIN_BUF 4 |
| 49 | 49 | #define TM6000_DEF_BUF 8 |
| 50 | 50 | |
| 51 | −#define TM6000_MAX_ISO_PACKETS 40 /* Max number of ISO packets */ | |
| 51 | +#define TM6000_MAX_ISO_PACKETS 46 /* Max number of ISO packets */ | |
| 52 | 52 | |
| 53 | 53 | /* Declare static vars that will be used as parameters */ |
| 54 | 54 | static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ |
| @@ -205,7 +205,11 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp, · 150 unmodified lines | ||
| 205 | 205 | c = (header >> 24) & 0xff; |
| 206 | 206 | |
| 207 | 207 | /* split the header fields */ |
| 208 | − size = (((header & 0x7e) << 1) -1) *4; | |
| 208 | + size = ((header & 0x7e) << 1); | |
| 209 | + | |
| 210 | + if (size > 0) | |
| 211 | + size -= 4; | |
| 212 | + | |
| 209 | 213 | block = (header >> 7) & 0xf; |
| 210 | 214 | field = (header >> 11) & 0x1; |
| 211 | 215 | line = (header >> 12) & 0x1ff; |
| @@ -307,10 +311,12 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp, · 95 unmodified lines | ||
| 307 | 311 | case TM6000_URB_MSG_PTS: |
| 308 | 312 | break; |
| 309 | 313 | case TM6000_URB_MSG_AUDIO: |
| 310 | −/* Need some code to process audio */ | |
| 311 | −printk ("%ld: cmd=%s, size=%d\n", jiffies, | |
| 314 | + /* Need some code to process audio */ | |
| 315 | + printk ("%ld: cmd=%s, size=%d\n", jiffies, | |
| 312 | 316 | tm6000_msg_type[cmd],size); |
| 313 | 317 | break; |
| 318 | + case TM6000_URB_MSG_VBI: | |
| 319 | + break; | |
| 314 | 320 | default: |
| 315 | 321 | dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n", |
| 316 | 322 | tm6000_msg_type[cmd],size); |
| @@ -333,14 +339,23 @@ printk ("%ld: cmd=%s, size=%d\n", jiffies, · 16 unmodified lines | ||
| 333 | 339 | return rc; |
| 334 | 340 | } |
| 335 | 341 | |
| 336 | −static int copy_streams(u8 *data, u8 *out_p, unsigned long len, | |
| 337 | − struct urb *urb, struct tm6000_buffer **buf) | |
| 342 | +static int copy_streams(u8 *data, unsigned long len, | |
| 343 | + struct urb *urb) | |
| 338 | 344 | { |
| 339 | 345 | struct tm6000_dmaqueue *dma_q = urb->context; |
| 340 | 346 | struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); |
| 341 | 347 | u8 *ptr=data, *endp=data+len; |
| 342 | 348 | unsigned long header=0; |
| 343 | 349 | int rc=0; |
| 350 | + struct tm6000_buffer *buf; | |
| 351 | + char *outp = NULL; | |
| 352 | + | |
| 353 | + get_next_buf(dma_q, &buf); | |
| 354 | + if (buf) | |
| 355 | + outp = videobuf_to_vmalloc(&buf->vb); | |
| 356 | + | |
| 357 | + if (!outp) | |
| 358 | + return 0; | |
| 344 | 359 | |
| 345 | 360 | for (ptr=data; ptr<endp;) { |
| 346 | 361 | if (!dev->isoc_ctl.cmd) { |
| @@ -388,14 +403,14 @@ static int copy_streams(u8 *data, u8 *out_p, unsigned long len, · 41 unmodified lines | ||
| 388 | 403 | } |
| 389 | 404 | HEADER: |
| 390 | 405 | /* Copy or continue last copy */ |
| 391 | − rc=copy_packet(urb,header,&ptr,endp,out_p,buf); | |
| 406 | + rc=copy_packet(urb,header,&ptr,endp,outp,&buf); | |
| 392 | 407 | if (rc<0) { |
| 393 | 408 | buf=NULL; |
| 394 | 409 | printk(KERN_ERR "tm6000: buffer underrun at %ld\n", |
| 395 | 410 | jiffies); |
| 396 | 411 | return rc; |
| 397 | 412 | } |
| 398 | − if (!*buf) | |
| 413 | + if (!buf) | |
| 399 | 414 | return 0; |
| 400 | 415 | } |
| 401 | 416 | |
| @@ -404,31 +419,40 @@ HEADER: · 2 unmodified lines | ||
| 404 | 419 | /* |
| 405 | 420 | * Identify the tm5600/6000 buffer header type and properly handles |
| 406 | 421 | */ |
| 407 | −static int copy_multiplexed(u8 *ptr, u8 *out_p, unsigned long len, | |
| 408 | − struct urb *urb, struct tm6000_buffer **buf) | |
| 422 | +static int copy_multiplexed(u8 *ptr, unsigned long len, | |
| 423 | + struct urb *urb) | |
| 409 | 424 | { |
| 410 | 425 | struct tm6000_dmaqueue *dma_q = urb->context; |
| 411 | 426 | struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); |
| 412 | 427 | unsigned int pos=dev->isoc_ctl.pos,cpysize; |
| 413 | 428 | int rc=1; |
| 429 | + struct tm6000_buffer *buf; | |
| 430 | + char *outp = NULL; | |
| 431 | + | |
| 432 | + get_next_buf(dma_q, &buf); | |
| 433 | + if (buf) | |
| 434 | + outp = videobuf_to_vmalloc(&buf->vb); | |
| 435 | + | |
| 436 | + if (!outp) | |
| 437 | + return 0; | |
| 414 | 438 | |
| 415 | 439 | while (len>0) { |
| 416 | − cpysize=min(len,(*buf)->vb.size-pos); | |
| 417 | −//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos); | |
| 418 | − memcpy(&out_p[pos], ptr, cpysize); | |
| 440 | + cpysize=min(len,buf->vb.size-pos); | |
| 441 | + //printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos); | |
| 442 | + memcpy(&outp[pos], ptr, cpysize); | |
| 419 | 443 | pos+=cpysize; |
| 420 | 444 | ptr+=cpysize; |
| 421 | 445 | len-=cpysize; |
| 422 | − if (pos >= (*buf)->vb.size) { | |
| 446 | + if (pos >= buf->vb.size) { | |
| 423 | 447 | pos=0; |
| 424 | 448 | /* Announces that a new buffer were filled */ |
| 425 | − buffer_filled (dev, dma_q, *buf); | |
| 449 | + buffer_filled (dev, dma_q, buf); | |
| 426 | 450 | dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n"); |
| 427 | − get_next_buf (dma_q, buf); | |
| 428 | − if (!*buf) | |
| 451 | + get_next_buf (dma_q, &buf); | |
| 452 | + if (!buf) | |
| 429 | 453 | break; |
| 430 | − out_p = videobuf_to_vmalloc(&((*buf)->vb)); | |
| 431 | − if (!out_p) | |
| 454 | + outp = videobuf_to_vmalloc(&(buf->vb)); | |
| 455 | + if (!outp) | |
| 432 | 456 | return rc; |
| 433 | 457 | pos = 0; |
| 434 | 458 | } |
| @@ -487,52 +511,36 @@ static inline int tm6000_isoc_copy(struct urb *urb) · 52 unmodified lines | ||
| 487 | 511 | struct tm6000_dmaqueue *dma_q = urb->context; |
| 488 | 512 | struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); |
| 489 | 513 | struct tm6000_buffer *buf; |
| 490 | − int i, len=0, rc=1; | |
| 491 | − int size; | |
| 492 | − char *outp = NULL, *p; | |
| 493 | − unsigned long copied; | |
| 494 | − | |
| 495 | − get_next_buf(dma_q, &buf); | |
| 496 | − if (buf) | |
| 497 | − outp = videobuf_to_vmalloc(&buf->vb); | |
| 514 | + int i, len=0, rc=1, status; | |
| 515 | + char *p; | |
| 498 | 516 | |
| 499 | − if (!outp) | |
| 500 | − return 0; | |
| 501 | − | |
| 502 | − size = buf->vb.size; | |
| 503 | − | |
| 504 | − copied=0; | |
| 505 | − | |
| 506 | − if (urb->status<0) { | |
| 507 | − print_err_status (dev,-1,urb->status); | |
| 517 | + if (urb->status < 0) { | |
| 518 | + print_err_status (dev, -1, urb->status); | |
| 508 | 519 | return 0; |
| 509 | 520 | } |
| 510 | 521 | |
| 511 | 522 | for (i = 0; i < urb->number_of_packets; i++) { |
| 512 | − int status = urb->iso_frame_desc[i].status; | |
| 523 | + status = urb->iso_frame_desc[i].status; | |
| 513 | 524 | |
| 514 | 525 | if (status<0) { |
| 515 | 526 | print_err_status (dev,i,status); |
| 516 | 527 | continue; |
| 517 | 528 | } |
| 518 | 529 | |
| 519 | − len=urb->iso_frame_desc[i].actual_length; | |
| 530 | + len = urb->iso_frame_desc[i].actual_length; | |
| 520 | 531 | |
| 521 | −// if (len>=TM6000_URB_MSG_LEN) { | |
| 522 | − p=urb->transfer_buffer + urb->iso_frame_desc[i].offset; | |
| 532 | + if (len > 0) { | |
| 533 | + p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | |
| 523 | 534 | if (!urb->iso_frame_desc[i].status) { |
| 524 | − if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) { | |
| 525 | − rc=copy_multiplexed(p, outp, len, urb, &buf); | |
| 535 | + if ((dev->fourcc)==V4L2_PIX_FMT_TM6000) { | |
| 536 | + rc=copy_multiplexed(p, len, urb); | |
| 526 | 537 | if (rc<=0) |
| 527 | 538 | return rc; |
| 528 | 539 | } else { |
| 529 | − copy_streams(p, outp, len, urb, &buf); | |
| 540 | + copy_streams(p, len, urb); | |
| 530 | 541 | } |
| 531 | 542 | } |
| 532 | − copied += len; | |
| 533 | − if (copied >= size || !buf) | |
| 534 | − break; | |
| 535 | −// } | |
| 543 | + } | |
| 536 | 544 | } |
| 537 | 545 | return rc; |
| 538 | 546 | } |
| @@ -612,7 +620,7 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev) · 73 unmodified lines | ||
| 612 | 620 | static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize) |
| 613 | 621 | { |
| 614 | 622 | struct tm6000_dmaqueue *dma_q = &dev->vidq; |
| 615 | − int i, j, sb_size, pipe, size, max_packets, num_bufs = 5; | |
| 623 | + int i, j, sb_size, pipe, size, max_packets, num_bufs = 8; | |
| 616 | 624 | struct urb *urb; |
| 617 | 625 | |
| 618 | 626 | /* De-allocates all pending stuff */ |
| @@ -168,6 +168,10 @@ struct tm6000_core { · 167 unmodified lines | ||
| 168 | 168 | struct i2c_adapter i2c_adap; |
| 169 | 169 | struct i2c_client i2c_client; |
| 170 | 170 | |
| 171 | + | |
| 172 | + /* extension */ | |
| 173 | + struct list_head devlist; | |
| 174 | + | |
| 171 | 175 | /* video for linux */ |
| 172 | 176 | int users; |
| 173 | 177 | |
| @@ -203,6 +207,16 @@ struct tm6000_core { · 29 unmodified lines | ||
| 203 | 207 | spinlock_t slock; |
| 204 | 208 | }; |
| 205 | 209 | |
| 210 | +#define TM6000_AUDIO 0x10 | |
| 211 | + | |
| 212 | +struct tm6000_ops { | |
| 213 | + struct list_head next; | |
| 214 | + char *name; | |
| 215 | + int id; | |
| 216 | + int (*init)(struct tm6000_core *); | |
| 217 | + int (*fini)(struct tm6000_core *); | |
| 218 | +}; | |
| 219 | + | |
| 206 | 220 | struct tm6000_fh { |
| 207 | 221 | struct tm6000_core *dev; |
| 208 | 222 | |
| @@ -232,6 +246,8 @@ int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index); · 23 unmodified lines | ||
| 232 | 246 | int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index); |
| 233 | 247 | int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index); |
| 234 | 248 | int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index); |
| 249 | +int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep); | |
| 250 | + | |
| 235 | 251 | int tm6000_init (struct tm6000_core *dev); |
| 236 | 252 | |
| 237 | 253 | int tm6000_init_analog_mode (struct tm6000_core *dev); |
| @@ -246,6 +262,13 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev); · 8 unmodified lines | ||
| 246 | 262 | int tm6000_v4l2_exit(void); |
| 247 | 263 | void tm6000_set_fourcc_format(struct tm6000_core *dev); |
| 248 | 264 | |
| 265 | +void tm6000_remove_from_devlist(struct tm6000_core *dev); | |
| 266 | +void tm6000_add_into_devlist(struct tm6000_core *dev); | |
| 267 | +int tm6000_register_extension(struct tm6000_ops *ops); | |
| 268 | +void tm6000_unregister_extension(struct tm6000_ops *ops); | |
| 269 | +void tm6000_init_extension(struct tm6000_core *dev); | |
| 270 | +void tm6000_close_extension(struct tm6000_core *dev); | |
| 271 | + | |
| 249 | 272 | /* In tm6000-stds.c */ |
| 250 | 273 | void tm6000_get_std_res(struct tm6000_core *dev); |
| 251 | 274 | int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm); |
| @@ -275,7 +298,7 @@ unsigned int tm6000_v4l2_poll(struct file *file, · 23 unmodified lines | ||
| 275 | 298 | int tm6000_queue_init(struct tm6000_core *dev); |
| 276 | 299 | |
| 277 | 300 | /* In tm6000-alsa.c */ |
| 278 | −int tm6000_audio_init(struct tm6000_core *dev, int idx); | |
| 301 | +/*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/ | |
| 279 | 302 | |
| 280 | 303 | |
| 281 | 304 | /* Debug stuff */ |
| @@ -55,7 +55,8 @@ void rc_map_init(void); · 54 unmodified lines | ||
| 55 | 55 | #define RC_MAP_AVERMEDIA_A16D "rc-avermedia-a16d" |
| 56 | 56 | #define RC_MAP_AVERMEDIA_CARDBUS "rc-avermedia-cardbus" |
| 57 | 57 | #define RC_MAP_AVERMEDIA_DVBT "rc-avermedia-dvbt" |
| 58 | −#define RC_MAP_AVERMEDIA_M135A_RM_JX "rc-avermedia-m135a-rm-jx" | |
| 58 | +#define RC_MAP_AVERMEDIA_M135A "rc-avermedia-m135a" | |
| 59 | +#define RC_MAP_AVERMEDIA_M733A_RM_K6 "rc-avermedia-m733a-rm-k6" | |
| 59 | 60 | #define RC_MAP_AVERMEDIA "rc-avermedia" |
| 60 | 61 | #define RC_MAP_AVERTV_303 "rc-avertv-303" |
| 61 | 62 | #define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus" |
| @@ -66,7 +66,7 @@ struct soc_camera_host_ops { · 65 unmodified lines | ||
| 66 | 66 | * .get_formats() fail, .put_formats() will not be called at all, the |
| 67 | 67 | * failing .get_formats() must then clean up internally. |
| 68 | 68 | */ |
| 69 | − int (*get_formats)(struct soc_camera_device *, int, | |
| 69 | + int (*get_formats)(struct soc_camera_device *, unsigned int, | |
| 70 | 70 | struct soc_camera_format_xlate *); |
| 71 | 71 | void (*put_formats)(struct soc_camera_device *); |
| 72 | 72 | int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *); |
| @@ -40,6 +40,7 @@ enum v4l2_mbus_pixelcode { · 39 unmodified lines | ||
| 40 | 40 | V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, |
| 41 | 41 | V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, |
| 42 | 42 | V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, |
| 43 | + V4L2_MBUS_FMT_SGRBG8_1X8, | |
| 43 | 44 | }; |
| 44 | 45 | |
| 45 | 46 | /** |
| @@ -58,4 +59,24 @@ struct v4l2_mbus_framefmt { · 12 unmodified lines | ||
| 58 | 59 | enum v4l2_colorspace colorspace; |
| 59 | 60 | }; |
| 60 | 61 | |
| 62 | +static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt, | |
| 63 | + const struct v4l2_mbus_framefmt *mbus_fmt) | |
| 64 | +{ | |
| 65 | + pix_fmt->width = mbus_fmt->width; | |
| 66 | + pix_fmt->height = mbus_fmt->height; | |
| 67 | + pix_fmt->field = mbus_fmt->field; | |
| 68 | + pix_fmt->colorspace = mbus_fmt->colorspace; | |
| 69 | +} | |
| 70 | + | |
| 71 | +static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt, | |
| 72 | + const struct v4l2_pix_format *pix_fmt, | |
| 73 | + enum v4l2_mbus_pixelcode code) | |
| 74 | +{ | |
| 75 | + mbus_fmt->width = pix_fmt->width; | |
| 76 | + mbus_fmt->height = pix_fmt->height; | |
| 77 | + mbus_fmt->field = pix_fmt->field; | |
| 78 | + mbus_fmt->colorspace = pix_fmt->colorspace; | |
| 79 | + mbus_fmt->code = code; | |
| 80 | +} | |
| 81 | + | |
| 61 | 82 | #endif |
| @@ -246,7 +246,7 @@ struct v4l2_subdev_video_ops { · 245 unmodified lines | ||
| 246 | 246 | struct v4l2_dv_timings *timings); |
| 247 | 247 | int (*g_dv_timings)(struct v4l2_subdev *sd, |
| 248 | 248 | struct v4l2_dv_timings *timings); |
| 249 | − int (*enum_mbus_fmt)(struct v4l2_subdev *sd, int index, | |
| 249 | + int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, | |
| 250 | 250 | enum v4l2_mbus_pixelcode *code); |
| 251 | 251 | int (*g_mbus_fmt)(struct v4l2_subdev *sd, |
| 252 | 252 | struct v4l2_mbus_framefmt *fmt); |