|
@@ -40,6 +40,7 @@ static int force_sensor = -1;
|
|
|
struct sd {
|
|
|
struct gspca_dev gspca_dev; /* !! must be the first item */
|
|
|
|
|
|
+ u8 brightness;
|
|
|
u8 contrast;
|
|
|
u8 gamma;
|
|
|
u8 autogain;
|
|
@@ -79,6 +80,8 @@ struct sd {
|
|
|
};
|
|
|
|
|
|
/* V4L2 controls supported by the driver */
|
|
|
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
|
|
|
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
|
|
|
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
|
|
|
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
|
|
|
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
|
|
@@ -91,6 +94,20 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
|
|
|
static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
|
|
|
|
|
|
static const struct ctrl sd_ctrls[] = {
|
|
|
+ {
|
|
|
+ {
|
|
|
+ .id = V4L2_CID_BRIGHTNESS,
|
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
|
+ .name = "Brightness",
|
|
|
+ .minimum = 0,
|
|
|
+ .maximum = 255,
|
|
|
+ .step = 1,
|
|
|
+#define BRIGHTNESS_DEF 128
|
|
|
+ .default_value = BRIGHTNESS_DEF,
|
|
|
+ },
|
|
|
+ .set = sd_setbrightness,
|
|
|
+ .get = sd_getbrightness,
|
|
|
+ },
|
|
|
{
|
|
|
{
|
|
|
.id = V4L2_CID_CONTRAST,
|
|
@@ -132,7 +149,7 @@ static const struct ctrl sd_ctrls[] = {
|
|
|
.set = sd_setautogain,
|
|
|
.get = sd_getautogain,
|
|
|
},
|
|
|
-#define LIGHTFREQ_IDX 3
|
|
|
+#define LIGHTFREQ_IDX 4
|
|
|
{
|
|
|
{
|
|
|
.id = V4L2_CID_POWER_LINE_FREQUENCY,
|
|
@@ -6011,9 +6028,12 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|
|
struct sd *sd = (struct sd *) gspca_dev;
|
|
|
struct usb_device *dev = gspca_dev->dev;
|
|
|
const u8 *Tgamma;
|
|
|
- int g, i, k, adj, gp;
|
|
|
+ int g, i, brightness, contrast, adj, gp1, gp2;
|
|
|
u8 gr[16];
|
|
|
- static const u8 delta_tb[16] = /* delta for contrast */
|
|
|
+ static const u8 delta_b[16] = /* delta for brightness */
|
|
|
+ {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d,
|
|
|
+ 0x1d, 0x1b, 0x1b, 0x1b, 0x19, 0x18, 0x18, 0x18};
|
|
|
+ static const u8 delta_c[16] = /* delta for contrast */
|
|
|
{0x2c, 0x1a, 0x12, 0x0c, 0x0a, 0x06, 0x06, 0x06,
|
|
|
0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02};
|
|
|
static const u8 gamma_tb[6][16] = {
|
|
@@ -6033,30 +6053,30 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|
|
|
|
|
Tgamma = gamma_tb[sd->gamma - 1];
|
|
|
|
|
|
- k = ((int) sd->contrast - 128); /* -128 / 128 */
|
|
|
+ contrast = ((int) sd->contrast - 128); /* -128 / 127 */
|
|
|
+ brightness = ((int) sd->brightness - 128); /* -128 / 92 */
|
|
|
adj = 0;
|
|
|
- gp = 0;
|
|
|
+ gp1 = gp2 = 0;
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
- g = Tgamma[i] - delta_tb[i] * k / 256 - adj / 2;
|
|
|
+ g = Tgamma[i] + delta_b[i] * brightness / 256
|
|
|
+ - delta_c[i] * contrast / 256 - adj / 2;
|
|
|
if (g > 0xff)
|
|
|
g = 0xff;
|
|
|
else if (g < 0)
|
|
|
g = 0;
|
|
|
reg_w(dev, g, 0x0120 + i); /* gamma */
|
|
|
- if (k > 0)
|
|
|
+ if (contrast > 0)
|
|
|
adj--;
|
|
|
- else
|
|
|
+ else if (contrast < 0)
|
|
|
adj++;
|
|
|
-
|
|
|
- if (i != 0) {
|
|
|
- if (gp == 0)
|
|
|
- gr[i - 1] = 0;
|
|
|
- else
|
|
|
- gr[i - 1] = g - gp;
|
|
|
- }
|
|
|
- gp = g;
|
|
|
+ if (i > 1)
|
|
|
+ gr[i - 1] = (g - gp2) / 2;
|
|
|
+ else if (i != 0)
|
|
|
+ gr[0] = gp1 == 0 ? 0 : (g - gp1);
|
|
|
+ gp2 = gp1;
|
|
|
+ gp1 = g;
|
|
|
}
|
|
|
- gr[15] = gr[14] / 2;
|
|
|
+ gr[15] = (0xff - gp2) / 2;
|
|
|
for (i = 0; i < 16; i++)
|
|
|
reg_w(dev, gr[i], 0x0130 + i); /* gradient */
|
|
|
}
|
|
@@ -6744,6 +6764,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|
|
cam->nmodes = ARRAY_SIZE(broken_vga_mode);
|
|
|
break;
|
|
|
}
|
|
|
+ sd->brightness = BRIGHTNESS_DEF;
|
|
|
sd->contrast = CONTRAST_DEF;
|
|
|
sd->gamma = gamma[sd->sensor];
|
|
|
sd->autogain = AUTOGAIN_DEF;
|
|
@@ -6954,6 +6975,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|
|
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
|
|
}
|
|
|
|
|
|
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
|
|
|
+{
|
|
|
+ struct sd *sd = (struct sd *) gspca_dev;
|
|
|
+
|
|
|
+ sd->brightness = val;
|
|
|
+ if (gspca_dev->streaming)
|
|
|
+ setcontrast(gspca_dev);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
|
|
|
+{
|
|
|
+ struct sd *sd = (struct sd *) gspca_dev;
|
|
|
+
|
|
|
+ *val = sd->brightness;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
|
|
|
{
|
|
|
struct sd *sd = (struct sd *) gspca_dev;
|