diff options
author | Jean-François Moine <moinejf@free.fr> | 2010-06-04 05:21:48 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-02 13:06:12 -0400 |
commit | a9dfc01d206b3bc807814751cb2b4e0704f4a2f7 (patch) | |
tree | 24b342169f6ccb3c8ab7a645e22c24959696f9c1 /drivers/media/video | |
parent | 93604b0fdde324da0a4581efaa584a036554b36a (diff) |
V4L/DVB: gspca - zc3xx: Add back the brightness control
This patch also changes a bit the contrast control.
Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/gspca/zc3xx.c | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 73c4ebbcbfb1..1420eb2a9d38 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -40,6 +40,7 @@ static int force_sensor = -1; | |||
40 | struct sd { | 40 | struct sd { |
41 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 41 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
42 | 42 | ||
43 | u8 brightness; | ||
43 | u8 contrast; | 44 | u8 contrast; |
44 | u8 gamma; | 45 | u8 gamma; |
45 | u8 autogain; | 46 | u8 autogain; |
@@ -79,6 +80,8 @@ struct sd { | |||
79 | }; | 80 | }; |
80 | 81 | ||
81 | /* V4L2 controls supported by the driver */ | 82 | /* V4L2 controls supported by the driver */ |
83 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
82 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | 85 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); |
83 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 86 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
84 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 87 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); |
@@ -93,6 +96,20 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | |||
93 | static const struct ctrl sd_ctrls[] = { | 96 | static const struct ctrl sd_ctrls[] = { |
94 | { | 97 | { |
95 | { | 98 | { |
99 | .id = V4L2_CID_BRIGHTNESS, | ||
100 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
101 | .name = "Brightness", | ||
102 | .minimum = 0, | ||
103 | .maximum = 255, | ||
104 | .step = 1, | ||
105 | #define BRIGHTNESS_DEF 128 | ||
106 | .default_value = BRIGHTNESS_DEF, | ||
107 | }, | ||
108 | .set = sd_setbrightness, | ||
109 | .get = sd_getbrightness, | ||
110 | }, | ||
111 | { | ||
112 | { | ||
96 | .id = V4L2_CID_CONTRAST, | 113 | .id = V4L2_CID_CONTRAST, |
97 | .type = V4L2_CTRL_TYPE_INTEGER, | 114 | .type = V4L2_CTRL_TYPE_INTEGER, |
98 | .name = "Contrast", | 115 | .name = "Contrast", |
@@ -132,7 +149,7 @@ static const struct ctrl sd_ctrls[] = { | |||
132 | .set = sd_setautogain, | 149 | .set = sd_setautogain, |
133 | .get = sd_getautogain, | 150 | .get = sd_getautogain, |
134 | }, | 151 | }, |
135 | #define LIGHTFREQ_IDX 3 | 152 | #define LIGHTFREQ_IDX 4 |
136 | { | 153 | { |
137 | { | 154 | { |
138 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 155 | .id = V4L2_CID_POWER_LINE_FREQUENCY, |
@@ -6011,9 +6028,12 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
6011 | struct sd *sd = (struct sd *) gspca_dev; | 6028 | struct sd *sd = (struct sd *) gspca_dev; |
6012 | struct usb_device *dev = gspca_dev->dev; | 6029 | struct usb_device *dev = gspca_dev->dev; |
6013 | const u8 *Tgamma; | 6030 | const u8 *Tgamma; |
6014 | int g, i, k, adj, gp; | 6031 | int g, i, brightness, contrast, adj, gp1, gp2; |
6015 | u8 gr[16]; | 6032 | u8 gr[16]; |
6016 | static const u8 delta_tb[16] = /* delta for contrast */ | 6033 | static const u8 delta_b[16] = /* delta for brightness */ |
6034 | {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d, | ||
6035 | 0x1d, 0x1b, 0x1b, 0x1b, 0x19, 0x18, 0x18, 0x18}; | ||
6036 | static const u8 delta_c[16] = /* delta for contrast */ | ||
6017 | {0x2c, 0x1a, 0x12, 0x0c, 0x0a, 0x06, 0x06, 0x06, | 6037 | {0x2c, 0x1a, 0x12, 0x0c, 0x0a, 0x06, 0x06, 0x06, |
6018 | 0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02}; | 6038 | 0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02}; |
6019 | static const u8 gamma_tb[6][16] = { | 6039 | static const u8 gamma_tb[6][16] = { |
@@ -6033,30 +6053,30 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
6033 | 6053 | ||
6034 | Tgamma = gamma_tb[sd->gamma - 1]; | 6054 | Tgamma = gamma_tb[sd->gamma - 1]; |
6035 | 6055 | ||
6036 | k = ((int) sd->contrast - 128); /* -128 / 128 */ | 6056 | contrast = ((int) sd->contrast - 128); /* -128 / 127 */ |
6057 | brightness = ((int) sd->brightness - 128); /* -128 / 92 */ | ||
6037 | adj = 0; | 6058 | adj = 0; |
6038 | gp = 0; | 6059 | gp1 = gp2 = 0; |
6039 | for (i = 0; i < 16; i++) { | 6060 | for (i = 0; i < 16; i++) { |
6040 | g = Tgamma[i] - delta_tb[i] * k / 256 - adj / 2; | 6061 | g = Tgamma[i] + delta_b[i] * brightness / 256 |
6062 | - delta_c[i] * contrast / 256 - adj / 2; | ||
6041 | if (g > 0xff) | 6063 | if (g > 0xff) |
6042 | g = 0xff; | 6064 | g = 0xff; |
6043 | else if (g < 0) | 6065 | else if (g < 0) |
6044 | g = 0; | 6066 | g = 0; |
6045 | reg_w(dev, g, 0x0120 + i); /* gamma */ | 6067 | reg_w(dev, g, 0x0120 + i); /* gamma */ |
6046 | if (k > 0) | 6068 | if (contrast > 0) |
6047 | adj--; | 6069 | adj--; |
6048 | else | 6070 | else if (contrast < 0) |
6049 | adj++; | 6071 | adj++; |
6050 | 6072 | if (i > 1) | |
6051 | if (i != 0) { | 6073 | gr[i - 1] = (g - gp2) / 2; |
6052 | if (gp == 0) | 6074 | else if (i != 0) |
6053 | gr[i - 1] = 0; | 6075 | gr[0] = gp1 == 0 ? 0 : (g - gp1); |
6054 | else | 6076 | gp2 = gp1; |
6055 | gr[i - 1] = g - gp; | 6077 | gp1 = g; |
6056 | } | ||
6057 | gp = g; | ||
6058 | } | 6078 | } |
6059 | gr[15] = gr[14] / 2; | 6079 | gr[15] = (0xff - gp2) / 2; |
6060 | for (i = 0; i < 16; i++) | 6080 | for (i = 0; i < 16; i++) |
6061 | reg_w(dev, gr[i], 0x0130 + i); /* gradient */ | 6081 | reg_w(dev, gr[i], 0x0130 + i); /* gradient */ |
6062 | } | 6082 | } |
@@ -6744,6 +6764,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
6744 | cam->nmodes = ARRAY_SIZE(broken_vga_mode); | 6764 | cam->nmodes = ARRAY_SIZE(broken_vga_mode); |
6745 | break; | 6765 | break; |
6746 | } | 6766 | } |
6767 | sd->brightness = BRIGHTNESS_DEF; | ||
6747 | sd->contrast = CONTRAST_DEF; | 6768 | sd->contrast = CONTRAST_DEF; |
6748 | sd->gamma = gamma[sd->sensor]; | 6769 | sd->gamma = gamma[sd->sensor]; |
6749 | sd->autogain = AUTOGAIN_DEF; | 6770 | sd->autogain = AUTOGAIN_DEF; |
@@ -6954,6 +6975,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
6954 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 6975 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
6955 | } | 6976 | } |
6956 | 6977 | ||
6978 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
6979 | { | ||
6980 | struct sd *sd = (struct sd *) gspca_dev; | ||
6981 | |||
6982 | sd->brightness = val; | ||
6983 | if (gspca_dev->streaming) | ||
6984 | setcontrast(gspca_dev); | ||
6985 | return 0; | ||
6986 | } | ||
6987 | |||
6988 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
6989 | { | ||
6990 | struct sd *sd = (struct sd *) gspca_dev; | ||
6991 | |||
6992 | *val = sd->brightness; | ||
6993 | return 0; | ||
6994 | } | ||
6995 | |||
6957 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | 6996 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) |
6958 | { | 6997 | { |
6959 | struct sd *sd = (struct sd *) gspca_dev; | 6998 | struct sd *sd = (struct sd *) gspca_dev; |