aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c219
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c8
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h3
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c77
-rw-r--r--drivers/media/video/em28xx/em28xx.h4
6 files changed, 222 insertions, 91 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 320f1f60276e..1c2e544eda73 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -218,7 +218,7 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = {
218struct em28xx_board em28xx_boards[] = { 218struct em28xx_board em28xx_boards[] = {
219 [EM2750_BOARD_UNKNOWN] = { 219 [EM2750_BOARD_UNKNOWN] = {
220 .name = "EM2710/EM2750/EM2751 webcam grabber", 220 .name = "EM2710/EM2750/EM2751 webcam grabber",
221 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, 221 .xclk = EM28XX_XCLK_FREQUENCY_20MHZ,
222 .tuner_type = TUNER_ABSENT, 222 .tuner_type = TUNER_ABSENT,
223 .is_webcam = 1, 223 .is_webcam = 1,
224 .input = { { 224 .input = { {
@@ -622,22 +622,27 @@ struct em28xx_board em28xx_boards[] = {
622 }, 622 },
623 [EM2861_BOARD_PLEXTOR_PX_TV100U] = { 623 [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
624 .name = "Plextor ConvertX PX-TV100U", 624 .name = "Plextor ConvertX PX-TV100U",
625 .valid = EM28XX_BOARD_NOT_VALIDATED,
626 .tuner_type = TUNER_TNF_5335MF, 625 .tuner_type = TUNER_TNF_5335MF,
626 .xclk = EM28XX_XCLK_I2S_MSB_TIMING |
627 EM28XX_XCLK_FREQUENCY_12MHZ,
627 .tda9887_conf = TDA9887_PRESENT, 628 .tda9887_conf = TDA9887_PRESENT,
628 .decoder = EM28XX_TVP5150, 629 .decoder = EM28XX_TVP5150,
630 .has_msp34xx = 1,
629 .input = { { 631 .input = { {
630 .type = EM28XX_VMUX_TELEVISION, 632 .type = EM28XX_VMUX_TELEVISION,
631 .vmux = TVP5150_COMPOSITE0, 633 .vmux = TVP5150_COMPOSITE0,
632 .amux = EM28XX_AMUX_LINE_IN, 634 .amux = EM28XX_AMUX_LINE_IN,
635 .gpio = pinnacle_hybrid_pro_analog,
633 }, { 636 }, {
634 .type = EM28XX_VMUX_COMPOSITE1, 637 .type = EM28XX_VMUX_COMPOSITE1,
635 .vmux = TVP5150_COMPOSITE1, 638 .vmux = TVP5150_COMPOSITE1,
636 .amux = EM28XX_AMUX_LINE_IN, 639 .amux = EM28XX_AMUX_LINE_IN,
640 .gpio = pinnacle_hybrid_pro_analog,
637 }, { 641 }, {
638 .type = EM28XX_VMUX_SVIDEO, 642 .type = EM28XX_VMUX_SVIDEO,
639 .vmux = TVP5150_SVIDEO, 643 .vmux = TVP5150_SVIDEO,
640 .amux = EM28XX_AMUX_LINE_IN, 644 .amux = EM28XX_AMUX_LINE_IN,
645 .gpio = pinnacle_hybrid_pro_analog,
641 } }, 646 } },
642 }, 647 },
643 648
@@ -1544,6 +1549,8 @@ struct usb_device_id em28xx_id_table[] = {
1544 .driver_info = EM2750_BOARD_UNKNOWN }, 1549 .driver_info = EM2750_BOARD_UNKNOWN },
1545 { USB_DEVICE(0xeb1a, 0x2800), 1550 { USB_DEVICE(0xeb1a, 0x2800),
1546 .driver_info = EM2800_BOARD_UNKNOWN }, 1551 .driver_info = EM2800_BOARD_UNKNOWN },
1552 { USB_DEVICE(0xeb1a, 0x2710),
1553 .driver_info = EM2820_BOARD_UNKNOWN },
1547 { USB_DEVICE(0xeb1a, 0x2820), 1554 { USB_DEVICE(0xeb1a, 0x2820),
1548 .driver_info = EM2820_BOARD_UNKNOWN }, 1555 .driver_info = EM2820_BOARD_UNKNOWN },
1549 { USB_DEVICE(0xeb1a, 0x2821), 1556 { USB_DEVICE(0xeb1a, 0x2821),
@@ -1723,6 +1730,25 @@ static inline void em28xx_set_model(struct em28xx *dev)
1723 EM28XX_I2C_FREQ_100_KHZ; 1730 EM28XX_I2C_FREQ_100_KHZ;
1724} 1731}
1725 1732
1733
1734/* FIXME: Should be replaced by a proper mt9m111 driver */
1735static int em28xx_initialize_mt9m111(struct em28xx *dev)
1736{
1737 int i;
1738 unsigned char regs[][3] = {
1739 { 0x0d, 0x00, 0x01, }, /* reset and use defaults */
1740 { 0x0d, 0x00, 0x00, },
1741 { 0x0a, 0x00, 0x21, },
1742 { 0x21, 0x04, 0x00, }, /* full readout speed, no row/col skipping */
1743 };
1744
1745 for (i = 0; i < ARRAY_SIZE(regs); i++)
1746 i2c_master_send(&dev->i2c_client, &regs[i][0], 3);
1747
1748 return 0;
1749}
1750
1751
1726/* FIXME: Should be replaced by a proper mt9m001 driver */ 1752/* FIXME: Should be replaced by a proper mt9m001 driver */
1727static int em28xx_initialize_mt9m001(struct em28xx *dev) 1753static int em28xx_initialize_mt9m001(struct em28xx *dev)
1728{ 1754{
@@ -1751,7 +1777,7 @@ static int em28xx_initialize_mt9m001(struct em28xx *dev)
1751 1777
1752/* HINT method: webcam I2C chips 1778/* HINT method: webcam I2C chips
1753 * 1779 *
1754 * This method work for webcams with Micron sensors 1780 * This method works for webcams with Micron sensors
1755 */ 1781 */
1756static int em28xx_hint_sensor(struct em28xx *dev) 1782static int em28xx_hint_sensor(struct em28xx *dev)
1757{ 1783{
@@ -1761,6 +1787,7 @@ static int em28xx_hint_sensor(struct em28xx *dev)
1761 __be16 version_be; 1787 __be16 version_be;
1762 u16 version; 1788 u16 version;
1763 1789
1790 /* Micron sensor detection */
1764 dev->i2c_client.addr = 0xba >> 1; 1791 dev->i2c_client.addr = 0xba >> 1;
1765 cmd = 0; 1792 cmd = 0;
1766 i2c_master_send(&dev->i2c_client, &cmd, 1); 1793 i2c_master_send(&dev->i2c_client, &cmd, 1);
@@ -1769,23 +1796,54 @@ static int em28xx_hint_sensor(struct em28xx *dev)
1769 return -EINVAL; 1796 return -EINVAL;
1770 1797
1771 version = be16_to_cpu(version_be); 1798 version = be16_to_cpu(version_be);
1772
1773 switch (version) { 1799 switch (version) {
1774 case 0x8243: /* mt9v011 640x480 1.3 Mpix sensor */ 1800 case 0x8232: /* mt9v011 640x480 1.3 Mpix sensor */
1801 case 0x8243: /* mt9v011 rev B 640x480 1.3 Mpix sensor */
1775 dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; 1802 dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
1803 em28xx_set_model(dev);
1804
1776 sensor_name = "mt9v011"; 1805 sensor_name = "mt9v011";
1777 dev->em28xx_sensor = EM28XX_MT9V011; 1806 dev->em28xx_sensor = EM28XX_MT9V011;
1778 dev->sensor_xres = 640; 1807 dev->sensor_xres = 640;
1779 dev->sensor_yres = 480; 1808 dev->sensor_yres = 480;
1780 dev->sensor_xtal = 6300000; 1809 /*
1810 * FIXME: mt9v011 uses I2S speed as xtal clk - at least with
1811 * the Silvercrest cam I have here for testing - for higher
1812 * resolutions, a high clock cause horizontal artifacts, so we
1813 * need to use a lower xclk frequency.
1814 * Yet, it would be possible to adjust xclk depending on the
1815 * desired resolution, since this affects directly the
1816 * frame rate.
1817 */
1818 dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ;
1819 dev->sensor_xtal = 4300000;
1781 1820
1782 /* probably means GRGB 16 bit bayer */ 1821 /* probably means GRGB 16 bit bayer */
1783 dev->vinmode = 0x0d; 1822 dev->vinmode = 0x0d;
1784 dev->vinctl = 0x00; 1823 dev->vinctl = 0x00;
1785 1824
1786 break; 1825 break;
1826
1827 case 0x143a: /* MT9M111 as found in the ECS G200 */
1828 dev->model = EM2750_BOARD_UNKNOWN;
1829 em28xx_set_model(dev);
1830
1831 sensor_name = "mt9m111";
1832 dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ;
1833 dev->em28xx_sensor = EM28XX_MT9M111;
1834 em28xx_initialize_mt9m111(dev);
1835 dev->sensor_xres = 640;
1836 dev->sensor_yres = 512;
1837
1838 dev->vinmode = 0x0a;
1839 dev->vinctl = 0x00;
1840
1841 break;
1842
1787 case 0x8431: 1843 case 0x8431:
1788 dev->model = EM2750_BOARD_UNKNOWN; 1844 dev->model = EM2750_BOARD_UNKNOWN;
1845 em28xx_set_model(dev);
1846
1789 sensor_name = "mt9m001"; 1847 sensor_name = "mt9m001";
1790 dev->em28xx_sensor = EM28XX_MT9M001; 1848 dev->em28xx_sensor = EM28XX_MT9M001;
1791 em28xx_initialize_mt9m001(dev); 1849 em28xx_initialize_mt9m001(dev);
@@ -1798,10 +1856,13 @@ static int em28xx_hint_sensor(struct em28xx *dev)
1798 1856
1799 break; 1857 break;
1800 default: 1858 default:
1801 printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version)); 1859 printk("Unknown Micron Sensor 0x%04x\n", version);
1802 return -EINVAL; 1860 return -EINVAL;
1803 } 1861 }
1804 1862
1863 /* Setup webcam defaults */
1864 em28xx_pre_card_setup(dev);
1865
1805 em28xx_errdev("Sensor is %s, using model %s entry.\n", 1866 em28xx_errdev("Sensor is %s, using model %s entry.\n",
1806 sensor_name, em28xx_boards[dev->model].name); 1867 sensor_name, em28xx_boards[dev->model].name);
1807 1868
@@ -1813,60 +1874,6 @@ static int em28xx_hint_sensor(struct em28xx *dev)
1813 */ 1874 */
1814void em28xx_pre_card_setup(struct em28xx *dev) 1875void em28xx_pre_card_setup(struct em28xx *dev)
1815{ 1876{
1816 int rc;
1817
1818 em28xx_set_model(dev);
1819
1820 em28xx_info("Identified as %s (card=%d)\n",
1821 dev->board.name, dev->model);
1822
1823 /* Set the default GPO/GPIO for legacy devices */
1824 dev->reg_gpo_num = EM2880_R04_GPO;
1825 dev->reg_gpio_num = EM28XX_R08_GPIO;
1826
1827 dev->wait_after_write = 5;
1828
1829 /* Based on the Chip ID, set the device configuration */
1830 rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
1831 if (rc > 0) {
1832 dev->chip_id = rc;
1833
1834 switch (dev->chip_id) {
1835 case CHIP_ID_EM2750:
1836 em28xx_info("chip ID is em2750\n");
1837 break;
1838 case CHIP_ID_EM2820:
1839 em28xx_info("chip ID is em2710 or em2820\n");
1840 break;
1841 case CHIP_ID_EM2840:
1842 em28xx_info("chip ID is em2840\n");
1843 break;
1844 case CHIP_ID_EM2860:
1845 em28xx_info("chip ID is em2860\n");
1846 break;
1847 case CHIP_ID_EM2870:
1848 em28xx_info("chip ID is em2870\n");
1849 dev->wait_after_write = 0;
1850 break;
1851 case CHIP_ID_EM2874:
1852 em28xx_info("chip ID is em2874\n");
1853 dev->reg_gpio_num = EM2874_R80_GPIO;
1854 dev->wait_after_write = 0;
1855 break;
1856 case CHIP_ID_EM2883:
1857 em28xx_info("chip ID is em2882/em2883\n");
1858 dev->wait_after_write = 0;
1859 break;
1860 default:
1861 em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
1862 }
1863 }
1864
1865 /* Prepopulate cached GPO register content */
1866 rc = em28xx_read_reg(dev, dev->reg_gpo_num);
1867 if (rc >= 0)
1868 dev->reg_gpo = rc;
1869
1870 /* Set the initial XCLK and I2C clock values based on the board 1877 /* Set the initial XCLK and I2C clock values based on the board
1871 definition */ 1878 definition */
1872 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f); 1879 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f);
@@ -1876,9 +1883,8 @@ void em28xx_pre_card_setup(struct em28xx *dev)
1876 /* request some modules */ 1883 /* request some modules */
1877 switch (dev->model) { 1884 switch (dev->model) {
1878 case EM2861_BOARD_PLEXTOR_PX_TV100U: 1885 case EM2861_BOARD_PLEXTOR_PX_TV100U:
1879 /* FIXME guess */ 1886 /* Sets the msp34xx I2S speed */
1880 /* Turn on analog audio output */ 1887 dev->i2s_speed = 2048000;
1881 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
1882 break; 1888 break;
1883 case EM2861_BOARD_KWORLD_PVRTV_300U: 1889 case EM2861_BOARD_KWORLD_PVRTV_300U:
1884 case EM2880_BOARD_KWORLD_DVB_305U: 1890 case EM2880_BOARD_KWORLD_DVB_305U:
@@ -2216,7 +2222,20 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2216 2222
2217void em28xx_card_setup(struct em28xx *dev) 2223void em28xx_card_setup(struct em28xx *dev)
2218{ 2224{
2219 em28xx_set_model(dev); 2225 /*
2226 * If the device can be a webcam, seek for a sensor.
2227 * If sensor is not found, then it isn't a webcam.
2228 */
2229 if (dev->board.is_webcam) {
2230 if (em28xx_hint_sensor(dev) < 0)
2231 dev->board.is_webcam = 0;
2232 else
2233 dev->progressive = 1;
2234 } else
2235 em28xx_set_model(dev);
2236
2237 em28xx_info("Identified as %s (card=%d)\n",
2238 dev->board.name, dev->model);
2220 2239
2221 dev->tuner_type = em28xx_boards[dev->model].tuner_type; 2240 dev->tuner_type = em28xx_boards[dev->model].tuner_type;
2222 if (em28xx_boards[dev->model].tuner_addr) 2241 if (em28xx_boards[dev->model].tuner_addr)
@@ -2290,10 +2309,6 @@ void em28xx_card_setup(struct em28xx *dev)
2290 em28xx_gpio_set(dev, dev->board.tuner_gpio); 2309 em28xx_gpio_set(dev, dev->board.tuner_gpio);
2291 em28xx_set_mode(dev, EM28XX_ANALOG_MODE); 2310 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
2292 break; 2311 break;
2293 case EM2820_BOARD_SILVERCREST_WEBCAM:
2294 /* FIXME: need to document the registers bellow */
2295 em28xx_write_reg(dev, 0x0d, 0x42);
2296 em28xx_write_reg(dev, 0x13, 0x08);
2297 } 2312 }
2298 2313
2299 if (dev->board.has_snapshot_button) 2314 if (dev->board.has_snapshot_button)
@@ -2367,7 +2382,9 @@ void em28xx_card_setup(struct em28xx *dev)
2367 } 2382 }
2368 2383
2369 em28xx_tuner_setup(dev); 2384 em28xx_tuner_setup(dev);
2370 em28xx_ir_init(dev); 2385
2386 if(!disable_ir)
2387 em28xx_ir_init(dev);
2371} 2388}
2372 2389
2373 2390
@@ -2433,7 +2450,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2433 int minor) 2450 int minor)
2434{ 2451{
2435 struct em28xx *dev = *devhandle; 2452 struct em28xx *dev = *devhandle;
2436 int retval = -ENOMEM; 2453 int retval;
2437 int errCode; 2454 int errCode;
2438 2455
2439 dev->udev = udev; 2456 dev->udev = udev;
@@ -2450,6 +2467,58 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2450 dev->em28xx_read_reg_req = em28xx_read_reg_req; 2467 dev->em28xx_read_reg_req = em28xx_read_reg_req;
2451 dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800; 2468 dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
2452 2469
2470 em28xx_set_model(dev);
2471
2472 /* Set the default GPO/GPIO for legacy devices */
2473 dev->reg_gpo_num = EM2880_R04_GPO;
2474 dev->reg_gpio_num = EM28XX_R08_GPIO;
2475
2476 dev->wait_after_write = 5;
2477
2478 /* Based on the Chip ID, set the device configuration */
2479 retval = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
2480 if (retval > 0) {
2481 dev->chip_id = retval;
2482
2483 switch (dev->chip_id) {
2484 case CHIP_ID_EM2710:
2485 em28xx_info("chip ID is em2710\n");
2486 break;
2487 case CHIP_ID_EM2750:
2488 em28xx_info("chip ID is em2750\n");
2489 break;
2490 case CHIP_ID_EM2820:
2491 em28xx_info("chip ID is em2820 (or em2710)\n");
2492 break;
2493 case CHIP_ID_EM2840:
2494 em28xx_info("chip ID is em2840\n");
2495 break;
2496 case CHIP_ID_EM2860:
2497 em28xx_info("chip ID is em2860\n");
2498 break;
2499 case CHIP_ID_EM2870:
2500 em28xx_info("chip ID is em2870\n");
2501 dev->wait_after_write = 0;
2502 break;
2503 case CHIP_ID_EM2874:
2504 em28xx_info("chip ID is em2874\n");
2505 dev->reg_gpio_num = EM2874_R80_GPIO;
2506 dev->wait_after_write = 0;
2507 break;
2508 case CHIP_ID_EM2883:
2509 em28xx_info("chip ID is em2882/em2883\n");
2510 dev->wait_after_write = 0;
2511 break;
2512 default:
2513 em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
2514 }
2515 }
2516
2517 /* Prepopulate cached GPO register content */
2518 retval = em28xx_read_reg(dev, dev->reg_gpo_num);
2519 if (retval >= 0)
2520 dev->reg_gpo = retval;
2521
2453 em28xx_pre_card_setup(dev); 2522 em28xx_pre_card_setup(dev);
2454 2523
2455 if (!dev->board.is_em2800) { 2524 if (!dev->board.is_em2800) {
@@ -2484,14 +2553,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2484 dev->vinmode = 0x10; 2553 dev->vinmode = 0x10;
2485 dev->vinctl = 0x11; 2554 dev->vinctl = 0x11;
2486 2555
2487 /*
2488 * If the device can be a webcam, seek for a sensor.
2489 * If sensor is not found, then it isn't a webcam.
2490 */
2491 if (dev->board.is_webcam)
2492 if (em28xx_hint_sensor(dev) < 0)
2493 dev->board.is_webcam = 0;
2494
2495 /* Do board specific init and eeprom reading */ 2556 /* Do board specific init and eeprom reading */
2496 em28xx_card_setup(dev); 2557 em28xx_card_setup(dev);
2497 2558
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 5b78e199abd1..98e140b5d95e 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -632,6 +632,9 @@ int em28xx_capture_start(struct em28xx *dev, int start)
632 return rc; 632 return rc;
633 } 633 }
634 634
635 if (dev->board.is_webcam)
636 rc = em28xx_write_reg(dev, 0x13, 0x0c);
637
635 /* enable video capture */ 638 /* enable video capture */
636 rc = em28xx_write_reg(dev, 0x48, 0x00); 639 rc = em28xx_write_reg(dev, 0x48, 0x00);
637 640
@@ -720,7 +723,10 @@ int em28xx_resolution_set(struct em28xx *dev)
720{ 723{
721 int width, height; 724 int width, height;
722 width = norm_maxw(dev); 725 width = norm_maxw(dev);
723 height = norm_maxh(dev) >> 1; 726 height = norm_maxh(dev);
727
728 if (!dev->progressive)
729 height >>= norm_maxh(dev);
724 730
725 em28xx_set_outfmt(dev); 731 em28xx_set_outfmt(dev);
726 732
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index cf0ac7f2a30d..d603575431b4 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -478,7 +478,6 @@ static int dvb_init(struct em28xx *dev)
478 } 478 }
479 break; 479 break;
480 case EM2880_BOARD_KWORLD_DVB_310U: 480 case EM2880_BOARD_KWORLD_DVB_310U:
481 case EM2880_BOARD_EMPIRE_DUAL_TV:
482 dvb->frontend = dvb_attach(zl10353_attach, 481 dvb->frontend = dvb_attach(zl10353_attach,
483 &em28xx_zl10353_with_xc3028, 482 &em28xx_zl10353_with_xc3028,
484 &dev->i2c_adap); 483 &dev->i2c_adap);
@@ -488,6 +487,7 @@ static int dvb_init(struct em28xx *dev)
488 } 487 }
489 break; 488 break;
490 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 489 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
490 case EM2880_BOARD_EMPIRE_DUAL_TV:
491 dvb->frontend = dvb_attach(zl10353_attach, 491 dvb->frontend = dvb_attach(zl10353_attach,
492 &em28xx_zl10353_xc3028_no_i2c_gate, 492 &em28xx_zl10353_xc3028_no_i2c_gate,
493 &dev->i2c_adap); 493 &dev->i2c_adap);
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index a2676d63cfd0..6bf84bd787df 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -176,7 +176,8 @@
176 176
177/* FIXME: Need to be populated with the other chip ID's */ 177/* FIXME: Need to be populated with the other chip ID's */
178enum em28xx_chip_id { 178enum em28xx_chip_id {
179 CHIP_ID_EM2820 = 18, /* Also used by em2710 */ 179 CHIP_ID_EM2710 = 17,
180 CHIP_ID_EM2820 = 18, /* Also used by some em2710 */
180 CHIP_ID_EM2840 = 20, 181 CHIP_ID_EM2840 = 20,
181 CHIP_ID_EM2750 = 33, 182 CHIP_ID_EM2750 = 33,
182 CHIP_ID_EM2860 = 34, 183 CHIP_ID_EM2860 = 34,
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index ff37b4c15f44..ab079d9256c4 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -194,15 +194,24 @@ static void em28xx_copy_video(struct em28xx *dev,
194 startread = p; 194 startread = p;
195 remain = len; 195 remain = len;
196 196
197 /* Interlaces frame */ 197 if (dev->progressive)
198 if (buf->top_field)
199 fieldstart = outp; 198 fieldstart = outp;
200 else 199 else {
201 fieldstart = outp + bytesperline; 200 /* Interlaces two half frames */
201 if (buf->top_field)
202 fieldstart = outp;
203 else
204 fieldstart = outp + bytesperline;
205 }
202 206
203 linesdone = dma_q->pos / bytesperline; 207 linesdone = dma_q->pos / bytesperline;
204 currlinedone = dma_q->pos % bytesperline; 208 currlinedone = dma_q->pos % bytesperline;
205 offset = linesdone * bytesperline * 2 + currlinedone; 209
210 if (dev->progressive)
211 offset = linesdone * bytesperline + currlinedone;
212 else
213 offset = linesdone * bytesperline * 2 + currlinedone;
214
206 startwrite = fieldstart + offset; 215 startwrite = fieldstart + offset;
207 lencopy = bytesperline - currlinedone; 216 lencopy = bytesperline - currlinedone;
208 lencopy = lencopy > remain ? remain : lencopy; 217 lencopy = lencopy > remain ? remain : lencopy;
@@ -376,7 +385,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
376 em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2], 385 em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
377 len, (p[2] & 1) ? "odd" : "even"); 386 len, (p[2] & 1) ? "odd" : "even");
378 387
379 if (!(p[2] & 1)) { 388 if (dev->progressive || !(p[2] & 1)) {
380 if (buf != NULL) 389 if (buf != NULL)
381 buffer_filled(dev, dma_q, buf); 390 buffer_filled(dev, dma_q, buf);
382 get_next_buf(dma_q, &buf); 391 get_next_buf(dma_q, &buf);
@@ -689,7 +698,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
689 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 698 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
690 699
691 /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ 700 /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
692 f->fmt.pix.field = dev->interlaced ? 701 if (dev->progressive)
702 f->fmt.pix.field = V4L2_FIELD_NONE;
703 else
704 f->fmt.pix.field = dev->interlaced ?
693 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; 705 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
694 706
695 mutex_unlock(&dev->lock); 707 mutex_unlock(&dev->lock);
@@ -753,7 +765,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
753 f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3; 765 f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
754 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; 766 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
755 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 767 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
756 f->fmt.pix.field = V4L2_FIELD_INTERLACED; 768 if (dev->progressive)
769 f->fmt.pix.field = V4L2_FIELD_NONE;
770 else
771 f->fmt.pix.field = dev->interlaced ?
772 V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
757 773
758 return 0; 774 return 0;
759} 775}
@@ -846,6 +862,41 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
846 return 0; 862 return 0;
847} 863}
848 864
865static int vidioc_g_parm(struct file *file, void *priv,
866 struct v4l2_streamparm *p)
867{
868 struct em28xx_fh *fh = priv;
869 struct em28xx *dev = fh->dev;
870 int rc = 0;
871
872 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
873 return -EINVAL;
874
875 if (dev->board.is_webcam)
876 rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0,
877 video, g_parm, p);
878 else
879 v4l2_video_std_frame_period(dev->norm,
880 &p->parm.capture.timeperframe);
881
882 return rc;
883}
884
885static int vidioc_s_parm(struct file *file, void *priv,
886 struct v4l2_streamparm *p)
887{
888 struct em28xx_fh *fh = priv;
889 struct em28xx *dev = fh->dev;
890
891 if (!dev->board.is_webcam)
892 return -EINVAL;
893
894 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
895 return -EINVAL;
896
897 return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p);
898}
899
849static const char *iname[] = { 900static const char *iname[] = {
850 [EM28XX_VMUX_COMPOSITE1] = "Composite1", 901 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
851 [EM28XX_VMUX_COMPOSITE2] = "Composite2", 902 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
@@ -1624,6 +1675,7 @@ static int em28xx_v4l2_open(struct file *filp)
1624 struct em28xx *dev; 1675 struct em28xx *dev;
1625 enum v4l2_buf_type fh_type; 1676 enum v4l2_buf_type fh_type;
1626 struct em28xx_fh *fh; 1677 struct em28xx_fh *fh;
1678 enum v4l2_field field;
1627 1679
1628 dev = em28xx_get_device(minor, &fh_type, &radio); 1680 dev = em28xx_get_device(minor, &fh_type, &radio);
1629 1681
@@ -1665,8 +1717,13 @@ static int em28xx_v4l2_open(struct file *filp)
1665 1717
1666 dev->users++; 1718 dev->users++;
1667 1719
1720 if (dev->progressive)
1721 field = V4L2_FIELD_NONE;
1722 else
1723 field = V4L2_FIELD_INTERLACED;
1724
1668 videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, 1725 videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops,
1669 NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, 1726 NULL, &dev->slock, fh->type, field,
1670 sizeof(struct em28xx_buffer), fh); 1727 sizeof(struct em28xx_buffer), fh);
1671 1728
1672 mutex_unlock(&dev->lock); 1729 mutex_unlock(&dev->lock);
@@ -1885,6 +1942,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1885 .vidioc_qbuf = vidioc_qbuf, 1942 .vidioc_qbuf = vidioc_qbuf,
1886 .vidioc_dqbuf = vidioc_dqbuf, 1943 .vidioc_dqbuf = vidioc_dqbuf,
1887 .vidioc_s_std = vidioc_s_std, 1944 .vidioc_s_std = vidioc_s_std,
1945 .vidioc_g_parm = vidioc_g_parm,
1946 .vidioc_s_parm = vidioc_s_parm,
1888 .vidioc_enum_input = vidioc_enum_input, 1947 .vidioc_enum_input = vidioc_enum_input,
1889 .vidioc_g_input = vidioc_g_input, 1948 .vidioc_g_input = vidioc_g_input,
1890 .vidioc_s_input = vidioc_s_input, 1949 .vidioc_s_input = vidioc_s_input,
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 45bd513f62dc..a2add61f7d59 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -367,6 +367,7 @@ enum em28xx_sensor {
367 EM28XX_NOSENSOR = 0, 367 EM28XX_NOSENSOR = 0,
368 EM28XX_MT9V011, 368 EM28XX_MT9V011,
369 EM28XX_MT9M001, 369 EM28XX_MT9M001,
370 EM28XX_MT9M111,
370}; 371};
371 372
372enum em28xx_adecoder { 373enum em28xx_adecoder {
@@ -484,6 +485,9 @@ struct em28xx {
484 int sensor_xres, sensor_yres; 485 int sensor_xres, sensor_yres;
485 int sensor_xtal; 486 int sensor_xtal;
486 487
488 /* Allows progressive (e. g. non-interlaced) mode */
489 int progressive;
490
487 /* Vinmode/Vinctl used at the driver */ 491 /* Vinmode/Vinctl used at the driver */
488 int vinmode, vinctl; 492 int vinmode, vinctl;
489 493