diff options
Diffstat (limited to 'drivers/media/video/gspca/sonixj.c')
-rw-r--r-- | drivers/media/video/gspca/sonixj.c | 94 |
1 files changed, 65 insertions, 29 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index edc26d8ad2ad..363c0fa39d9e 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #define MODULE_NAME "sonixj" | 22 | #define MODULE_NAME "sonixj" |
23 | 23 | ||
24 | #include "gspca.h" | 24 | #include "gspca.h" |
25 | #define QUANT_VAL 4 /* quantization table */ | ||
26 | #include "jpeg.h" | 25 | #include "jpeg.h" |
27 | 26 | ||
28 | #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0) | 27 | #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0) |
@@ -47,6 +46,10 @@ struct sd { | |||
47 | u8 gamma; | 46 | u8 gamma; |
48 | u8 vflip; /* ov7630/ov7648 only */ | 47 | u8 vflip; /* ov7630/ov7648 only */ |
49 | u8 infrared; /* mt9v111 only */ | 48 | u8 infrared; /* mt9v111 only */ |
49 | u8 quality; /* image quality */ | ||
50 | u8 jpegqual; /* webcam quality */ | ||
51 | |||
52 | u8 reg18; | ||
50 | 53 | ||
51 | s8 ag_cnt; | 54 | s8 ag_cnt; |
52 | #define AG_CNT_START 13 | 55 | #define AG_CNT_START 13 |
@@ -68,6 +71,8 @@ struct sd { | |||
68 | #define SENSOR_OV7660 7 | 71 | #define SENSOR_OV7660 7 |
69 | #define SENSOR_SP80708 8 | 72 | #define SENSOR_SP80708 8 |
70 | u8 i2c_base; | 73 | u8 i2c_base; |
74 | |||
75 | u8 *jpeg_hdr; | ||
71 | }; | 76 | }; |
72 | 77 | ||
73 | /* V4L2 controls supported by the driver */ | 78 | /* V4L2 controls supported by the driver */ |
@@ -859,25 +864,6 @@ static const u8 sp80708_sensor_init[][8] = { | |||
859 | {} | 864 | {} |
860 | }; | 865 | }; |
861 | 866 | ||
862 | static const u8 qtable4[] = { | ||
863 | 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, | ||
864 | 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11, | ||
865 | 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f, | ||
866 | 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15, | ||
867 | 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d, | ||
868 | 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23, | ||
869 | 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30, | ||
870 | 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29, | ||
871 | 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a, | ||
872 | 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29, | ||
873 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
874 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
875 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
876 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
877 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
878 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29 | ||
879 | }; | ||
880 | |||
881 | /* read <len> bytes to gspca_dev->usb_buf */ | 867 | /* read <len> bytes to gspca_dev->usb_buf */ |
882 | static void reg_r(struct gspca_dev *gspca_dev, | 868 | static void reg_r(struct gspca_dev *gspca_dev, |
883 | u16 value, int len) | 869 | u16 value, int len) |
@@ -1309,6 +1295,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1309 | else | 1295 | else |
1310 | sd->vflip = 1; | 1296 | sd->vflip = 1; |
1311 | sd->infrared = INFRARED_DEF; | 1297 | sd->infrared = INFRARED_DEF; |
1298 | sd->quality = 80; | ||
1299 | sd->jpegqual = 80; | ||
1312 | 1300 | ||
1313 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; | 1301 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; |
1314 | return 0; | 1302 | return 0; |
@@ -1610,12 +1598,49 @@ static void setinfrared(struct sd *sd) | |||
1610 | sd->infrared ? 0x66 : 0x64); | 1598 | sd->infrared ? 0x66 : 0x64); |
1611 | } | 1599 | } |
1612 | 1600 | ||
1601 | static void setjpegqual(struct gspca_dev *gspca_dev) | ||
1602 | { | ||
1603 | struct sd *sd = (struct sd *) gspca_dev; | ||
1604 | int i, sc; | ||
1605 | |||
1606 | if (sd->jpegqual < 50) | ||
1607 | sc = 5000 / sd->jpegqual; | ||
1608 | else | ||
1609 | sc = 200 - sd->jpegqual * 2; | ||
1610 | #if USB_BUF_SZ < 64 | ||
1611 | #error "No room enough in usb_buf for quantization table" | ||
1612 | #endif | ||
1613 | for (i = 0; i < 64; i++) | ||
1614 | gspca_dev->usb_buf[i] = | ||
1615 | (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100; | ||
1616 | usb_control_msg(gspca_dev->dev, | ||
1617 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
1618 | 0x08, | ||
1619 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
1620 | 0x0100, 0, | ||
1621 | gspca_dev->usb_buf, 64, | ||
1622 | 500); | ||
1623 | for (i = 0; i < 64; i++) | ||
1624 | gspca_dev->usb_buf[i] = | ||
1625 | (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100; | ||
1626 | usb_control_msg(gspca_dev->dev, | ||
1627 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
1628 | 0x08, | ||
1629 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
1630 | 0x0140, 0, | ||
1631 | gspca_dev->usb_buf, 64, | ||
1632 | 500); | ||
1633 | |||
1634 | sd->reg18 ^= 0x40; | ||
1635 | reg_w1(gspca_dev, 0x18, sd->reg18); | ||
1636 | } | ||
1637 | |||
1613 | /* -- start the camera -- */ | 1638 | /* -- start the camera -- */ |
1614 | static int sd_start(struct gspca_dev *gspca_dev) | 1639 | static int sd_start(struct gspca_dev *gspca_dev) |
1615 | { | 1640 | { |
1616 | struct sd *sd = (struct sd *) gspca_dev; | 1641 | struct sd *sd = (struct sd *) gspca_dev; |
1617 | int i; | 1642 | int i; |
1618 | u8 reg1, reg17, reg18; | 1643 | u8 reg1, reg17; |
1619 | const u8 *sn9c1xx; | 1644 | const u8 *sn9c1xx; |
1620 | int mode; | 1645 | int mode; |
1621 | static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; | 1646 | static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; |
@@ -1624,6 +1649,12 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1624 | static const u8 CE_ov76xx[] = | 1649 | static const u8 CE_ov76xx[] = |
1625 | { 0x32, 0xdd, 0x32, 0xdd }; | 1650 | { 0x32, 0xdd, 0x32, 0xdd }; |
1626 | 1651 | ||
1652 | /* create the JPEG header */ | ||
1653 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | ||
1654 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | ||
1655 | 0x21); /* JPEG 422 */ | ||
1656 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | ||
1657 | |||
1627 | sn9c1xx = sn_tb[(int) sd->sensor]; | 1658 | sn9c1xx = sn_tb[(int) sd->sensor]; |
1628 | configure_gpio(gspca_dev, sn9c1xx); | 1659 | configure_gpio(gspca_dev, sn9c1xx); |
1629 | 1660 | ||
@@ -1782,13 +1813,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1782 | } | 1813 | } |
1783 | 1814 | ||
1784 | /* here change size mode 0 -> VGA; 1 -> CIF */ | 1815 | /* here change size mode 0 -> VGA; 1 -> CIF */ |
1785 | reg18 = sn9c1xx[0x18] | (mode << 4); | 1816 | sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40; |
1786 | reg_w1(gspca_dev, 0x18, reg18 | 0x40); | 1817 | reg_w1(gspca_dev, 0x18, sd->reg18); |
1787 | 1818 | setjpegqual(gspca_dev); | |
1788 | reg_w(gspca_dev, 0x0100, qtable4, 0x40); | ||
1789 | reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40); | ||
1790 | |||
1791 | reg_w1(gspca_dev, 0x18, reg18); | ||
1792 | 1819 | ||
1793 | reg_w1(gspca_dev, 0x17, reg17); | 1820 | reg_w1(gspca_dev, 0x17, reg17); |
1794 | reg_w1(gspca_dev, 0x01, reg1); | 1821 | reg_w1(gspca_dev, 0x01, reg1); |
@@ -1845,6 +1872,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1845 | reg_w1(gspca_dev, 0xf1, 0x00); | 1872 | reg_w1(gspca_dev, 0xf1, 0x00); |
1846 | } | 1873 | } |
1847 | 1874 | ||
1875 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1876 | { | ||
1877 | struct sd *sd = (struct sd *) gspca_dev; | ||
1878 | |||
1879 | kfree(sd->jpeg_hdr); | ||
1880 | } | ||
1881 | |||
1848 | static void do_autogain(struct gspca_dev *gspca_dev) | 1882 | static void do_autogain(struct gspca_dev *gspca_dev) |
1849 | { | 1883 | { |
1850 | struct sd *sd = (struct sd *) gspca_dev; | 1884 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -1928,7 +1962,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1928 | if (gspca_dev->last_packet_type == LAST_PACKET) { | 1962 | if (gspca_dev->last_packet_type == LAST_PACKET) { |
1929 | 1963 | ||
1930 | /* put the JPEG 422 header */ | 1964 | /* put the JPEG 422 header */ |
1931 | jpeg_put_header(gspca_dev, frame, 0x21); | 1965 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, |
1966 | sd->jpeg_hdr, JPEG_HDR_SZ); | ||
1932 | } | 1967 | } |
1933 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 1968 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); |
1934 | } | 1969 | } |
@@ -2104,6 +2139,7 @@ static const struct sd_desc sd_desc = { | |||
2104 | .init = sd_init, | 2139 | .init = sd_init, |
2105 | .start = sd_start, | 2140 | .start = sd_start, |
2106 | .stopN = sd_stopN, | 2141 | .stopN = sd_stopN, |
2142 | .stop0 = sd_stop0, | ||
2107 | .pkt_scan = sd_pkt_scan, | 2143 | .pkt_scan = sd_pkt_scan, |
2108 | .dq_callback = do_autogain, | 2144 | .dq_callback = do_autogain, |
2109 | }; | 2145 | }; |