diff options
| -rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 6b2b5d3e2fad..54429b629b2d 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[] = { | |||
| 218 | struct em28xx_board em28xx_boards[] = { | 218 | struct 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 = { { |
| @@ -1768,6 +1768,7 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
| 1768 | __be16 version_be; | 1768 | __be16 version_be; |
| 1769 | u16 version; | 1769 | u16 version; |
| 1770 | 1770 | ||
| 1771 | /* Micron sensor detection */ | ||
| 1771 | dev->i2c_client.addr = 0xba >> 1; | 1772 | dev->i2c_client.addr = 0xba >> 1; |
| 1772 | cmd = 0; | 1773 | cmd = 0; |
| 1773 | i2c_master_send(&dev->i2c_client, &cmd, 1); | 1774 | i2c_master_send(&dev->i2c_client, &cmd, 1); |
| @@ -1776,16 +1777,27 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
| 1776 | return -EINVAL; | 1777 | return -EINVAL; |
| 1777 | 1778 | ||
| 1778 | version = be16_to_cpu(version_be); | 1779 | version = be16_to_cpu(version_be); |
| 1779 | |||
| 1780 | switch (version) { | 1780 | switch (version) { |
| 1781 | case 0x8232: /* mt9v011 640x480 1.3 Mpix sensor */ | 1781 | case 0x8232: /* mt9v011 640x480 1.3 Mpix sensor */ |
| 1782 | case 0x8243: /* mt9v011 rev B 640x480 1.3 Mpix sensor */ | 1782 | case 0x8243: /* mt9v011 rev B 640x480 1.3 Mpix sensor */ |
| 1783 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; | 1783 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; |
| 1784 | em28xx_set_model(dev); | ||
| 1785 | |||
| 1784 | sensor_name = "mt9v011"; | 1786 | sensor_name = "mt9v011"; |
| 1785 | dev->em28xx_sensor = EM28XX_MT9V011; | 1787 | dev->em28xx_sensor = EM28XX_MT9V011; |
| 1786 | dev->sensor_xres = 640; | 1788 | dev->sensor_xres = 640; |
| 1787 | dev->sensor_yres = 480; | 1789 | dev->sensor_yres = 480; |
| 1788 | dev->sensor_xtal = 12150000; | 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; | ||
| 1789 | 1801 | ||
| 1790 | /* probably means GRGB 16 bit bayer */ | 1802 | /* probably means GRGB 16 bit bayer */ |
| 1791 | dev->vinmode = 0x0d; | 1803 | dev->vinmode = 0x0d; |
| @@ -1794,6 +1806,8 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
| 1794 | break; | 1806 | break; |
| 1795 | case 0x8431: | 1807 | case 0x8431: |
| 1796 | dev->model = EM2750_BOARD_UNKNOWN; | 1808 | dev->model = EM2750_BOARD_UNKNOWN; |
| 1809 | em28xx_set_model(dev); | ||
| 1810 | |||
| 1797 | sensor_name = "mt9m001"; | 1811 | sensor_name = "mt9m001"; |
| 1798 | dev->em28xx_sensor = EM28XX_MT9M001; | 1812 | dev->em28xx_sensor = EM28XX_MT9M001; |
| 1799 | em28xx_initialize_mt9m001(dev); | 1813 | em28xx_initialize_mt9m001(dev); |
| @@ -1810,6 +1824,9 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
| 1810 | return -EINVAL; | 1824 | return -EINVAL; |
| 1811 | } | 1825 | } |
| 1812 | 1826 | ||
| 1827 | /* Setup webcam defaults */ | ||
| 1828 | em28xx_pre_card_setup(dev); | ||
| 1829 | |||
| 1813 | em28xx_errdev("Sensor is %s, using model %s entry.\n", | 1830 | em28xx_errdev("Sensor is %s, using model %s entry.\n", |
| 1814 | sensor_name, em28xx_boards[dev->model].name); | 1831 | sensor_name, em28xx_boards[dev->model].name); |
| 1815 | 1832 | ||
| @@ -2169,7 +2186,20 @@ void em28xx_register_i2c_ir(struct em28xx *dev) | |||
| 2169 | 2186 | ||
| 2170 | void em28xx_card_setup(struct em28xx *dev) | 2187 | void em28xx_card_setup(struct em28xx *dev) |
| 2171 | { | 2188 | { |
| 2172 | 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); | ||
| 2173 | 2203 | ||
| 2174 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; | 2204 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; |
| 2175 | if (em28xx_boards[dev->model].tuner_addr) | 2205 | if (em28xx_boards[dev->model].tuner_addr) |
| @@ -2489,18 +2519,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 2489 | dev->vinmode = 0x10; | 2519 | dev->vinmode = 0x10; |
| 2490 | dev->vinctl = 0x11; | 2520 | dev->vinctl = 0x11; |
| 2491 | 2521 | ||
| 2492 | /* | ||
| 2493 | * If the device can be a webcam, seek for a sensor. | ||
| 2494 | * If sensor is not found, then it isn't a webcam. | ||
| 2495 | */ | ||
| 2496 | if (dev->board.is_webcam) | ||
| 2497 | if (em28xx_hint_sensor(dev) < 0) | ||
| 2498 | dev->board.is_webcam = 0; | ||
| 2499 | |||
| 2500 | /* It makes no sense to use de-interlacing mode on webcams */ | ||
| 2501 | if (dev->board.is_webcam) | ||
| 2502 | dev->progressive = 1; | ||
| 2503 | |||
| 2504 | /* Do board specific init and eeprom reading */ | 2522 | /* Do board specific init and eeprom reading */ |
| 2505 | em28xx_card_setup(dev); | 2523 | em28xx_card_setup(dev); |
| 2506 | 2524 | ||
