aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2010-01-04 13:54:59 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:10:28 -0500
commitfd18046fffc24b06c9820d9b540c518fc0e1b627 (patch)
tree021f96b7a37a7766a501a57f6792817963ae040f /drivers
parent878b35aedb930a31a72298b717a22990b6773a03 (diff)
V4L/DVB (13895): gspca - zc3xx: Fix the contrast control.
The previous calculation gave bad gamma tables. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/zc3xx.c110
1 files changed, 30 insertions, 80 deletions
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index e0dd0ea0588e..d217c042dee9 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -115,7 +115,7 @@ static struct ctrl sd_ctrls[] = {
115 .type = V4L2_CTRL_TYPE_INTEGER, 115 .type = V4L2_CTRL_TYPE_INTEGER,
116 .name = "Contrast", 116 .name = "Contrast",
117 .minimum = 0, 117 .minimum = 0,
118 .maximum = 256, 118 .maximum = 255,
119 .step = 1, 119 .step = 1,
120 .default_value = 128, 120 .default_value = 128,
121 }, 121 },
@@ -6053,105 +6053,55 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6053{ 6053{
6054 struct sd *sd = (struct sd *) gspca_dev; 6054 struct sd *sd = (struct sd *) gspca_dev;
6055 struct usb_device *dev = gspca_dev->dev; 6055 struct usb_device *dev = gspca_dev->dev;
6056 const __u8 *Tgamma, *Tgradient; 6056 const __u8 *Tgamma;
6057 int g, i, k; 6057 int g, i, k, adj, gp;
6058 static const __u8 kgamma_tb[16] = /* delta for contrast */ 6058 u8 gr[16];
6059 static const u8 delta_tb[16] = /* delta for contrast */
6059 {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, 6060 {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08,
6060 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; 6061 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
6061 static const __u8 kgrad_tb[16] = 6062 static const u8 gamma_tb[6][16] = {
6062 {0x1b, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00,
6063 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x04};
6064 static const __u8 Tgamma_1[16] =
6065 {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f, 6063 {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f,
6066 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff}; 6064 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff},
6067 static const __u8 Tgradient_1[16] =
6068 {0x00, 0x01, 0x05, 0x0b, 0x10, 0x15, 0x18, 0x1a,
6069 0x1a, 0x18, 0x16, 0x14, 0x12, 0x0f, 0x0d, 0x06};
6070 static const __u8 Tgamma_2[16] =
6071 {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c, 6065 {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c,
6072 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff}; 6066 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff},
6073 static const __u8 Tgradient_2[16] =
6074 {0x05, 0x0f, 0x16, 0x1a, 0x19, 0x19, 0x17, 0x15,
6075 0x12, 0x10, 0x0e, 0x0b, 0x09, 0x08, 0x06, 0x03};
6076 static const __u8 Tgamma_3[16] =
6077 {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac, 6067 {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac,
6078 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff}; 6068 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff},
6079 static const __u8 Tgradient_3[16] =
6080 {0x0c, 0x16, 0x1b, 0x1c, 0x19, 0x18, 0x15, 0x12,
6081 0x10, 0x0d, 0x0b, 0x09, 0x08, 0x06, 0x05, 0x03};
6082 static const __u8 Tgamma_4[16] =
6083 {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 6069 {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
6084 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff}; 6070 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff},
6085 static const __u8 Tgradient_4[16] =
6086 {0x26, 0x22, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0d,
6087 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02};
6088 static const __u8 Tgamma_5[16] =
6089 {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2, 6071 {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2,
6090 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff}; 6072 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff},
6091 static const __u8 Tgradient_5[16] =
6092 {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b,
6093 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02};
6094 static const __u8 Tgamma_6[16] = /* ?? was gamma 5 */
6095 {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, 6073 {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3,
6096 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}; 6074 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff},
6097 static const __u8 Tgradient_6[16] =
6098 {0x18, 0x20, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0e,
6099 0x0b, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01};
6100 static const __u8 *gamma_tb[] = {
6101 NULL, Tgamma_1, Tgamma_2,
6102 Tgamma_3, Tgamma_4, Tgamma_5, Tgamma_6
6103 };
6104 static const __u8 *gradient_tb[] = {
6105 NULL, Tgradient_1, Tgradient_2,
6106 Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6
6107 }; 6075 };
6108#ifdef GSPCA_DEBUG
6109 __u8 v[16];
6110#endif
6111 6076
6112 Tgamma = gamma_tb[sd->gamma]; 6077 Tgamma = gamma_tb[sd->gamma - 1];
6113 Tgradient = gradient_tb[sd->gamma];
6114 6078
6115 k = (sd->contrast - 128) /* -128 / 128 */ 6079 k = ((int) sd->contrast - 128); /* -128 / 128 */
6116 * Tgamma[0]; 6080 adj = 0;
6117 PDEBUG(D_CONF, "gamma:%d contrast:%d gamma coeff: %d/128", 6081 gp = 0;
6118 sd->gamma, sd->contrast, k);
6119 for (i = 0; i < 16; i++) { 6082 for (i = 0; i < 16; i++) {
6120 g = Tgamma[i] + kgamma_tb[i] * k / 128; 6083 g = Tgamma[i] - delta_tb[i] * k / 128 - adj / 2;
6121 if (g > 0xff) 6084 if (g > 0xff)
6122 g = 0xff; 6085 g = 0xff;
6123 else if (g <= 0) 6086 else if (g <= 0)
6124 g = 1; 6087 g = 1;
6125 reg_w(dev, g, 0x0120 + i); /* gamma */ 6088 reg_w(dev, g, 0x0120 + i); /* gamma */
6126#ifdef GSPCA_DEBUG 6089 if (k > 0)
6127 if (gspca_debug & D_CONF) 6090 adj--;
6128 v[i] = g; 6091 else
6129#endif 6092 adj++;
6130 } 6093
6131 PDEBUG(D_CONF, "tb: %02x %02x %02x %02x %02x %02x %02x %02x", 6094 if (i != 0) {
6132 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); 6095 if (gp == 0)
6133 PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", 6096 gr[i - 1] = 0;
6134 v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
6135 for (i = 0; i < 16; i++) {
6136 g = Tgradient[i] - kgrad_tb[i] * k / 128;
6137 if (g > 0xff)
6138 g = 0xff;
6139 else if (g <= 0) {
6140 if (i != 15)
6141 g = 0;
6142 else 6097 else
6143 g = 1; 6098 gr[i - 1] = g - gp;
6144 } 6099 }
6145 reg_w(dev, g, 0x0130 + i); /* gradient */ 6100 gp = g;
6146#ifdef GSPCA_DEBUG
6147 if (gspca_debug & D_CONF)
6148 v[i] = g;
6149#endif
6150 } 6101 }
6151 PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", 6102 gr[15] = gr[14] / 2;
6152 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); 6103 for (i = 0; i < 16; i++)
6153 PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", 6104 reg_w(dev, gr[i], 0x0130 + i); /* gradient */
6154 v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
6155} 6105}
6156 6106
6157static void setquality(struct gspca_dev *gspca_dev) 6107static void setquality(struct gspca_dev *gspca_dev)