aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sonixb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/sonixb.c')
-rw-r--r--drivers/media/video/gspca/sonixb.c96
1 files changed, 67 insertions, 29 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 5033810f56fc..7f67148a5230 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -20,6 +20,26 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23/* Some documentation on known sonixb registers:
24
25Reg Use
260x10 high nibble red gain low nibble blue gain
270x11 low nibble green gain
280x12 hstart
290x13 vstart
300x15 hsize (hsize = register-value * 16)
310x16 vsize (vsize = register-value * 16)
320x17 bit 0 toggle compression quality (according to sn9c102 driver)
330x18 bit 7 enables compression, bit 4-5 set image down scaling:
34 00 scale 1, 01 scale 1/2, 10, scale 1/4
350x19 high-nibble is sensor clock divider, changes exposure on sensors which
36 use a clock generated by the bridge. Some sensors have their own clock.
370x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32)
380x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32)
390x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
400x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
41*/
42
23#define MODULE_NAME "sonixb" 43#define MODULE_NAME "sonixb"
24 44
25#include "gspca.h" 45#include "gspca.h"
@@ -74,10 +94,10 @@ struct sensor_data {
74/* sensor_data flags */ 94/* sensor_data flags */
75#define F_GAIN 0x01 /* has gain */ 95#define F_GAIN 0x01 /* has gain */
76#define F_SIF 0x02 /* sif or vga */ 96#define F_SIF 0x02 /* sif or vga */
77#define F_RAW 0x04 /* sensor tested ok with raw bayer mode */
78 97
79/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ 98/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
80#define MODE_RAW 0x10 /* raw bayer mode */ 99#define MODE_RAW 0x10 /* raw bayer mode */
100#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
81 101
82/* ctrl_dis helper macros */ 102/* ctrl_dis helper macros */
83#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)) 103#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
@@ -211,7 +231,7 @@ static struct ctrl sd_ctrls[] = {
211static struct v4l2_pix_format vga_mode[] = { 231static struct v4l2_pix_format vga_mode[] = {
212 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 232 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
213 .bytesperline = 160, 233 .bytesperline = 160,
214 .sizeimage = 160 * 120, 234 .sizeimage = 160 * 120 * 5 / 4,
215 .colorspace = V4L2_COLORSPACE_SRGB, 235 .colorspace = V4L2_COLORSPACE_SRGB,
216 .priv = 2 | MODE_RAW}, 236 .priv = 2 | MODE_RAW},
217 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 237 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
@@ -231,9 +251,19 @@ static struct v4l2_pix_format vga_mode[] = {
231 .priv = 0}, 251 .priv = 0},
232}; 252};
233static struct v4l2_pix_format sif_mode[] = { 253static struct v4l2_pix_format sif_mode[] = {
254 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
255 .bytesperline = 160,
256 .sizeimage = 160 * 120,
257 .colorspace = V4L2_COLORSPACE_SRGB,
258 .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
259 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
260 .bytesperline = 160,
261 .sizeimage = 160 * 120 * 5 / 4,
262 .colorspace = V4L2_COLORSPACE_SRGB,
263 .priv = 1 | MODE_REDUCED_SIF},
234 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 264 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
235 .bytesperline = 176, 265 .bytesperline = 176,
236 .sizeimage = 176 * 144, 266 .sizeimage = 176 * 144 * 5 / 4,
237 .colorspace = V4L2_COLORSPACE_SRGB, 267 .colorspace = V4L2_COLORSPACE_SRGB,
238 .priv = 1 | MODE_RAW}, 268 .priv = 1 | MODE_RAW},
239 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 269 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
@@ -241,6 +271,11 @@ static struct v4l2_pix_format sif_mode[] = {
241 .sizeimage = 176 * 144 * 5 / 4, 271 .sizeimage = 176 * 144 * 5 / 4,
242 .colorspace = V4L2_COLORSPACE_SRGB, 272 .colorspace = V4L2_COLORSPACE_SRGB,
243 .priv = 1}, 273 .priv = 1},
274 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
275 .bytesperline = 320,
276 .sizeimage = 320 * 240 * 5 / 4,
277 .colorspace = V4L2_COLORSPACE_SRGB,
278 .priv = 0 | MODE_REDUCED_SIF},
244 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 279 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
245 .bytesperline = 352, 280 .bytesperline = 352,
246 .sizeimage = 352 * 288 * 5 / 4, 281 .sizeimage = 352 * 288 * 5 / 4,
@@ -266,7 +301,7 @@ static const __u8 initOv6650[] = {
266 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 301 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
267 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 302 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, 303 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
269 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 304 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
270}; 305};
271static const __u8 ov6650_sensor_init[][8] = 306static const __u8 ov6650_sensor_init[][8] =
272{ 307{
@@ -350,7 +385,7 @@ static const __u8 initPas106[] = {
350 0x00, 0x00, 385 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 386 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
352 0x16, 0x12, 0x24, COMP1, MCK_INIT1, 387 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
353 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c 388 0x18, 0x10, 0x02, 0x02, 0x09, 0x07
354}; 389};
355/* compression 0x86 mckinit1 0x2b */ 390/* compression 0x86 mckinit1 0x2b */
356static const __u8 pas106_sensor_init[][8] = { 391static const __u8 pas106_sensor_init[][8] = {
@@ -456,15 +491,14 @@ static const __u8 tas5130_sensor_init[][8] = {
456 491
457struct sensor_data sensor_data[] = { 492struct sensor_data sensor_data[] = {
458SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0), 493SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
459SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, 0, 494SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
460 0x60),
461SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, 495SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
462 F_GAIN, 0, 0x21), 496 F_GAIN, 0, 0x21),
463SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ, 497SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
464 0), 498 0),
465SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_RAW, 499SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
466 NO_EXPO|NO_FREQ, 0), 500 NO_EXPO|NO_FREQ, 0),
467SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, 501SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
468 NO_BRIGHTNESS|NO_FREQ, 0), 502 NO_BRIGHTNESS|NO_FREQ, 0),
469SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 503SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
470 0), 504 0),
@@ -834,10 +868,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
834 cam->cam_mode = sif_mode; 868 cam->cam_mode = sif_mode;
835 cam->nmodes = ARRAY_SIZE(sif_mode); 869 cam->nmodes = ARRAY_SIZE(sif_mode);
836 } 870 }
837 if (!(sensor_data[sd->sensor].flags & F_RAW)) {
838 cam->cam_mode++;
839 cam->nmodes--;
840 }
841 sd->brightness = BRIGHTNESS_DEF; 871 sd->brightness = BRIGHTNESS_DEF;
842 sd->gain = GAIN_DEF; 872 sd->gain = GAIN_DEF;
843 sd->exposure = EXPOSURE_DEF; 873 sd->exposure = EXPOSURE_DEF;
@@ -864,31 +894,39 @@ static int sd_init(struct gspca_dev *gspca_dev)
864static void sd_start(struct gspca_dev *gspca_dev) 894static void sd_start(struct gspca_dev *gspca_dev)
865{ 895{
866 struct sd *sd = (struct sd *) gspca_dev; 896 struct sd *sd = (struct sd *) gspca_dev;
897 struct cam *cam = &gspca_dev->cam;
867 int mode, l; 898 int mode, l;
868 const __u8 *sn9c10x; 899 const __u8 *sn9c10x;
869 __u8 reg17_19[3]; 900 __u8 reg12_19[8];
870 901
871 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 0x07; 902 mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
872 sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge]; 903 sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
873 l = sensor_data[sd->sensor].bridge_init_size[sd->bridge]; 904 l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
874 reg17_19[0] = sn9c10x[0x17 - 1]; 905 memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
875 reg17_19[1] = sn9c10x[0x18 - 1] | (mode << 4); 906 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
876 reg17_19[2] = sn9c10x[0x19 - 1];
877 /* Special cases where reg 17 and or 19 value depends on mode */ 907 /* Special cases where reg 17 and or 19 value depends on mode */
878 switch (sd->sensor) { 908 switch (sd->sensor) {
879 case SENSOR_PAS202: 909 case SENSOR_PAS202:
880 reg17_19[0] = mode ? 0x24 : 0x20; 910 reg12_19[5] = mode ? 0x24 : 0x20;
881 break; 911 break;
882 case SENSOR_TAS5130CXX: 912 case SENSOR_TAS5130CXX:
883 /* probably not mode specific at all most likely the upper 913 /* probably not mode specific at all most likely the upper
884 nibble of 0x19 is exposure (clock divider) just as with 914 nibble of 0x19 is exposure (clock divider) just as with
885 the tas5110, we need someone to test this. */ 915 the tas5110, we need someone to test this. */
886 reg17_19[2] = mode ? 0x23 : 0x43; 916 reg12_19[7] = mode ? 0x23 : 0x43;
887 break; 917 break;
888 } 918 }
889 /* Disable compression when the raw bayer format has been selected */ 919 /* Disable compression when the raw bayer format has been selected */
890 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) 920 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
891 reg17_19[1] &= ~0x80; 921 reg12_19[6] &= ~0x80;
922
923 /* Vga mode emulation on SIF sensor? */
924 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
925 reg12_19[0] += 16; /* 0x12: hstart adjust */
926 reg12_19[1] += 24; /* 0x13: vstart adjust */
927 reg12_19[3] = 320 / 16; /* 0x15: hsize */
928 reg12_19[4] = 240 / 16; /* 0x16: vsize */
929 }
892 930
893 /* reg 0x01 bit 2 video transfert on */ 931 /* reg 0x01 bit 2 video transfert on */
894 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); 932 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
@@ -907,24 +945,24 @@ static void sd_start(struct gspca_dev *gspca_dev)
907 sd->bridge]); 945 sd->bridge]);
908 946
909 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ 947 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
910 reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); 948 reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
911 /* compression register */ 949 /* compression register */
912 reg_w(gspca_dev, 0x18, &reg17_19[1], 1); 950 reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
913 /* H_start */ 951 /* H_start */
914 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); 952 reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
915 /* V_START */ 953 /* V_START */
916 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1); 954 reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
917 /* reset 0x17 SensorClk enable inv Clk 0x60 */ 955 /* reset 0x17 SensorClk enable inv Clk 0x60 */
918 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ 956 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
919 reg_w(gspca_dev, 0x17, &reg17_19[0], 1); 957 reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
920 /*MCKSIZE ->3 */ /*fixme: not ov7630*/ 958 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
921 reg_w(gspca_dev, 0x19, &reg17_19[2], 1); 959 reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
922 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ 960 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
923 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); 961 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
924 /* Enable video transfert */ 962 /* Enable video transfert */
925 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); 963 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
926 /* Compression */ 964 /* Compression */
927 reg_w(gspca_dev, 0x18, &reg17_19[1], 2); 965 reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
928 msleep(20); 966 msleep(20);
929 967
930 sd->reg11 = -1; 968 sd->reg11 = -1;