Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Subdriver for the GL860 chip with the OV9655 sensor
0003  * Author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
0004  * on dsd's weblog
0005  */
0006 
0007 /* Sensor : OV9655 */
0008 
0009 #include "gl860.h"
0010 
0011 static struct validx tbl_init_at_startup[] = {
0012     {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
0013     {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
0014 
0015     {0x0040, 0x0000},
0016 };
0017 
0018 static struct validx tbl_commmon[] = {
0019     {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d},
0020     {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
0021     {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0040, 0x0000},
0022     {0x00f3, 0x0006}, {0x0058, 0x0000}, {0x0048, 0x0000}, {0x0061, 0x0000},
0023 };
0024 
0025 static s32 tbl_length[] = {12, 56, 52, 54, 56, 42, 32, 12};
0026 
0027 static u8 *tbl_640[] = {
0028     (u8[]){
0029         0x00, 0x40, 0x07, 0x6a, 0x06, 0xf3, 0x0d, 0x6a,
0030         0x10, 0x10, 0xc1, 0x01
0031     }, (u8[]){
0032         0x12, 0x80, 0x00, 0x00, 0x01, 0x98, 0x02, 0x80,
0033         0x03, 0x12, 0x04, 0x03, 0x0b, 0x57, 0x0e, 0x61,
0034         0x0f, 0x42, 0x11, 0x01, 0x12, 0x60, 0x13, 0x00,
0035         0x14, 0x3a, 0x16, 0x24, 0x17, 0x14, 0x18, 0x00,
0036         0x19, 0x01, 0x1a, 0x3d, 0x1e, 0x04, 0x24, 0x3c,
0037         0x25, 0x36, 0x26, 0x72, 0x27, 0x08, 0x28, 0x08,
0038         0x29, 0x15, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x08
0039     }, (u8[]){
0040         0x32, 0xff, 0x33, 0x00, 0x34, 0x3d, 0x35, 0x00,
0041         0x36, 0xfa, 0x38, 0x72, 0x39, 0x57, 0x3a, 0x00,
0042         0x3b, 0x0c, 0x3d, 0x99, 0x3e, 0x0c, 0x3f, 0xc1,
0043         0x40, 0xc0, 0x41, 0x00, 0x42, 0xc0, 0x43, 0x0a,
0044         0x44, 0xf0, 0x45, 0x46, 0x46, 0x62, 0x47, 0x2a,
0045         0x48, 0x3c, 0x4a, 0xee, 0x4b, 0xe7, 0x4c, 0xe7,
0046         0x4d, 0xe7, 0x4e, 0xe7
0047     }, (u8[]){
0048         0x4f, 0x98, 0x50, 0x98, 0x51, 0x00, 0x52, 0x28,
0049         0x53, 0x70, 0x54, 0x98, 0x58, 0x1a, 0x59, 0x85,
0050         0x5a, 0xa9, 0x5b, 0x64, 0x5c, 0x84, 0x5d, 0x53,
0051         0x5e, 0x0e, 0x5f, 0xf0, 0x60, 0xf0, 0x61, 0xf0,
0052         0x62, 0x00, 0x63, 0x00, 0x64, 0x02, 0x65, 0x20,
0053         0x66, 0x00, 0x69, 0x0a, 0x6b, 0x5a, 0x6c, 0x04,
0054         0x6d, 0x55, 0x6e, 0x00, 0x6f, 0x9d
0055     }, (u8[]){
0056         0x70, 0x15, 0x71, 0x78, 0x72, 0x00, 0x73, 0x00,
0057         0x74, 0x3a, 0x75, 0x35, 0x76, 0x01, 0x77, 0x02,
0058         0x7a, 0x24, 0x7b, 0x04, 0x7c, 0x07, 0x7d, 0x10,
0059         0x7e, 0x28, 0x7f, 0x36, 0x80, 0x44, 0x81, 0x52,
0060         0x82, 0x60, 0x83, 0x6c, 0x84, 0x78, 0x85, 0x8c,
0061         0x86, 0x9e, 0x87, 0xbb, 0x88, 0xd2, 0x89, 0xe5,
0062         0x8a, 0x23, 0x8c, 0x8d, 0x90, 0x7c, 0x91, 0x7b
0063     }, (u8[]){
0064         0x9d, 0x02, 0x9e, 0x02, 0x9f, 0x74, 0xa0, 0x73,
0065         0xa1, 0x40, 0xa4, 0x50, 0xa5, 0x68, 0xa6, 0x70,
0066         0xa8, 0xc1, 0xa9, 0xef, 0xaa, 0x92, 0xab, 0x04,
0067         0xac, 0x80, 0xad, 0x80, 0xae, 0x80, 0xaf, 0x80,
0068         0xb2, 0xf2, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x00,
0069         0xb6, 0xaf
0070     }, (u8[]){
0071         0xbb, 0xae, 0xbc, 0x4f, 0xbd, 0x4e, 0xbe, 0x6a,
0072         0xbf, 0x68, 0xc0, 0xaa, 0xc1, 0xc0, 0xc2, 0x01,
0073         0xc3, 0x4e, 0xc6, 0x85, 0xc7, 0x81, 0xc9, 0xe0,
0074         0xca, 0xe8, 0xcb, 0xf0, 0xcc, 0xd8, 0xcd, 0x93
0075     }, (u8[]){
0076         0xd0, 0x01, 0xd1, 0x08, 0xd2, 0xe0, 0xd3, 0x01,
0077         0xd4, 0x10, 0xd5, 0x80
0078     }
0079 };
0080 
0081 static u8 *tbl_1280[] = {
0082     (u8[]){
0083         0x00, 0x40, 0x07, 0x6a, 0x06, 0xf3, 0x0d, 0x6a,
0084         0x10, 0x10, 0xc1, 0x01
0085     },
0086     (u8[]){
0087         0x12, 0x80, 0x00, 0x00, 0x01, 0x98, 0x02, 0x80,
0088         0x03, 0x12, 0x04, 0x01, 0x0b, 0x57, 0x0e, 0x61,
0089         0x0f, 0x42, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00,
0090         0x14, 0x3a, 0x16, 0x24, 0x17, 0x1b, 0x18, 0xbb,
0091         0x19, 0x01, 0x1a, 0x81, 0x1e, 0x04, 0x24, 0x3c,
0092         0x25, 0x36, 0x26, 0x72, 0x27, 0x08, 0x28, 0x08,
0093         0x29, 0x15, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x08
0094     },
0095     (u8[]){
0096         0x32, 0xa4, 0x33, 0x00, 0x34, 0x3d, 0x35, 0x00,
0097         0x36, 0xf8, 0x38, 0x72, 0x39, 0x57, 0x3a, 0x00,
0098         0x3b, 0x0c, 0x3d, 0x99, 0x3e, 0x0c, 0x3f, 0xc2,
0099         0x40, 0xc0, 0x41, 0x00, 0x42, 0xc0, 0x43, 0x0a,
0100         0x44, 0xf0, 0x45, 0x46, 0x46, 0x62, 0x47, 0x2a,
0101         0x48, 0x3c, 0x4a, 0xec, 0x4b, 0xe8, 0x4c, 0xe8,
0102         0x4d, 0xe8, 0x4e, 0xe8
0103     },
0104     (u8[]){
0105         0x4f, 0x98, 0x50, 0x98, 0x51, 0x00, 0x52, 0x28,
0106         0x53, 0x70, 0x54, 0x98, 0x58, 0x1a, 0x59, 0x85,
0107         0x5a, 0xa9, 0x5b, 0x64, 0x5c, 0x84, 0x5d, 0x53,
0108         0x5e, 0x0e, 0x5f, 0xf0, 0x60, 0xf0, 0x61, 0xf0,
0109         0x62, 0x00, 0x63, 0x00, 0x64, 0x02, 0x65, 0x20,
0110         0x66, 0x00, 0x69, 0x02, 0x6b, 0x5a, 0x6c, 0x04,
0111         0x6d, 0x55, 0x6e, 0x00, 0x6f, 0x9d
0112     },
0113     (u8[]){
0114         0x70, 0x08, 0x71, 0x78, 0x72, 0x00, 0x73, 0x01,
0115         0x74, 0x3a, 0x75, 0x35, 0x76, 0x01, 0x77, 0x02,
0116         0x7a, 0x24, 0x7b, 0x04, 0x7c, 0x07, 0x7d, 0x10,
0117         0x7e, 0x28, 0x7f, 0x36, 0x80, 0x44, 0x81, 0x52,
0118         0x82, 0x60, 0x83, 0x6c, 0x84, 0x78, 0x85, 0x8c,
0119         0x86, 0x9e, 0x87, 0xbb, 0x88, 0xd2, 0x89, 0xe5,
0120         0x8a, 0x23, 0x8c, 0x0d, 0x90, 0x90, 0x91, 0x90
0121     },
0122     (u8[]){
0123         0x9d, 0x02, 0x9e, 0x02, 0x9f, 0x94, 0xa0, 0x94,
0124         0xa1, 0x01, 0xa4, 0x50, 0xa5, 0x68, 0xa6, 0x70,
0125         0xa8, 0xc1, 0xa9, 0xef, 0xaa, 0x92, 0xab, 0x04,
0126         0xac, 0x80, 0xad, 0x80, 0xae, 0x80, 0xaf, 0x80,
0127         0xb2, 0xf2, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x00,
0128         0xb6, 0xaf
0129     },
0130     (u8[]){
0131         0xbb, 0xae, 0xbc, 0x38, 0xbd, 0x39, 0xbe, 0x01,
0132         0xbf, 0x01, 0xc0, 0xe2, 0xc1, 0xc0, 0xc2, 0x01,
0133         0xc3, 0x4e, 0xc6, 0x85, 0xc7, 0x81, 0xc9, 0xe0,
0134         0xca, 0xe8, 0xcb, 0xf0, 0xcc, 0xd8, 0xcd, 0x93
0135     },
0136     (u8[]){
0137         0xd0, 0x21, 0xd1, 0x18, 0xd2, 0xe0, 0xd3, 0x01,
0138         0xd4, 0x28, 0xd5, 0x00
0139     }
0140 };
0141 
0142 static u8 c04[] = {0x04};
0143 static u8 dat_post1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
0144 static u8 dat_post2[] = "\x10\x10\xc1\x02";
0145 static u8 dat_post3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
0146 static u8 dat_post4[] = "\x10\x02\xc1\x06";
0147 static u8 dat_post5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
0148 static u8 dat_post6[] = "\x10\x10\xc1\x05";
0149 static u8 dat_post7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
0150 static u8 dat_post8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
0151 
0152 static struct validx tbl_init_post_alt[] = {
0153     {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff},
0154     {0x6003, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6001, 0x00ff},
0155     {0x6000, 0x801e},
0156     {0xffff, 0xffff},
0157     {0x6004, 0x001e}, {0x6000, 0x801e},
0158     {0xffff, 0xffff},
0159     {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
0160     {0xffff, 0xffff},
0161     {0x6004, 0x001e}, {0x6000, 0x801e},
0162     {0xffff, 0xffff},
0163     {0x6004, 0x001e}, {0x6012, 0x0003},
0164     {0xffff, 0xffff},
0165     {0x6000, 0x801e},
0166     {0xffff, 0xffff},
0167     {0x6004, 0x001e}, {0x6000, 0x801e},
0168     {0xffff, 0xffff},
0169     {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
0170     {0xffff, 0xffff},
0171     {0x6004, 0x001e}, {0x6000, 0x801e},
0172     {0xffff, 0xffff},
0173     {0x6004, 0x001e}, {0x6012, 0x0003},
0174     {0xffff, 0xffff},
0175     {0x6000, 0x801e},
0176     {0xffff, 0xffff},
0177     {0x6004, 0x001e}, {0x6000, 0x801e},
0178     {0xffff, 0xffff},
0179     {0x6004, 0x001e}, {0x6012, 0x0003},
0180 };
0181 
0182 static int  ov9655_init_at_startup(struct gspca_dev *gspca_dev);
0183 static int  ov9655_configure_alt(struct gspca_dev *gspca_dev);
0184 static int  ov9655_init_pre_alt(struct gspca_dev *gspca_dev);
0185 static int  ov9655_init_post_alt(struct gspca_dev *gspca_dev);
0186 static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev);
0187 static int  ov9655_camera_settings(struct gspca_dev *gspca_dev);
0188 /*==========================================================================*/
0189 
0190 void ov9655_init_settings(struct gspca_dev *gspca_dev)
0191 {
0192     struct sd *sd = (struct sd *) gspca_dev;
0193 
0194     sd->vcur.backlight  =   0;
0195     sd->vcur.brightness = 128;
0196     sd->vcur.sharpness  =   0;
0197     sd->vcur.contrast   =   0;
0198     sd->vcur.gamma      =   0;
0199     sd->vcur.hue        =   0;
0200     sd->vcur.saturation =   0;
0201     sd->vcur.whitebal   =   0;
0202 
0203     sd->vmax.backlight  =   0;
0204     sd->vmax.brightness = 255;
0205     sd->vmax.sharpness  =   0;
0206     sd->vmax.contrast   =   0;
0207     sd->vmax.gamma      =   0;
0208     sd->vmax.hue        =   0 + 1;
0209     sd->vmax.saturation =   0;
0210     sd->vmax.whitebal   =   0;
0211     sd->vmax.mirror     = 0;
0212     sd->vmax.flip       = 0;
0213     sd->vmax.AC50Hz     = 0;
0214 
0215     sd->dev_camera_settings = ov9655_camera_settings;
0216     sd->dev_init_at_startup = ov9655_init_at_startup;
0217     sd->dev_configure_alt   = ov9655_configure_alt;
0218     sd->dev_init_pre_alt    = ov9655_init_pre_alt;
0219     sd->dev_post_unset_alt  = ov9655_post_unset_alt;
0220 }
0221 
0222 /*==========================================================================*/
0223 
0224 static int ov9655_init_at_startup(struct gspca_dev *gspca_dev)
0225 {
0226     fetch_validx(gspca_dev, tbl_init_at_startup,
0227             ARRAY_SIZE(tbl_init_at_startup));
0228     fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
0229 /*  ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL);*/
0230 
0231     return 0;
0232 }
0233 
0234 static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev)
0235 {
0236     struct sd *sd = (struct sd *) gspca_dev;
0237 
0238     sd->vold.brightness = -1;
0239     sd->vold.hue = -1;
0240 
0241     fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
0242 
0243     ov9655_init_post_alt(gspca_dev);
0244 
0245     return 0;
0246 }
0247 
0248 static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
0249 {
0250     s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
0251     s32 n; /* reserved for FETCH functions */
0252     s32 i;
0253     u8 **tbl;
0254 
0255     ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
0256 
0257     tbl = (reso == IMAGE_640) ? tbl_640 : tbl_1280;
0258 
0259     ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
0260             tbl_length[0], tbl[0]);
0261     for (i = 1; i < 7; i++)
0262         ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200,
0263                 tbl_length[i], tbl[i]);
0264     ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
0265             tbl_length[7], tbl[7]);
0266 
0267     n = fetch_validx(gspca_dev, tbl_init_post_alt,
0268             ARRAY_SIZE(tbl_init_post_alt));
0269 
0270     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0271     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0272                     ARRAY_SIZE(tbl_init_post_alt), n);
0273     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0274     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0275                     ARRAY_SIZE(tbl_init_post_alt), n);
0276     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0277     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0278                     ARRAY_SIZE(tbl_init_post_alt), n);
0279     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0280     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0281                     ARRAY_SIZE(tbl_init_post_alt), n);
0282     ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
0283     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0284                     ARRAY_SIZE(tbl_init_post_alt), n);
0285 
0286     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0287     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0288                     ARRAY_SIZE(tbl_init_post_alt), n);
0289     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0290     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0291                     ARRAY_SIZE(tbl_init_post_alt), n);
0292     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0293     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0294                     ARRAY_SIZE(tbl_init_post_alt), n);
0295     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0296     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0297                     ARRAY_SIZE(tbl_init_post_alt), n);
0298     ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
0299     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0300                     ARRAY_SIZE(tbl_init_post_alt), n);
0301 
0302     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0303     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0304                     ARRAY_SIZE(tbl_init_post_alt), n);
0305     ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
0306     keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
0307                     ARRAY_SIZE(tbl_init_post_alt), n);
0308 
0309     ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post1);
0310 
0311     ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post2);
0312     ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post3);
0313 
0314     ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post4);
0315     ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post5);
0316 
0317     ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post6);
0318     ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post7);
0319 
0320     ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post8);
0321 
0322     ov9655_camera_settings(gspca_dev);
0323 
0324     return 0;
0325 }
0326 
0327 static int ov9655_configure_alt(struct gspca_dev *gspca_dev)
0328 {
0329     s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
0330 
0331     switch (reso) {
0332     case IMAGE_640:
0333         gspca_dev->alt = 1 + 1;
0334         break;
0335 
0336     default:
0337         gspca_dev->alt = 1 + 1;
0338         break;
0339     }
0340     return 0;
0341 }
0342 
0343 static int ov9655_camera_settings(struct gspca_dev *gspca_dev)
0344 {
0345     struct sd *sd = (struct sd *) gspca_dev;
0346 
0347     u8 dat_bright[] = "\x04\x00\x10\x7c\xa1\x00\x00\x70";
0348 
0349     s32 bright = sd->vcur.brightness;
0350     s32 hue    = sd->vcur.hue;
0351 
0352     if (bright != sd->vold.brightness) {
0353         sd->vold.brightness = bright;
0354         if (bright < 0 || bright > sd->vmax.brightness)
0355             bright = 0;
0356 
0357         dat_bright[3] = bright;
0358         ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_bright);
0359     }
0360 
0361     if (hue != sd->vold.hue) {
0362         sd->vold.hue = hue;
0363         sd->swapRB = (hue != 0);
0364     }
0365 
0366     return 0;
0367 }
0368 
0369 static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev)
0370 {
0371     ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
0372     ctrl_out(gspca_dev, 0x40, 1, 0x0061, 0x0000, 0, NULL);
0373 }