aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-cards.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-cards.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c287
1 files changed, 195 insertions, 92 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index ebd24a25fb85..ed281f565945 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -58,8 +58,6 @@ static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
58module_param_array(card, int, NULL, 0444); 58module_param_array(card, int, NULL, 0444);
59MODULE_PARM_DESC(card, "card type"); 59MODULE_PARM_DESC(card, "card type");
60 60
61#define MT9V011_VERSION 0x8243
62
63/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ 61/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
64static unsigned long em28xx_devused; 62static unsigned long em28xx_devused;
65 63
@@ -159,6 +157,20 @@ static struct em28xx_reg_seq evga_indtube_digital[] = {
159 { -1, -1, -1, -1}, 157 { -1, -1, -1, -1},
160}; 158};
161 159
160/* Pinnacle Hybrid Pro eb1a:2881 */
161static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
162 {EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10},
163 { -1, -1, -1, -1},
164};
165
166static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
167 {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
168 {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */
169 {EM2880_R04_GPO, 0x0c, 0xff, 1},
170 { -1, -1, -1, -1},
171};
172
173
162/* Callback for the most boards */ 174/* Callback for the most boards */
163static struct em28xx_reg_seq default_tuner_gpio[] = { 175static struct em28xx_reg_seq default_tuner_gpio[] = {
164 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, 176 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
@@ -205,13 +217,15 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = {
205 */ 217 */
206struct em28xx_board em28xx_boards[] = { 218struct em28xx_board em28xx_boards[] = {
207 [EM2750_BOARD_UNKNOWN] = { 219 [EM2750_BOARD_UNKNOWN] = {
208 .name = "Unknown EM2750/EM2751 webcam grabber", 220 .name = "EM2710/EM2750/EM2751 webcam grabber",
209 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, 221 .xclk = EM28XX_XCLK_FREQUENCY_20MHZ,
210 .tuner_type = TUNER_ABSENT, /* This is a webcam */ 222 .tuner_type = TUNER_ABSENT,
223 .is_webcam = 1,
211 .input = { { 224 .input = { {
212 .type = EM28XX_VMUX_COMPOSITE1, 225 .type = EM28XX_VMUX_COMPOSITE1,
213 .vmux = 0, 226 .vmux = 0,
214 .amux = EM28XX_AMUX_VIDEO, 227 .amux = EM28XX_AMUX_VIDEO,
228 .gpio = silvercrest_reg_seq,
215 } }, 229 } },
216 }, 230 },
217 [EM2800_BOARD_UNKNOWN] = { 231 [EM2800_BOARD_UNKNOWN] = {
@@ -233,13 +247,15 @@ struct em28xx_board em28xx_boards[] = {
233 [EM2820_BOARD_UNKNOWN] = { 247 [EM2820_BOARD_UNKNOWN] = {
234 .name = "Unknown EM2750/28xx video grabber", 248 .name = "Unknown EM2750/28xx video grabber",
235 .tuner_type = TUNER_ABSENT, 249 .tuner_type = TUNER_ABSENT,
250 .is_webcam = 1, /* To enable sensor probe */
236 }, 251 },
237 [EM2750_BOARD_DLCW_130] = { 252 [EM2750_BOARD_DLCW_130] = {
238 /* Beijing Huaqi Information Digital Technology Co., Ltd */ 253 /* Beijing Huaqi Information Digital Technology Co., Ltd */
239 .name = "Huaqi DLCW-130", 254 .name = "Huaqi DLCW-130",
240 .valid = EM28XX_BOARD_NOT_VALIDATED, 255 .valid = EM28XX_BOARD_NOT_VALIDATED,
241 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, 256 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ,
242 .tuner_type = TUNER_ABSENT, /* This is a webcam */ 257 .tuner_type = TUNER_ABSENT,
258 .is_webcam = 1,
243 .input = { { 259 .input = { {
244 .type = EM28XX_VMUX_COMPOSITE1, 260 .type = EM28XX_VMUX_COMPOSITE1,
245 .vmux = 0, 261 .vmux = 0,
@@ -440,7 +456,8 @@ struct em28xx_board em28xx_boards[] = {
440 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { 456 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = {
441 .name = "Videology 20K14XUSB USB2.0", 457 .name = "Videology 20K14XUSB USB2.0",
442 .valid = EM28XX_BOARD_NOT_VALIDATED, 458 .valid = EM28XX_BOARD_NOT_VALIDATED,
443 .tuner_type = TUNER_ABSENT, /* This is a webcam */ 459 .tuner_type = TUNER_ABSENT,
460 .is_webcam = 1,
444 .input = { { 461 .input = { {
445 .type = EM28XX_VMUX_COMPOSITE1, 462 .type = EM28XX_VMUX_COMPOSITE1,
446 .vmux = 0, 463 .vmux = 0,
@@ -450,8 +467,7 @@ struct em28xx_board em28xx_boards[] = {
450 [EM2820_BOARD_SILVERCREST_WEBCAM] = { 467 [EM2820_BOARD_SILVERCREST_WEBCAM] = {
451 .name = "Silvercrest Webcam 1.3mpix", 468 .name = "Silvercrest Webcam 1.3mpix",
452 .tuner_type = TUNER_ABSENT, 469 .tuner_type = TUNER_ABSENT,
453 .is_27xx = 1, 470 .is_webcam = 1,
454 .decoder = EM28XX_MT9V011,
455 .input = { { 471 .input = { {
456 .type = EM28XX_VMUX_COMPOSITE1, 472 .type = EM28XX_VMUX_COMPOSITE1,
457 .vmux = 0, 473 .vmux = 0,
@@ -500,7 +516,8 @@ struct em28xx_board em28xx_boards[] = {
500 /* Beijing Huaqi Information Digital Technology Co., Ltd */ 516 /* Beijing Huaqi Information Digital Technology Co., Ltd */
501 .name = "NetGMBH Cam", 517 .name = "NetGMBH Cam",
502 .valid = EM28XX_BOARD_NOT_VALIDATED, 518 .valid = EM28XX_BOARD_NOT_VALIDATED,
503 .tuner_type = TUNER_ABSENT, /* This is a webcam */ 519 .tuner_type = TUNER_ABSENT,
520 .is_webcam = 1,
504 .input = { { 521 .input = { {
505 .type = EM28XX_VMUX_COMPOSITE1, 522 .type = EM28XX_VMUX_COMPOSITE1,
506 .vmux = 0, 523 .vmux = 0,
@@ -605,22 +622,27 @@ struct em28xx_board em28xx_boards[] = {
605 }, 622 },
606 [EM2861_BOARD_PLEXTOR_PX_TV100U] = { 623 [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
607 .name = "Plextor ConvertX PX-TV100U", 624 .name = "Plextor ConvertX PX-TV100U",
608 .valid = EM28XX_BOARD_NOT_VALIDATED,
609 .tuner_type = TUNER_TNF_5335MF, 625 .tuner_type = TUNER_TNF_5335MF,
626 .xclk = EM28XX_XCLK_I2S_MSB_TIMING |
627 EM28XX_XCLK_FREQUENCY_12MHZ,
610 .tda9887_conf = TDA9887_PRESENT, 628 .tda9887_conf = TDA9887_PRESENT,
611 .decoder = EM28XX_TVP5150, 629 .decoder = EM28XX_TVP5150,
630 .has_msp34xx = 1,
612 .input = { { 631 .input = { {
613 .type = EM28XX_VMUX_TELEVISION, 632 .type = EM28XX_VMUX_TELEVISION,
614 .vmux = TVP5150_COMPOSITE0, 633 .vmux = TVP5150_COMPOSITE0,
615 .amux = EM28XX_AMUX_LINE_IN, 634 .amux = EM28XX_AMUX_LINE_IN,
635 .gpio = pinnacle_hybrid_pro_analog,
616 }, { 636 }, {
617 .type = EM28XX_VMUX_COMPOSITE1, 637 .type = EM28XX_VMUX_COMPOSITE1,
618 .vmux = TVP5150_COMPOSITE1, 638 .vmux = TVP5150_COMPOSITE1,
619 .amux = EM28XX_AMUX_LINE_IN, 639 .amux = EM28XX_AMUX_LINE_IN,
640 .gpio = pinnacle_hybrid_pro_analog,
620 }, { 641 }, {
621 .type = EM28XX_VMUX_SVIDEO, 642 .type = EM28XX_VMUX_SVIDEO,
622 .vmux = TVP5150_SVIDEO, 643 .vmux = TVP5150_SVIDEO,
623 .amux = EM28XX_AMUX_LINE_IN, 644 .amux = EM28XX_AMUX_LINE_IN,
645 .gpio = pinnacle_hybrid_pro_analog,
624 } }, 646 } },
625 }, 647 },
626 648
@@ -1250,25 +1272,26 @@ struct em28xx_board em28xx_boards[] = {
1250 }, 1272 },
1251 [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { 1273 [EM2881_BOARD_PINNACLE_HYBRID_PRO] = {
1252 .name = "Pinnacle Hybrid Pro", 1274 .name = "Pinnacle Hybrid Pro",
1253 .valid = EM28XX_BOARD_NOT_VALIDATED,
1254 .tuner_type = TUNER_XC2028, 1275 .tuner_type = TUNER_XC2028,
1255 .tuner_gpio = default_tuner_gpio, 1276 .tuner_gpio = default_tuner_gpio,
1256 .decoder = EM28XX_TVP5150, 1277 .decoder = EM28XX_TVP5150,
1278 .has_dvb = 1,
1279 .dvb_gpio = pinnacle_hybrid_pro_digital,
1257 .input = { { 1280 .input = { {
1258 .type = EM28XX_VMUX_TELEVISION, 1281 .type = EM28XX_VMUX_TELEVISION,
1259 .vmux = TVP5150_COMPOSITE0, 1282 .vmux = TVP5150_COMPOSITE0,
1260 .amux = EM28XX_AMUX_VIDEO, 1283 .amux = EM28XX_AMUX_VIDEO,
1261 .gpio = default_analog, 1284 .gpio = pinnacle_hybrid_pro_analog,
1262 }, { 1285 }, {
1263 .type = EM28XX_VMUX_COMPOSITE1, 1286 .type = EM28XX_VMUX_COMPOSITE1,
1264 .vmux = TVP5150_COMPOSITE1, 1287 .vmux = TVP5150_COMPOSITE1,
1265 .amux = EM28XX_AMUX_LINE_IN, 1288 .amux = EM28XX_AMUX_LINE_IN,
1266 .gpio = default_analog, 1289 .gpio = pinnacle_hybrid_pro_analog,
1267 }, { 1290 }, {
1268 .type = EM28XX_VMUX_SVIDEO, 1291 .type = EM28XX_VMUX_SVIDEO,
1269 .vmux = TVP5150_SVIDEO, 1292 .vmux = TVP5150_SVIDEO,
1270 .amux = EM28XX_AMUX_LINE_IN, 1293 .amux = EM28XX_AMUX_LINE_IN,
1271 .gpio = default_analog, 1294 .gpio = pinnacle_hybrid_pro_analog,
1272 } }, 1295 } },
1273 }, 1296 },
1274 [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { 1297 [EM2882_BOARD_PINNACLE_HYBRID_PRO] = {
@@ -1526,6 +1549,8 @@ struct usb_device_id em28xx_id_table[] = {
1526 .driver_info = EM2750_BOARD_UNKNOWN }, 1549 .driver_info = EM2750_BOARD_UNKNOWN },
1527 { USB_DEVICE(0xeb1a, 0x2800), 1550 { USB_DEVICE(0xeb1a, 0x2800),
1528 .driver_info = EM2800_BOARD_UNKNOWN }, 1551 .driver_info = EM2800_BOARD_UNKNOWN },
1552 { USB_DEVICE(0xeb1a, 0x2710),
1553 .driver_info = EM2820_BOARD_UNKNOWN },
1529 { USB_DEVICE(0xeb1a, 0x2820), 1554 { USB_DEVICE(0xeb1a, 0x2820),
1530 .driver_info = EM2820_BOARD_UNKNOWN }, 1555 .driver_info = EM2820_BOARD_UNKNOWN },
1531 { USB_DEVICE(0xeb1a, 0x2821), 1556 { USB_DEVICE(0xeb1a, 0x2821),
@@ -1638,6 +1663,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
1638 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, 1663 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
1639 {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, 1664 {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
1640 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, 1665 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
1666 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
1641}; 1667};
1642 1668
1643/* I2C devicelist hash table for devices with generic USB IDs */ 1669/* I2C devicelist hash table for devices with generic USB IDs */
@@ -1704,6 +1730,32 @@ static inline void em28xx_set_model(struct em28xx *dev)
1704 EM28XX_I2C_FREQ_100_KHZ; 1730 EM28XX_I2C_FREQ_100_KHZ;
1705} 1731}
1706 1732
1733/* FIXME: Should be replaced by a proper mt9m001 driver */
1734static int em28xx_initialize_mt9m001(struct em28xx *dev)
1735{
1736 int i;
1737 unsigned char regs[][3] = {
1738 { 0x0d, 0x00, 0x01, },
1739 { 0x0d, 0x00, 0x00, },
1740 { 0x04, 0x05, 0x00, }, /* hres = 1280 */
1741 { 0x03, 0x04, 0x00, }, /* vres = 1024 */
1742 { 0x20, 0x11, 0x00, },
1743 { 0x06, 0x00, 0x10, },
1744 { 0x2b, 0x00, 0x24, },
1745 { 0x2e, 0x00, 0x24, },
1746 { 0x35, 0x00, 0x24, },
1747 { 0x2d, 0x00, 0x20, },
1748 { 0x2c, 0x00, 0x20, },
1749 { 0x09, 0x0a, 0xd4, },
1750 { 0x35, 0x00, 0x57, },
1751 };
1752
1753 for (i = 0; i < ARRAY_SIZE(regs); i++)
1754 i2c_master_send(&dev->i2c_client, &regs[i][0], 3);
1755
1756 return 0;
1757}
1758
1707/* HINT method: webcam I2C chips 1759/* HINT method: webcam I2C chips
1708 * 1760 *
1709 * This method work for webcams with Micron sensors 1761 * This method work for webcams with Micron sensors
@@ -1716,9 +1768,7 @@ static int em28xx_hint_sensor(struct em28xx *dev)
1716 __be16 version_be; 1768 __be16 version_be;
1717 u16 version; 1769 u16 version;
1718 1770
1719 if (dev->model != EM2820_BOARD_UNKNOWN) 1771 /* Micron sensor detection */
1720 return 0;
1721
1722 dev->i2c_client.addr = 0xba >> 1; 1772 dev->i2c_client.addr = 0xba >> 1;
1723 cmd = 0; 1773 cmd = 0;
1724 i2c_master_send(&dev->i2c_client, &cmd, 1); 1774 i2c_master_send(&dev->i2c_client, &cmd, 1);
@@ -1727,18 +1777,57 @@ static int em28xx_hint_sensor(struct em28xx *dev)
1727 return -EINVAL; 1777 return -EINVAL;
1728 1778
1729 version = be16_to_cpu(version_be); 1779 version = be16_to_cpu(version_be);
1730
1731 switch (version) { 1780 switch (version) {
1732 case MT9V011_VERSION: 1781 case 0x8232: /* mt9v011 640x480 1.3 Mpix sensor */
1782 case 0x8243: /* mt9v011 rev B 640x480 1.3 Mpix sensor */
1733 dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; 1783 dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
1784 em28xx_set_model(dev);
1785
1734 sensor_name = "mt9v011"; 1786 sensor_name = "mt9v011";
1787 dev->em28xx_sensor = EM28XX_MT9V011;
1788 dev->sensor_xres = 640;
1789 dev->sensor_yres = 480;
1790 /*
1791 * FIXME: mt9v011 uses I2S speed as xtal clk - at least with
1792 * the Silvercrest cam I have here for testing - for higher
1793 * resolutions, a high clock cause horizontal artifacts, so we
1794 * need to use a lower xclk frequency.
1795 * Yet, it would be possible to adjust xclk depending on the
1796 * desired resolution, since this affects directly the
1797 * frame rate.
1798 */
1799 dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ;
1800 dev->sensor_xtal = 4300000;
1801
1802 /* probably means GRGB 16 bit bayer */
1803 dev->vinmode = 0x0d;
1804 dev->vinctl = 0x00;
1805
1806 break;
1807 case 0x8431:
1808 dev->model = EM2750_BOARD_UNKNOWN;
1809 em28xx_set_model(dev);
1810
1811 sensor_name = "mt9m001";
1812 dev->em28xx_sensor = EM28XX_MT9M001;
1813 em28xx_initialize_mt9m001(dev);
1814 dev->sensor_xres = 1280;
1815 dev->sensor_yres = 1024;
1816
1817 /* probably means BGGR 16 bit bayer */
1818 dev->vinmode = 0x0c;
1819 dev->vinctl = 0x00;
1820
1735 break; 1821 break;
1736 default: 1822 default:
1737 printk("Unknown Sensor 0x%04x\n", be16_to_cpu(version)); 1823 printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version));
1738 return -EINVAL; 1824 return -EINVAL;
1739 } 1825 }
1740 1826
1741 em28xx_errdev("Sensor is %s, assuming that webcam is %s\n", 1827 /* Setup webcam defaults */
1828 em28xx_pre_card_setup(dev);
1829
1830 em28xx_errdev("Sensor is %s, using model %s entry.\n",
1742 sensor_name, em28xx_boards[dev->model].name); 1831 sensor_name, em28xx_boards[dev->model].name);
1743 1832
1744 return 0; 1833 return 0;
@@ -1749,63 +1838,6 @@ static int em28xx_hint_sensor(struct em28xx *dev)
1749 */ 1838 */
1750void em28xx_pre_card_setup(struct em28xx *dev) 1839void em28xx_pre_card_setup(struct em28xx *dev)
1751{ 1840{
1752 int rc;
1753
1754 em28xx_set_model(dev);
1755
1756 em28xx_info("Identified as %s (card=%d)\n",
1757 dev->board.name, dev->model);
1758
1759 /* Set the default GPO/GPIO for legacy devices */
1760 dev->reg_gpo_num = EM2880_R04_GPO;
1761 dev->reg_gpio_num = EM28XX_R08_GPIO;
1762
1763 dev->wait_after_write = 5;
1764
1765 /* Based on the Chip ID, set the device configuration */
1766 rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
1767 if (rc > 0) {
1768 dev->chip_id = rc;
1769
1770 switch (dev->chip_id) {
1771 case CHIP_ID_EM2750:
1772 em28xx_info("chip ID is em2750\n");
1773 break;
1774 case CHIP_ID_EM2820:
1775 if (dev->board.is_27xx)
1776 em28xx_info("chip is em2710\n");
1777 else
1778 em28xx_info("chip ID is em2820\n");
1779 break;
1780 case CHIP_ID_EM2840:
1781 em28xx_info("chip ID is em2840\n");
1782 break;
1783 case CHIP_ID_EM2860:
1784 em28xx_info("chip ID is em2860\n");
1785 break;
1786 case CHIP_ID_EM2870:
1787 em28xx_info("chip ID is em2870\n");
1788 dev->wait_after_write = 0;
1789 break;
1790 case CHIP_ID_EM2874:
1791 em28xx_info("chip ID is em2874\n");
1792 dev->reg_gpio_num = EM2874_R80_GPIO;
1793 dev->wait_after_write = 0;
1794 break;
1795 case CHIP_ID_EM2883:
1796 em28xx_info("chip ID is em2882/em2883\n");
1797 dev->wait_after_write = 0;
1798 break;
1799 default:
1800 em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
1801 }
1802 }
1803
1804 /* Prepopulate cached GPO register content */
1805 rc = em28xx_read_reg(dev, dev->reg_gpo_num);
1806 if (rc >= 0)
1807 dev->reg_gpo = rc;
1808
1809 /* Set the initial XCLK and I2C clock values based on the board 1841 /* Set the initial XCLK and I2C clock values based on the board
1810 definition */ 1842 definition */
1811 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f); 1843 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f);
@@ -1815,9 +1847,8 @@ void em28xx_pre_card_setup(struct em28xx *dev)
1815 /* request some modules */ 1847 /* request some modules */
1816 switch (dev->model) { 1848 switch (dev->model) {
1817 case EM2861_BOARD_PLEXTOR_PX_TV100U: 1849 case EM2861_BOARD_PLEXTOR_PX_TV100U:
1818 /* FIXME guess */ 1850 /* Sets the msp34xx I2S speed */
1819 /* Turn on analog audio output */ 1851 dev->i2s_speed = 2048000;
1820 em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
1821 break; 1852 break;
1822 case EM2861_BOARD_KWORLD_PVRTV_300U: 1853 case EM2861_BOARD_KWORLD_PVRTV_300U:
1823 case EM2880_BOARD_KWORLD_DVB_305U: 1854 case EM2880_BOARD_KWORLD_DVB_305U:
@@ -1929,6 +1960,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
1929 ctl->demod = XC3028_FE_ZARLINK456; 1960 ctl->demod = XC3028_FE_ZARLINK456;
1930 break; 1961 break;
1931 case EM2880_BOARD_TERRATEC_HYBRID_XS: 1962 case EM2880_BOARD_TERRATEC_HYBRID_XS:
1963 case EM2881_BOARD_PINNACLE_HYBRID_PRO:
1932 ctl->demod = XC3028_FE_ZARLINK456; 1964 ctl->demod = XC3028_FE_ZARLINK456;
1933 break; 1965 break;
1934 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: 1966 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
@@ -2154,7 +2186,20 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2154 2186
2155void em28xx_card_setup(struct em28xx *dev) 2187void em28xx_card_setup(struct em28xx *dev)
2156{ 2188{
2157 em28xx_set_model(dev); 2189 /*
2190 * If the device can be a webcam, seek for a sensor.
2191 * If sensor is not found, then it isn't a webcam.
2192 */
2193 if (dev->board.is_webcam) {
2194 if (em28xx_hint_sensor(dev) < 0)
2195 dev->board.is_webcam = 0;
2196 else
2197 dev->progressive = 1;
2198 } else
2199 em28xx_set_model(dev);
2200
2201 em28xx_info("Identified as %s (card=%d)\n",
2202 dev->board.name, dev->model);
2158 2203
2159 dev->tuner_type = em28xx_boards[dev->model].tuner_type; 2204 dev->tuner_type = em28xx_boards[dev->model].tuner_type;
2160 if (em28xx_boards[dev->model].tuner_addr) 2205 if (em28xx_boards[dev->model].tuner_addr)
@@ -2225,12 +2270,9 @@ void em28xx_card_setup(struct em28xx *dev)
2225 em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, 2270 em28xx_set_mode() in em28xx_pre_card_setup() was a no-op,
2226 so make the call now so the analog GPIOs are set properly 2271 so make the call now so the analog GPIOs are set properly
2227 before probing the i2c bus. */ 2272 before probing the i2c bus. */
2273 em28xx_gpio_set(dev, dev->board.tuner_gpio);
2228 em28xx_set_mode(dev, EM28XX_ANALOG_MODE); 2274 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
2229 break; 2275 break;
2230 case EM2820_BOARD_SILVERCREST_WEBCAM:
2231 /* FIXME: need to document the registers bellow */
2232 em28xx_write_reg(dev, 0x0d, 0x42);
2233 em28xx_write_reg(dev, 0x13, 0x08);
2234 } 2276 }
2235 2277
2236 if (dev->board.has_snapshot_button) 2278 if (dev->board.has_snapshot_button)
@@ -2262,9 +2304,14 @@ void em28xx_card_setup(struct em28xx *dev)
2262 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2304 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2263 "tvp5150", "tvp5150", tvp5150_addrs); 2305 "tvp5150", "tvp5150", tvp5150_addrs);
2264 2306
2265 if (dev->board.decoder == EM28XX_MT9V011) 2307 if (dev->em28xx_sensor == EM28XX_MT9V011) {
2266 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2308 struct v4l2_subdev *sd;
2267 "mt9v011", "mt9v011", mt9v011_addrs); 2309
2310 sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
2311 &dev->i2c_adap, "mt9v011", "mt9v011", mt9v011_addrs);
2312 v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
2313 }
2314
2268 2315
2269 if (dev->board.adecoder == EM28XX_TVAUDIO) 2316 if (dev->board.adecoder == EM28XX_TVAUDIO)
2270 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2317 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
@@ -2365,7 +2412,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2365 int minor) 2412 int minor)
2366{ 2413{
2367 struct em28xx *dev = *devhandle; 2414 struct em28xx *dev = *devhandle;
2368 int retval = -ENOMEM; 2415 int retval;
2369 int errCode; 2416 int errCode;
2370 2417
2371 dev->udev = udev; 2418 dev->udev = udev;
@@ -2382,6 +2429,58 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2382 dev->em28xx_read_reg_req = em28xx_read_reg_req; 2429 dev->em28xx_read_reg_req = em28xx_read_reg_req;
2383 dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800; 2430 dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
2384 2431
2432 em28xx_set_model(dev);
2433
2434 /* Set the default GPO/GPIO for legacy devices */
2435 dev->reg_gpo_num = EM2880_R04_GPO;
2436 dev->reg_gpio_num = EM28XX_R08_GPIO;
2437
2438 dev->wait_after_write = 5;
2439
2440 /* Based on the Chip ID, set the device configuration */
2441 retval = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
2442 if (retval > 0) {
2443 dev->chip_id = retval;
2444
2445 switch (dev->chip_id) {
2446 case CHIP_ID_EM2710:
2447 em28xx_info("chip ID is em2710\n");
2448 break;
2449 case CHIP_ID_EM2750:
2450 em28xx_info("chip ID is em2750\n");
2451 break;
2452 case CHIP_ID_EM2820:
2453 em28xx_info("chip ID is em2820 (or em2710)\n");
2454 break;
2455 case CHIP_ID_EM2840:
2456 em28xx_info("chip ID is em2840\n");
2457 break;
2458 case CHIP_ID_EM2860:
2459 em28xx_info("chip ID is em2860\n");
2460 break;
2461 case CHIP_ID_EM2870:
2462 em28xx_info("chip ID is em2870\n");
2463 dev->wait_after_write = 0;
2464 break;
2465 case CHIP_ID_EM2874:
2466 em28xx_info("chip ID is em2874\n");
2467 dev->reg_gpio_num = EM2874_R80_GPIO;
2468 dev->wait_after_write = 0;
2469 break;
2470 case CHIP_ID_EM2883:
2471 em28xx_info("chip ID is em2882/em2883\n");
2472 dev->wait_after_write = 0;
2473 break;
2474 default:
2475 em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
2476 }
2477 }
2478
2479 /* Prepopulate cached GPO register content */
2480 retval = em28xx_read_reg(dev, dev->reg_gpo_num);
2481 if (retval >= 0)
2482 dev->reg_gpo = retval;
2483
2385 em28xx_pre_card_setup(dev); 2484 em28xx_pre_card_setup(dev);
2386 2485
2387 if (!dev->board.is_em2800) { 2486 if (!dev->board.is_em2800) {
@@ -2410,7 +2509,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2410 return errCode; 2509 return errCode;
2411 } 2510 }
2412 2511
2413 em28xx_hint_sensor(dev); 2512 /*
2513 * Default format, used for tvp5150 or saa711x output formats
2514 */
2515 dev->vinmode = 0x10;
2516 dev->vinctl = 0x11;
2414 2517
2415 /* Do board specific init and eeprom reading */ 2518 /* Do board specific init and eeprom reading */
2416 em28xx_card_setup(dev); 2519 em28xx_card_setup(dev);