aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2011-04-27 16:36:05 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-05-20 08:29:29 -0400
commit240d57bb8238d6998644c7f696c27076956ff653 (patch)
treeeada3a282c50d4209ee76d7ef92f4748a1d11174 /drivers
parent449a0bada34e5e554ef52aca86aeaa81ed35533e (diff)
[media] usbvision: add Nogatech USB MicroCam
Add Nogatech USB MicroCam PAL (NV3001P) and NTSC (NV3000N) support to usbvision driver. PAL version is tested, NTSC untested. Data captured using usbsnoop, init_values are listed in the INF file along with image dimensions, offsets and frame rates. Signed-off-by: Ondrej Zary <linux@rainbow-software.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.c33
-rw-r--r--drivers/media/video/usbvision/usbvision-cards.h2
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c73
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c3
-rw-r--r--drivers/media/video/usbvision/usbvision.h6
6 files changed, 114 insertions, 5 deletions
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c
index 68b998bd203f..8f5266157f15 100644
--- a/drivers/media/video/usbvision/usbvision-cards.c
+++ b/drivers/media/video/usbvision/usbvision-cards.c
@@ -1025,6 +1025,34 @@ struct usbvision_device_data_st usbvision_device_data[] = {
1025 .y_offset = -1, 1025 .y_offset = -1,
1026 .model_string = "Hauppauge WinTv-USB", 1026 .model_string = "Hauppauge WinTv-USB",
1027 }, 1027 },
1028 [MICROCAM_NTSC] = {
1029 .interface = -1,
1030 .codec = CODEC_WEBCAM,
1031 .video_channels = 1,
1032 .video_norm = V4L2_STD_NTSC,
1033 .audio_channels = 0,
1034 .radio = 0,
1035 .vbi = 0,
1036 .tuner = 0,
1037 .tuner_type = 0,
1038 .x_offset = 71,
1039 .y_offset = 15,
1040 .model_string = "Nogatech USB MicroCam NTSC (NV3000N)",
1041 },
1042 [MICROCAM_PAL] = {
1043 .interface = -1,
1044 .codec = CODEC_WEBCAM,
1045 .video_channels = 1,
1046 .video_norm = V4L2_STD_PAL,
1047 .audio_channels = 0,
1048 .radio = 0,
1049 .vbi = 0,
1050 .tuner = 0,
1051 .tuner_type = 0,
1052 .x_offset = 71,
1053 .y_offset = 18,
1054 .model_string = "Nogatech USB MicroCam PAL (NV3001P)",
1055 },
1028}; 1056};
1029const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data); 1057const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data);
1030 1058
@@ -1042,6 +1070,8 @@ struct usb_device_id usbvision_table[] = {
1042 { USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG }, 1070 { USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG },
1043 { USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN }, 1071 { USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN },
1044 { USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH }, 1072 { USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH },
1073 { USB_DEVICE(0x0573, 0x3000), .driver_info = MICROCAM_NTSC },
1074 { USB_DEVICE(0x0573, 0x3001), .driver_info = MICROCAM_PAL },
1045 { USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM }, 1075 { USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM },
1046 { USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM }, 1076 { USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM },
1047 { USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM }, 1077 { USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM },
@@ -1088,8 +1118,7 @@ struct usb_device_id usbvision_table[] = {
1088 { USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM }, 1118 { USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM },
1089 { USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB }, 1119 { USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB },
1090 { USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM }, 1120 { USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM },
1091 { USB_DEVICE(0x2304, 0x0113), 1121 { USB_DEVICE(0x2304, 0x0113), .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
1092 .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
1093 { USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 }, 1122 { USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 },
1094 { USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 }, 1123 { USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 },
1095 { USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 }, 1124 { USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 },
diff --git a/drivers/media/video/usbvision/usbvision-cards.h b/drivers/media/video/usbvision/usbvision-cards.h
index 9c6ad22960d8..a51cc1185cce 100644
--- a/drivers/media/video/usbvision/usbvision-cards.h
+++ b/drivers/media/video/usbvision/usbvision-cards.h
@@ -63,5 +63,7 @@
63#define PINNA_PCTV_BUNGEE_PAL_FM 62 63#define PINNA_PCTV_BUNGEE_PAL_FM 62
64#define HPG_WINTV 63 64#define HPG_WINTV 63
65#define PINNA_PCTV_USB_NTSC_FM_V3 64 65#define PINNA_PCTV_USB_NTSC_FM_V3 64
66#define MICROCAM_NTSC 65
67#define MICROCAM_PAL 66
66 68
67extern const int usbvision_device_data_size; 69extern const int usbvision_device_data_size;
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index c8feb0d6fccf..89ac46277031 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -1679,6 +1679,55 @@ int usbvision_power_off(struct usb_usbvision *usbvision)
1679 return err_code; 1679 return err_code;
1680} 1680}
1681 1681
1682/* configure webcam image sensor using the serial port */
1683static int usbvision_init_webcam(struct usb_usbvision *usbvision)
1684{
1685 int rc;
1686 int i;
1687 static char init_values[38][3] = {
1688 { 0x04, 0x12, 0x08 }, { 0x05, 0xff, 0xc8 }, { 0x06, 0x18, 0x07 }, { 0x07, 0x90, 0x00 },
1689 { 0x09, 0x00, 0x00 }, { 0x0a, 0x00, 0x00 }, { 0x0b, 0x08, 0x00 }, { 0x0d, 0xcc, 0xcc },
1690 { 0x0e, 0x13, 0x14 }, { 0x10, 0x9b, 0x83 }, { 0x11, 0x5a, 0x3f }, { 0x12, 0xe4, 0x73 },
1691 { 0x13, 0x88, 0x84 }, { 0x14, 0x89, 0x80 }, { 0x15, 0x00, 0x20 }, { 0x16, 0x00, 0x00 },
1692 { 0x17, 0xff, 0xa0 }, { 0x18, 0x6b, 0x20 }, { 0x19, 0x22, 0x40 }, { 0x1a, 0x10, 0x07 },
1693 { 0x1b, 0x00, 0x47 }, { 0x1c, 0x03, 0xe0 }, { 0x1d, 0x00, 0x00 }, { 0x1e, 0x00, 0x00 },
1694 { 0x1f, 0x00, 0x00 }, { 0x20, 0x00, 0x00 }, { 0x21, 0x00, 0x00 }, { 0x22, 0x00, 0x00 },
1695 { 0x23, 0x00, 0x00 }, { 0x24, 0x00, 0x00 }, { 0x25, 0x00, 0x00 }, { 0x26, 0x00, 0x00 },
1696 { 0x27, 0x00, 0x00 }, { 0x28, 0x00, 0x00 }, { 0x29, 0x00, 0x00 }, { 0x08, 0x80, 0x60 },
1697 { 0x0f, 0x2d, 0x24 }, { 0x0c, 0x80, 0x80 }
1698 };
1699 char value[3];
1700
1701 /* the only difference between PAL and NTSC init_values */
1702 if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_NTSC)
1703 init_values[4][1] = 0x34;
1704
1705 for (i = 0; i < sizeof(init_values) / 3; i++) {
1706 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
1707 memcpy(value, init_values[i], 3);
1708 rc = usb_control_msg(usbvision->dev,
1709 usb_sndctrlpipe(usbvision->dev, 1),
1710 USBVISION_OP_CODE,
1711 USB_DIR_OUT | USB_TYPE_VENDOR |
1712 USB_RECIP_ENDPOINT, 0,
1713 (__u16) USBVISION_SER_DAT1, value,
1714 3, HZ);
1715 if (rc < 0)
1716 return rc;
1717 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SIO);
1718 /* write 3 bytes to the serial port using SIO mode */
1719 usbvision_write_reg(usbvision, USBVISION_SER_CONT, 3 | 0x10);
1720 usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, 0);
1721 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
1722 usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_IO_2);
1723 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT);
1724 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_DAT_IO);
1725 usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT | USBVISION_DAT_IO);
1726 }
1727
1728 return 0;
1729}
1730
1682/* 1731/*
1683 * usbvision_set_video_format() 1732 * usbvision_set_video_format()
1684 * 1733 *
@@ -1797,6 +1846,13 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
1797 1846
1798 frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */ 1847 frame_drop = FRAMERATE_MAX; /* We can allow the maximum here, because dropping is controlled */
1799 1848
1849 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
1850 if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_PAL)
1851 frame_drop = 25;
1852 else
1853 frame_drop = 30;
1854 }
1855
1800 /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ... 1856 /* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
1801 => frame_skip = 4; 1857 => frame_skip = 4;
1802 => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25; 1858 => frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
@@ -2046,6 +2102,12 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
2046 value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */ 2102 value[7] = 0x00; /* 0x0010 -> 16 Input video v offset */
2047 } 2103 }
2048 2104
2105 /* webcam is only 480 pixels wide, both PAL and NTSC version */
2106 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
2107 value[0] = 0xe0;
2108 value[1] = 0x01; /* 0x01E0 -> 480 Input video line length */
2109 }
2110
2049 if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) { 2111 if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) {
2050 value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff; 2112 value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff;
2051 value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8; 2113 value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8;
@@ -2148,7 +2210,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
2148 (__u16) USBVISION_DRM_PRM1, value, 8, HZ); 2210 (__u16) USBVISION_DRM_PRM1, value, 8, HZ);
2149 2211
2150 if (rc < 0) { 2212 if (rc < 0) {
2151 dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc); 2213 dev_err(&usbvision->dev->dev, "%s: ERROR=%d\n", __func__, rc);
2152 return rc; 2214 return rc;
2153 } 2215 }
2154 2216
@@ -2180,8 +2242,15 @@ int usbvision_power_on(struct usb_usbvision *usbvision)
2180 usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2242 usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2181 USBVISION_SSPND_EN | USBVISION_RES2); 2243 USBVISION_SSPND_EN | USBVISION_RES2);
2182 2244
2245 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
2246 usbvision_write_reg(usbvision, USBVISION_VIN_REG1,
2247 USBVISION_16_422_SYNC | USBVISION_HVALID_PO);
2248 usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
2249 USBVISION_NOHVALID | USBVISION_KEEP_BLANK);
2250 }
2183 usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2251 usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2184 USBVISION_SSPND_EN | USBVISION_PWR_VID); 2252 USBVISION_SSPND_EN | USBVISION_PWR_VID);
2253 mdelay(10);
2185 err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG, 2254 err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2186 USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2); 2255 USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
2187 if (err_code == 1) 2256 if (err_code == 1)
@@ -2310,6 +2379,8 @@ int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel)
2310 2379
2311int usbvision_setup(struct usb_usbvision *usbvision, int format) 2380int usbvision_setup(struct usb_usbvision *usbvision, int format)
2312{ 2381{
2382 if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM)
2383 usbvision_init_webcam(usbvision);
2313 usbvision_set_video_format(usbvision, format); 2384 usbvision_set_video_format(usbvision, format);
2314 usbvision_set_dram_settings(usbvision); 2385 usbvision_set_dram_settings(usbvision);
2315 usbvision_set_compress_params(usbvision); 2386 usbvision_set_compress_params(usbvision);
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 05b1344181cd..d7f97513b289 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -222,7 +222,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
222 i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev); 222 i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
223 223
224 if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) { 224 if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
225 printk(KERN_ERR "usbvision_register: can't write reg\n"); 225 printk(KERN_ERR "usbvision_i2c_register: can't write reg\n");
226 return -EBUSY; 226 return -EBUSY;
227 } 227 }
228 228
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 6083137f0bf8..711cd997e21c 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1470,7 +1470,8 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
1470 1470
1471 /* This should be here to make i2c clients to be able to register */ 1471 /* This should be here to make i2c clients to be able to register */
1472 /* first switch off audio */ 1472 /* first switch off audio */
1473 usbvision_audio_off(usbvision); 1473 if (usbvision_device_data[model].audio_channels > 0)
1474 usbvision_audio_off(usbvision);
1474 if (!power_on_at_open) { 1475 if (!power_on_at_open) {
1475 /* and then power up the noisy tuner */ 1476 /* and then power up the noisy tuner */
1476 usbvision_power_on(usbvision); 1477 usbvision_power_on(usbvision);
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index 8074787fd1ac..43cf61fe4943 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -59,6 +59,11 @@
59 #define USBVISION_AUDIO_RADIO 2 59 #define USBVISION_AUDIO_RADIO 2
60 #define USBVISION_AUDIO_MUTE 3 60 #define USBVISION_AUDIO_MUTE 3
61#define USBVISION_SER_MODE 0x07 61#define USBVISION_SER_MODE 0x07
62 #define USBVISION_CLK_OUT (1 << 0)
63 #define USBVISION_DAT_IO (1 << 1)
64 #define USBVISION_SENS_OUT (1 << 2)
65 #define USBVISION_SER_MODE_SOFT (0 << 4)
66 #define USBVISION_SER_MODE_SIO (1 << 4)
62#define USBVISION_SER_ADRS 0x08 67#define USBVISION_SER_ADRS 0x08
63#define USBVISION_SER_CONT 0x09 68#define USBVISION_SER_CONT 0x09
64#define USBVISION_SER_DAT1 0x0A 69#define USBVISION_SER_DAT1 0x0A
@@ -328,6 +333,7 @@ struct usbvision_frame {
328 333
329#define CODEC_SAA7113 7113 334#define CODEC_SAA7113 7113
330#define CODEC_SAA7111 7111 335#define CODEC_SAA7111 7111
336#define CODEC_WEBCAM 3000
331#define BRIDGE_NT1003 1003 337#define BRIDGE_NT1003 1003
332#define BRIDGE_NT1004 1004 338#define BRIDGE_NT1004 1004
333#define BRIDGE_NT1005 1005 339#define BRIDGE_NT1005 1005