~ubuntu-branches/ubuntu/lucid/linux-rt/lucid

« back to all changes in this revision

Viewing changes to drivers/media/video/gspca/sunplus.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2009-08-05 23:00:52 UTC
  • Revision ID: james.westby@ubuntu.com-20090805230052-7xedvqcyk9dnnxb2
Tags: 2.6.31-1.1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
struct sd {
33
33
        struct gspca_dev gspca_dev;     /* !! must be the first item */
34
34
 
35
 
        __u8 packet[ISO_MAX_SIZE + 128];
36
 
                                /* !! no more than 128 ff in an ISO packet */
37
 
 
38
35
        unsigned char brightness;
39
36
        unsigned char contrast;
40
37
        unsigned char colors;
41
38
        unsigned char autogain;
 
39
        u8 quality;
 
40
#define QUALITY_MIN 70
 
41
#define QUALITY_MAX 95
 
42
#define QUALITY_DEF 85
42
43
 
43
 
        char qindex;
44
44
        char bridge;
45
45
#define BRIDGE_SPCA504 0
46
46
#define BRIDGE_SPCA504B 1
52
52
#define LogitechClickSmart420 2
53
53
#define LogitechClickSmart820 3
54
54
#define MegapixV4 4
 
55
 
 
56
        u8 *jpeg_hdr;
55
57
};
56
58
 
57
59
/* V4L2 controls supported by the driver */
812
814
        struct cam *cam;
813
815
 
814
816
        cam = &gspca_dev->cam;
815
 
        cam->epaddr = 0x01;
816
817
 
817
818
        sd->bridge = id->driver_info >> 8;
818
819
        sd->subtype = id->driver_info;
850
851
                cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
851
852
                break;
852
853
        }
853
 
        sd->qindex = 5;                 /* set the quantization table */
854
854
        sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
855
855
        sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
856
856
        sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
 
857
        sd->quality = QUALITY_DEF;
857
858
        return 0;
858
859
}
859
860
 
970
971
        __u8 i;
971
972
        __u8 info[6];
972
973
 
 
974
        /* create the JPEG header */
 
975
        sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
 
976
        jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
 
977
                        0x22);          /* JPEG 411 */
 
978
        jpeg_set_qual(sd->jpeg_hdr, sd->quality);
 
979
 
973
980
        if (sd->bridge == BRIDGE_SPCA504B)
974
981
                spca504B_setQtable(gspca_dev);
975
982
        spca504B_SetSizeType(gspca_dev);
1079
1086
        }
1080
1087
}
1081
1088
 
 
1089
static void sd_stop0(struct gspca_dev *gspca_dev)
 
1090
{
 
1091
        struct sd *sd = (struct sd *) gspca_dev;
 
1092
 
 
1093
        kfree(sd->jpeg_hdr);
 
1094
}
 
1095
 
1082
1096
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1083
1097
                        struct gspca_frame *frame,      /* target */
1084
1098
                        __u8 *data,                     /* isoc packet */
1086
1100
{
1087
1101
        struct sd *sd = (struct sd *) gspca_dev;
1088
1102
        int i, sof = 0;
1089
 
        unsigned char *s, *d;
1090
1103
        static unsigned char ffd9[] = {0xff, 0xd9};
1091
1104
 
1092
1105
/* frames are jpeg 4.1.1 without 0xff escape */
1155
1168
                                        ffd9, 2);
1156
1169
 
1157
1170
                /* put the JPEG header in the new frame */
1158
 
                jpeg_put_header(gspca_dev, frame,
1159
 
                                ((struct sd *) gspca_dev)->qindex,
1160
 
                                0x22);
 
1171
                gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
 
1172
                        sd->jpeg_hdr, JPEG_HDR_SZ);
1161
1173
        }
1162
1174
 
1163
1175
        /* add 0x00 after 0xff */
1164
 
        for (i = len; --i >= 0; )
1165
 
                if (data[i] == 0xff)
1166
 
                        break;
1167
 
        if (i < 0) {                    /* no 0xff */
1168
 
                gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1169
 
                return;
1170
 
        }
1171
 
        s = data;
1172
 
        d = sd->packet;
1173
 
        for (i = 0; i < len; i++) {
1174
 
                *d++ = *s++;
1175
 
                if (s[-1] == 0xff)
1176
 
                        *d++ = 0x00;
1177
 
        }
1178
 
        gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1179
 
                        sd->packet, d - sd->packet);
 
1176
        i = 0;
 
1177
        do {
 
1178
                if (data[i] == 0xff) {
 
1179
                        gspca_frame_add(gspca_dev, INTER_PACKET, frame,
 
1180
                                        data, i + 1);
 
1181
                        len -= i;
 
1182
                        data += i;
 
1183
                        *data = 0x00;
 
1184
                        i = 0;
 
1185
                }
 
1186
                i++;
 
1187
        } while (i < len);
 
1188
        gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1180
1189
}
1181
1190
 
1182
1191
static void setbrightness(struct gspca_dev *gspca_dev)
1198
1207
        }
1199
1208
}
1200
1209
 
1201
 
static void getbrightness(struct gspca_dev *gspca_dev)
1202
 
{
1203
 
        struct sd *sd = (struct sd *) gspca_dev;
1204
 
        __u16 brightness = 0;
1205
 
 
1206
 
        switch (sd->bridge) {
1207
 
        default:
1208
 
/*      case BRIDGE_SPCA533: */
1209
 
/*      case BRIDGE_SPCA504B: */
1210
 
/*      case BRIDGE_SPCA504: */
1211
 
/*      case BRIDGE_SPCA504C: */
1212
 
                brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
1213
 
                break;
1214
 
        case BRIDGE_SPCA536:
1215
 
                brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
1216
 
                break;
1217
 
        }
1218
 
        sd->brightness = ((brightness & 0xff) - 128) % 255;
1219
 
}
1220
 
 
1221
1210
static void setcontrast(struct gspca_dev *gspca_dev)
1222
1211
{
1223
1212
        struct sd *sd = (struct sd *) gspca_dev;
1237
1226
        }
1238
1227
}
1239
1228
 
1240
 
static void getcontrast(struct gspca_dev *gspca_dev)
1241
 
{
1242
 
        struct sd *sd = (struct sd *) gspca_dev;
1243
 
 
1244
 
        switch (sd->bridge) {
1245
 
        default:
1246
 
/*      case BRIDGE_SPCA533: */
1247
 
/*      case BRIDGE_SPCA504B: */
1248
 
/*      case BRIDGE_SPCA504: */
1249
 
/*      case BRIDGE_SPCA504C: */
1250
 
                sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
1251
 
                break;
1252
 
        case BRIDGE_SPCA536:
1253
 
                sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
1254
 
                break;
1255
 
        }
1256
 
}
1257
 
 
1258
1229
static void setcolors(struct gspca_dev *gspca_dev)
1259
1230
{
1260
1231
        struct sd *sd = (struct sd *) gspca_dev;
1274
1245
        }
1275
1246
}
1276
1247
 
1277
 
static void getcolors(struct gspca_dev *gspca_dev)
1278
 
{
1279
 
        struct sd *sd = (struct sd *) gspca_dev;
1280
 
 
1281
 
        switch (sd->bridge) {
1282
 
        default:
1283
 
/*      case BRIDGE_SPCA533: */
1284
 
/*      case BRIDGE_SPCA504B: */
1285
 
/*      case BRIDGE_SPCA504: */
1286
 
/*      case BRIDGE_SPCA504C: */
1287
 
                sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
1288
 
                break;
1289
 
        case BRIDGE_SPCA536:
1290
 
                sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
1291
 
                break;
1292
 
        }
1293
 
}
1294
 
 
1295
1248
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1296
1249
{
1297
1250
        struct sd *sd = (struct sd *) gspca_dev;
1306
1259
{
1307
1260
        struct sd *sd = (struct sd *) gspca_dev;
1308
1261
 
1309
 
        getbrightness(gspca_dev);
1310
1262
        *val = sd->brightness;
1311
1263
        return 0;
1312
1264
}
1325
1277
{
1326
1278
        struct sd *sd = (struct sd *) gspca_dev;
1327
1279
 
1328
 
        getcontrast(gspca_dev);
1329
1280
        *val = sd->contrast;
1330
1281
        return 0;
1331
1282
}
1344
1295
{
1345
1296
        struct sd *sd = (struct sd *) gspca_dev;
1346
1297
 
1347
 
        getcolors(gspca_dev);
1348
1298
        *val = sd->colors;
1349
1299
        return 0;
1350
1300
}
1365
1315
        return 0;
1366
1316
}
1367
1317
 
 
1318
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
 
1319
                        struct v4l2_jpegcompression *jcomp)
 
1320
{
 
1321
        struct sd *sd = (struct sd *) gspca_dev;
 
1322
 
 
1323
        if (jcomp->quality < QUALITY_MIN)
 
1324
                sd->quality = QUALITY_MIN;
 
1325
        else if (jcomp->quality > QUALITY_MAX)
 
1326
                sd->quality = QUALITY_MAX;
 
1327
        else
 
1328
                sd->quality = jcomp->quality;
 
1329
        if (gspca_dev->streaming)
 
1330
                jpeg_set_qual(sd->jpeg_hdr, sd->quality);
 
1331
        return 0;
 
1332
}
 
1333
 
 
1334
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
 
1335
                        struct v4l2_jpegcompression *jcomp)
 
1336
{
 
1337
        struct sd *sd = (struct sd *) gspca_dev;
 
1338
 
 
1339
        memset(jcomp, 0, sizeof *jcomp);
 
1340
        jcomp->quality = sd->quality;
 
1341
        jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
 
1342
                        | V4L2_JPEG_MARKER_DQT;
 
1343
        return 0;
 
1344
}
 
1345
 
1368
1346
/* sub-driver description */
1369
1347
static const struct sd_desc sd_desc = {
1370
1348
        .name = MODULE_NAME,
1374
1352
        .init = sd_init,
1375
1353
        .start = sd_start,
1376
1354
        .stopN = sd_stopN,
 
1355
        .stop0 = sd_stop0,
1377
1356
        .pkt_scan = sd_pkt_scan,
 
1357
        .get_jcomp = sd_get_jcomp,
 
1358
        .set_jcomp = sd_set_jcomp,
1378
1359
};
1379
1360
 
1380
1361
/* -- module initialisation -- */
1465
1446
/* -- module insert / remove -- */
1466
1447
static int __init sd_mod_init(void)
1467
1448
{
1468
 
        if (usb_register(&sd_driver) < 0)
1469
 
                return -1;
 
1449
        int ret;
 
1450
        ret = usb_register(&sd_driver);
 
1451
        if (ret < 0)
 
1452
                return ret;
1470
1453
        PDEBUG(D_PROBE, "registered");
1471
1454
        return 0;
1472
1455
}