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.c50
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[] = {
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 = { {
@@ -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
2170void em28xx_card_setup(struct em28xx *dev) 2187void 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