Commit a9dfc01d authored by Jean-François Moine's avatar Jean-François Moine Committed by Mauro Carvalho Chehab

V4L/DVB: gspca - zc3xx: Add back the brightness control

This patch also changes a bit the contrast control.
Signed-off-by: default avatarJean-François Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 93604b0f
...@@ -40,6 +40,7 @@ static int force_sensor = -1; ...@@ -40,6 +40,7 @@ static int force_sensor = -1;
struct sd { struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */ struct gspca_dev gspca_dev; /* !! must be the first item */
u8 brightness;
u8 contrast; u8 contrast;
u8 gamma; u8 gamma;
u8 autogain; u8 autogain;
...@@ -79,6 +80,8 @@ struct sd { ...@@ -79,6 +80,8 @@ struct sd {
}; };
/* V4L2 controls supported by the driver */ /* 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_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getcontrast(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); 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); ...@@ -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 int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
static const struct ctrl sd_ctrls[] = { 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, .id = V4L2_CID_CONTRAST,
...@@ -132,7 +149,7 @@ static const struct ctrl sd_ctrls[] = { ...@@ -132,7 +149,7 @@ static const struct ctrl sd_ctrls[] = {
.set = sd_setautogain, .set = sd_setautogain,
.get = sd_getautogain, .get = sd_getautogain,
}, },
#define LIGHTFREQ_IDX 3 #define LIGHTFREQ_IDX 4
{ {
{ {
.id = V4L2_CID_POWER_LINE_FREQUENCY, .id = V4L2_CID_POWER_LINE_FREQUENCY,
...@@ -6011,9 +6028,12 @@ static void setcontrast(struct gspca_dev *gspca_dev) ...@@ -6011,9 +6028,12 @@ static void setcontrast(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev; struct usb_device *dev = gspca_dev->dev;
const u8 *Tgamma; const u8 *Tgamma;
int g, i, k, adj, gp; int g, i, brightness, contrast, adj, gp1, gp2;
u8 gr[16]; 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, {0x2c, 0x1a, 0x12, 0x0c, 0x0a, 0x06, 0x06, 0x06,
0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02}; 0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02};
static const u8 gamma_tb[6][16] = { static const u8 gamma_tb[6][16] = {
...@@ -6033,30 +6053,30 @@ static void setcontrast(struct gspca_dev *gspca_dev) ...@@ -6033,30 +6053,30 @@ static void setcontrast(struct gspca_dev *gspca_dev)
Tgamma = gamma_tb[sd->gamma - 1]; 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; adj = 0;
gp = 0; gp1 = gp2 = 0;
for (i = 0; i < 16; i++) { 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) if (g > 0xff)
g = 0xff; g = 0xff;
else if (g < 0) else if (g < 0)
g = 0; g = 0;
reg_w(dev, g, 0x0120 + i); /* gamma */ reg_w(dev, g, 0x0120 + i); /* gamma */
if (k > 0) if (contrast > 0)
adj--; adj--;
else else if (contrast < 0)
adj++; adj++;
if (i > 1)
if (i != 0) { gr[i - 1] = (g - gp2) / 2;
if (gp == 0) else if (i != 0)
gr[i - 1] = 0; gr[0] = gp1 == 0 ? 0 : (g - gp1);
else gp2 = gp1;
gr[i - 1] = g - gp; gp1 = g;
}
gp = g;
} }
gr[15] = gr[14] / 2; gr[15] = (0xff - gp2) / 2;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
reg_w(dev, gr[i], 0x0130 + i); /* gradient */ reg_w(dev, gr[i], 0x0130 + i); /* gradient */
} }
...@@ -6744,6 +6764,7 @@ static int sd_config(struct gspca_dev *gspca_dev, ...@@ -6744,6 +6764,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->nmodes = ARRAY_SIZE(broken_vga_mode); cam->nmodes = ARRAY_SIZE(broken_vga_mode);
break; break;
} }
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF; sd->contrast = CONTRAST_DEF;
sd->gamma = gamma[sd->sensor]; sd->gamma = gamma[sd->sensor];
sd->autogain = AUTOGAIN_DEF; sd->autogain = AUTOGAIN_DEF;
...@@ -6954,6 +6975,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ...@@ -6954,6 +6975,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 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) static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment