I do some investigation of function set_optical_parameters as I transfer 
execution of instruction into user space and disassemble the program. 
For reference I use cycle execution of i486 worst case (is possible for 
some instruction to not get the correct cycles but as estimation is good 
start).
Possible optimization:
1. Define __u8 optical_parameters[21] as global static - I try but 
always the values is not save on this global static array - What I do 
wrong ??? Pleas for some idea about __u8 optical_parameters[21] (see in 
patch what i want to do with this array ) ??? For first time global 
initialization of array is not work for me ???
If this array going into global space as static the functions can split 
into small parts for Brightness, Contrast, HUE-Saturation

2. Possible optimization of calculation multiplying and dividing I can 
replace with logic operation and reanalyze execution time.

3. As total execution calculation of RGB matrix parameters is not get 
too much microprocessor time (near to sn9c20x_set_gamma - too many 
multiplication and dividing ). Maybe other often call code get this time.



--~--~---------~--~----~------------~-------~--~----~
Lets make microdia webcams plug'n play, (currently plug'n pray)
To post to this group, send email to [email protected]
Visit us online https://groups.google.com/group/microdia
-~----------~----~----~----~------~----~------~--~---

diff --git a/sn9c20x-bridge.c b/sn9c20x-bridge.c
index f5d77b8..b4c3212 100644
--- a/sn9c20x-bridge.c
+++ b/sn9c20x-bridge.c
@@ -30,8 +30,312 @@
 #include "sn9c20x.h"
 #include "sn9c20x-bridge.h"
 
+
+
+/**
+ * @var RX
+ *   Coordinate X aray for eliptic HSV corrections, conditionaly Red pixel
+ */
+const int RX[] = {41,  44,  46,  48,  50,  52,  54,  56,
+               58,  60,  62,  64,  66,  68,  70,  72,
+               74,  76,  78,  80,  81,  83,  85,  87,
+               88,  90,  92,  93,  95,  97,  98, 100,
+               101, 102, 104, 105, 107, 108, 109, 110,
+               112, 113, 114, 115, 116, 117, 118, 119,
+               120, 121, 122, 123, 123, 124, 125, 125,
+               126, 127, 127, 128, 128, 129, 129, 129,
+               130, 130, 130, 130, 131, 131, 131, 131,
+               131, 131, 131, 131, 130, 130, 130, 130,
+               129, 129, 129, 128, 128, 127, 127, 126,
+               125, 125, 124, 123, 122, 122, 121, 120,
+               119, 118, 117, 116, 115, 114, 112, 111,
+               110, 109, 107, 106, 105, 103, 102, 101,
+               99,  98,  96,  94,  93,  91,  90,  88,
+               86,  84,  83,  81,  79,  77,  75,  74,
+               72,  70,  68,  66,  64,  62,  60,  58,
+               56,  54,  52,  49,  47,  45,  43,  41,
+               39,  36,  34,  32,  30,  28,  25,  23,
+               21,  19,  16,  14,  12,   9,   7,   5,
+               3,   0,  -1,  -3,  -6,  -8, -10, -12,
+               -15, -17, -19, -22, -24, -26, -28, -30,
+               -33, -35, -37, -39, -41, -44, -46, -48,
+               -50, -52, -54, -56, -58, -60, -62, -64,
+               -66, -68, -70, -72, -74, -76, -78, -80,
+               -81, -83, -85, -87, -88, -90, -92, -93,
+               -95, -97, -98, -100, -101, -102, -104, -105,
+               -107, -108, -109, -110, -112, -113, -114, -115,
+               -116, -117, -118, -119, -120, -121, -122, -123,
+               -123, -124, -125, -125, -126, -127, -127, -128,
+               -128, -128, -128, -128, -128, -128, -128, -128,
+               -128, -128, -128, -128, -128, -128, -128, -128,
+               -128, -128, -128, -128, -128, -128, -128, -128,
+               -128, -127, -127, -126, -125, -125, -124, -123,
+               -122, -122, -121, -120, -119, -118, -117, -116,
+               -115, -114, -112, -111, -110, -109, -107, -106,
+               -105, -103, -102, -101, -99, -98, -96, -94,
+               -93, -91, -90, -88, -86, -84, -83, -81,
+               -79, -77, -75, -74, -72, -70, -68, -66,
+               -64, -62, -60, -58, -56, -54, -52, -49,
+               -47, -45, -43, -41, -39, -36, -34, -32,
+               -30, -28, -25, -23, -21, -19, -16, -14,
+               -12,  -9,  -7,  -5,  -3,   0,   1,   3,
+               6,   8,  10,  12,  15,  17,  19,  22,
+               24,  26,  28,  30,  33,  35,  37,  39, 41};
+
+/**
+ * @var RY
+ *   Coordinate Y aray for eliptic HSV corrections, conditionaly Red pixel
+ */
+const int RY[] = {     82,  80,  78,  76,  74,  73,  71,  69,
+               67,  65,  63,  61,  58,  56,  54,  52,
+               50,  48,  46,  44,  41,  39,  37,  35,
+               32,  30,  28,  26,  23,  21,  19,  16,
+               14,  12,  10,   7,   5,   3,   0,  -1,
+               -3,  -6,  -8, -10, -13, -15, -17, -19,
+               -22, -24, -26, -29, -31, -33, -35, -38,
+               -40, -42, -44, -46, -48, -51, -53, -55,
+               -57, -59, -61, -63, -65, -67, -69, -71,
+               -73, -75, -77, -79, -81, -82, -84, -86,
+               -88, -89, -91, -93, -94, -96, -98, -99,
+               -101, -102, -104, -105, -106, -108, -109, -110,
+               -112, -113, -114, -115, -116, -117, -119, -120,
+               -120, -121, -122, -123, -124, -125, -126, -126,
+               -127, -128, -128, -128, -128, -128, -128, -128,
+               -128, -128, -128, -128, -128, -128, -128, -128,
+               -128, -128, -128, -128, -128, -128, -128, -128,
+               -128, -128, -128, -128, -128, -128, -128, -128,
+               -127, -127, -126, -125, -125, -124, -123, -122,
+               -121, -120, -119, -118, -117, -116, -115, -114,
+               -113, -111, -110, -109, -107, -106, -105, -103,
+               -102, -100, -99, -97, -96, -94, -92, -91,
+               -89, -87, -85, -84, -82, -80, -78, -76,
+               -74, -73, -71, -69, -67, -65, -63, -61,
+               -58, -56, -54, -52, -50, -48, -46, -44,
+               -41, -39, -37, -35, -32, -30, -28, -26,
+               -23, -21, -19, -16, -14, -12, -10,  -7,
+               -5,  -3,   0,   1,   3,   6,   8,  10,
+               13,  15,  17,  19,  22,  24,  26,  29,
+               31,  33,  35,  38,  40,  42,  44,  46,
+               48,  51,  53,  55,  57,  59,  61,  63,
+               65,  67,  69,  71,  73,  75,  77,  79,
+               81,  82,  84,  86,  88,  89,  91,  93,
+               94,  96,  98,  99, 101, 102, 104, 105,
+               106, 108, 109, 110, 112, 113, 114, 115,
+               116, 117, 119, 120, 120, 121, 122, 123,
+               124, 125, 126, 126, 127, 128, 128, 129,
+               129, 130, 130, 131, 131, 131, 131, 132,
+               132, 132, 132, 132, 132, 132, 132, 132,
+               132, 132, 132, 131, 131, 131, 130, 130,
+               130, 129, 129, 128, 127, 127, 126, 125,
+               125, 124, 123, 122, 121, 120, 119, 118,
+               117, 116, 115, 114, 113, 111, 110, 109,
+               107, 106, 105, 103, 102, 100,  99,  97,
+               96,  94,  92,  91,  89,  87,  85,  84,  82};
+
+/**
+ * @var GX
+ *   Coordinate X aray for eliptic HSV corrections, conditionaly Green pixel
+ */
+const int GX[] = {     -124, -124, -125, -125, -125, -125, -125, -125,
+               -125, -126, -126, -125, -125, -125, -125, -125,
+               -125, -124, -124, -124, -123, -123, -122, -122,
+               -121, -121, -120, -120, -119, -118, -117, -117,
+               -116, -115, -114, -113, -112, -111, -110, -109,
+               -108, -107, -105, -104, -103, -102, -100, -99,
+               -98, -96, -95, -93, -92, -91, -89, -87,
+               -86, -84, -83, -81, -79, -77, -76, -74,
+               -72, -70, -69, -67, -65, -63, -61, -59,
+               -57, -55, -53, -51, -49, -47, -45, -43,
+               -41, -39, -37, -35, -33, -30, -28, -26,
+               -24, -22, -20, -18, -15, -13, -11,  -9,
+               -7,  -4,  -2,   0,   1,   3,   6,   8,
+               10,  12,  14,  17,  19,  21,  23,  25,
+               27,  29,  32,  34,  36,  38,  40,  42,
+               44,  46,  48,  50,  52,  54,  56,  58,
+               60,  62,  64,  66,  68,  70,  71,  73,
+               75,  77,  78,  80,  82,  83,  85,  87,
+               88,  90,  91,  93,  94,  96,  97,  98,
+               100, 101, 102, 104, 105, 106, 107, 108,
+               109, 111, 112, 113, 113, 114, 115, 116,
+               117, 118, 118, 119, 120, 120, 121, 122,
+               122, 123, 123, 124, 124, 124, 125, 125,
+               125, 125, 125, 125, 125, 126, 126, 125,
+               125, 125, 125, 125, 125, 124, 124, 124,
+               123, 123, 122, 122, 121, 121, 120, 120,
+               119, 118, 117, 117, 116, 115, 114, 113,
+               112, 111, 110, 109, 108, 107, 105, 104,
+               103, 102, 100,  99,  98,  96,  95,  93,
+               92,  91,  89,  87,  86,  84,  83,  81,
+               79,  77,  76,  74,  72,  70,  69,  67,
+               65,  63,  61,  59,  57,  55,  53,  51,
+               49,  47,  45,  43,  41,  39,  37,  35,
+               33,  30,  28,  26,  24,  22,  20,  18,
+               15,  13,  11,   9,   7,   4,   2,   0,
+               -1,  -3,  -6,  -8, -10, -12, -14, -17,
+               -19, -21, -23, -25, -27, -29, -32, -34,
+               -36, -38, -40, -42, -44, -46, -48, -50,
+               -52, -54, -56, -58, -60, -62, -64, -66,
+               -68, -70, -71, -73, -75, -77, -78, -80,
+               -82, -83, -85, -87, -88, -90, -91, -93,
+               -94, -96, -97, -98, -100, -101, -102, -104,
+               -105, -106, -107, -108, -109, -111, -112, -113,
+               -113, -114, -115, -116, -117, -118, -118, -119,
+               -120, -120, -121, -122, -122, -123, -123, -124, -124};
+
+/**
+ * @var GY
+ *   Coordinate Y aray for eliptic HSV corrections, conditionaly Green pixel
+ */
+const int GY[] = {     -100, -99, -98, -97, -95, -94, -93, -91,
+               -90, -89, -87, -86, -84, -83, -81, -80,
+               -78, -76, -75, -73, -71, -70, -68, -66,
+               -64, -63, -61, -59, -57, -55, -53, -51,
+               -49, -48, -46, -44, -42, -40, -38, -36,
+               -34, -32, -30, -27, -25, -23, -21, -19,
+               -17, -15, -13, -11,  -9,  -7,  -4,  -2,
+               0,   1,   3,   5,   7,   9,  11,  14,
+               16,  18,  20,  22,  24,  26,  28,  30,
+               32,  34,  36,  38,  40,  42,  44,  46,
+               48,  50,  52,  54,  56,  58,  59,  61,
+               63,  65,  67,  68,  70,  72,  74,  75,
+               77,  78,  80,  82,  83,  85,  86,  88,
+               89,  90,  92,  93,  95,  96,  97,  98,
+               100, 101, 102, 103, 104, 105, 106, 107,
+               108, 109, 110, 111, 112, 112, 113, 114,
+               115, 115, 116, 116, 117, 117, 118, 118,
+               119, 119, 119, 120, 120, 120, 120, 120,
+               121, 121, 121, 121, 121, 121, 120, 120,
+               120, 120, 120, 119, 119, 119, 118, 118,
+               117, 117, 116, 116, 115, 114, 114, 113,
+               112, 111, 111, 110, 109, 108, 107, 106,
+               105, 104, 103, 102, 100,  99,  98,  97,
+               95,  94,  93,  91,  90,  89,  87,  86,
+               84,  83,  81,  80,  78,  76,  75,  73,
+               71,  70,  68,  66,  64,  63,  61,  59,
+               57,  55,  53,  51,  49,  48,  46,  44,
+               42,  40,  38,  36,  34,  32,  30,  27,
+               25,  23,  21,  19,  17,  15,  13,  11,
+               9,   7,   4,   2,   0,  -1,  -3,  -5,
+               -7,  -9, -11, -14, -16, -18, -20, -22,
+               -24, -26, -28, -30, -32, -34, -36, -38,
+               -40, -42, -44, -46, -48, -50, -52, -54,
+               -56, -58, -59, -61, -63, -65, -67, -68,
+               -70, -72, -74, -75, -77, -78, -80, -82,
+               -83, -85, -86, -88, -89, -90, -92, -93,
+               -95, -96, -97, -98, -100, -101, -102, -103,
+               -104, -105, -106, -107, -108, -109, -110, -111,
+               -112, -112, -113, -114, -115, -115, -116, -116,
+               -117, -117, -118, -118, -119, -119, -119, -120,
+               -120, -120, -120, -120, -121, -121, -121, -121,
+               -121, -121, -120, -120, -120, -120, -120, -119,
+               -119, -119, -118, -118, -117, -117, -116, -116,
+               -115, -114, -114, -113, -112, -111, -111, -110,
+               -109, -108, -107, -106, -105, -104, -103, -102, -100};
+
+/**
+ * @var BX
+ *   Coordinate X aray for eliptic HSV corrections, conditionaly Blue pixel
+ */
+const int BX[] = {     112, 113, 114, 114, 115, 116, 117, 117,
+               118, 118, 119, 119, 120, 120, 120, 121,
+               121, 121, 122, 122, 122, 122, 122, 122,
+               122, 122, 122, 122, 122, 122, 121, 121,
+               121, 120, 120, 120, 119, 119, 118, 118,
+               117, 116, 116, 115, 114, 113, 113, 112,
+               111, 110, 109, 108, 107, 106, 105, 104,
+               103, 102, 100,  99,  98,  97,  95,  94,
+               93,  91,  90,  88,  87,  85,  84,  82,
+               80,  79,  77,  76,  74,  72,  70,  69,
+               67,  65,  63,  61,  60,  58,  56,  54,
+               52,  50,  48,  46,  44,  42,  40,  38,
+               36,  34,  32,  30,  28,  26,  24,  22,
+               19,  17,  15,  13,  11,   9,   7,   5,
+               2,   0,  -1,  -3,  -5,  -7,  -9, -12,
+               -14, -16, -18, -20, -22, -24, -26, -28,
+               -31, -33, -35, -37, -39, -41, -43, -45,
+               -47, -49, -51, -53, -54, -56, -58, -60,
+               -62, -64, -66, -67, -69, -71, -73, -74,
+               -76, -78, -79, -81, -83, -84, -86, -87,
+               -89, -90, -92, -93, -94, -96, -97, -98,
+               -99, -101, -102, -103, -104, -105, -106, -107,
+               -108, -109, -110, -111, -112, -113, -114, -114,
+               -115, -116, -117, -117, -118, -118, -119, -119,
+               -120, -120, -120, -121, -121, -121, -122, -122,
+               -122, -122, -122, -122, -122, -122, -122, -122,
+               -122, -122, -121, -121, -121, -120, -120, -120,
+               -119, -119, -118, -118, -117, -116, -116, -115,
+               -114, -113, -113, -112, -111, -110, -109, -108,
+               -107, -106, -105, -104, -103, -102, -100, -99,
+               -98, -97, -95, -94, -93, -91, -90, -88,
+               -87, -85, -84, -82, -80, -79, -77, -76,
+               -74, -72, -70, -69, -67, -65, -63, -61,
+               -60, -58, -56, -54, -52, -50, -48, -46,
+               -44, -42, -40, -38, -36, -34, -32, -30,
+               -28, -26, -24, -22, -19, -17, -15, -13,
+               -11,  -9,  -7,  -5,  -2,   0,   1,   3,
+               5,   7,   9,  12,  14,  16,  18,  20,
+               22,  24,  26,  28,  31,  33,  35,  37,
+               39,  41,  43,  45,  47,  49,  51,  53,
+               54,  56,  58,  60,  62,  64,  66,  67,
+               69,  71,  73,  74,  76,  78,  79,  81,
+               83,  84,  86,  87,  89,  90,  92,  93,
+               94,  96,  97,  98,  99, 101, 102, 103,
+               104, 105, 106, 107, 108, 109, 110, 111, 112};
+
+/**
+ * @var BY
+ *   Coordinate Y aray for eliptic HSV corrections, conditionaly Blue pixel
+ */
+const int BY[] = {     -11, -13, -15, -17, -19, -21, -23, -25,
+               -27, -29, -31, -33, -35, -37, -39, -41,
+               -43, -45, -46, -48, -50, -52, -54, -55,
+               -57, -59, -61, -62, -64, -66, -67, -69,
+               -71, -72, -74, -75, -77, -78, -80, -81,
+               -83, -84, -86, -87, -88, -90, -91, -92,
+               -93, -95, -96, -97, -98, -99, -100, -101,
+               -102, -103, -104, -105, -106, -106, -107, -108,
+               -109, -109, -110, -111, -111, -112, -112, -113,
+               -113, -114, -114, -114, -115, -115, -115, -115,
+               -116, -116, -116, -116, -116, -116, -116, -116,
+               -116, -115, -115, -115, -115, -114, -114, -114,
+               -113, -113, -112, -112, -111, -111, -110, -110,
+               -109, -108, -108, -107, -106, -105, -104, -103,
+               -102, -101, -100, -99, -98, -97, -96, -95,
+               -94, -93, -91, -90, -89, -88, -86, -85,
+               -84, -82, -81, -79, -78, -76, -75, -73,
+               -71, -70, -68, -67, -65, -63, -62, -60,
+               -58, -56, -55, -53, -51, -49, -47, -45,
+               -44, -42, -40, -38, -36, -34, -32, -30,
+               -28, -26, -24, -22, -20, -18, -16, -14,
+               -12, -10,  -8,  -6,  -4,  -2,   0,   1,
+               3,   5,   7,   9,  11,  13,  15,  17,
+               19,  21,  23,  25,  27,  29,  31,  33,
+               35,  37,  39,  41,  43,  45,  46,  48,
+               50,  52,  54,  55,  57,  59,  61,  62,
+               64,  66,  67,  69,  71,  72,  74,  75,
+               77,  78,  80,  81,  83,  84,  86,  87,
+               88,  90,  91,  92,  93,  95,  96,  97,
+               98,  99, 100, 101, 102, 103, 104, 105,
+               106, 106, 107, 108, 109, 109, 110, 111,
+               111, 112, 112, 113, 113, 114, 114, 114,
+               115, 115, 115, 115, 116, 116, 116, 116,
+               116, 116, 116, 116, 116, 115, 115, 115,
+               115, 114, 114, 114, 113, 113, 112, 112,
+               111, 111, 110, 110, 109, 108, 108, 107,
+               106, 105, 104, 103, 102, 101, 100,  99,
+               98,  97,  96,  95,  94,  93,  91,  90,
+               89,  88,  86,  85,  84,  82,  81,  79,
+               78,  76,  75,  73,  71,  70,  68,  67,
+               65,  63,  62,  60,  58,  56,  55,  53,
+               51,  49,  47,  45,  44,  42,  40,  38,
+               36,  34,  32,  30,  28,  26,  24,  22,
+               20,  18,  16,  14,  12,  10,   8,   6,
+               4,   2,   0,  -1,  -3,  -5,  -7,  -9, -11};
+
+
+
 int sn9c20x_set_camera_control(struct usb_sn9c20x *dev,
-       __u32 control, __u32 value)
+       __u32 control, __s32 value)
 {
        int ret = -EINVAL;
        switch (control) {
@@ -53,6 +357,18 @@ int sn9c20x_set_camera_control(struct usb_sn9c20x *dev,
                        ret = dev->camera.set_gamma(dev);
                }
                break;
+       case V4L2_CID_SATURATION:
+               if (dev->camera.set_saturation) {
+                       dev->vsettings.colour = value;
+                       ret = dev->camera.set_saturation(dev);
+               }
+               break;
+       case V4L2_CID_HUE:
+               if (dev->camera.set_hue) {
+                       dev->vsettings.hue = value;
+                       ret = dev->camera.set_hue(dev);
+               }
+               break;
        case V4L2_CID_SHARPNESS:
                if (dev->camera.set_sharpness) {
                        dev->vsettings.sharpness = value;
@@ -482,34 +798,127 @@ int sn9c20x_write_i2c_array(struct usb_sn9c20x *dev,
        return ret;
 }
 
+static __u8 optical_parameters[] = {0x16, 0x0, 0x2b, 0x0, 0x8, 0x0, 0xf6,
+                               0x0f, 0xd2, 0x0f, 0x38, 0x0, 0x34, 0x0, 0xcf,
+                               0x0f, 0xfd, 0x0f, 0x0, 0x0, 0x0};
+
+
 /**
- * @brief Set contrast inside sn9c20x chip
+ * @brief Calculate and set optical parameters
  *
- * @author Comer352l
+ * @author Comer352l, Boris Borisov
  *
  * @param dev Pointer to the device
  *
  * @return Zero (success) or negative (USB-error value)
  *
  */
-int sn9c20x_set_contrast(struct usb_sn9c20x *dev)
+int sn9c20x_set_optical_parameters(struct usb_sn9c20x *dev)
 {
-       /* from 0x26 to 0x4b */
-       __u8 brightness_contrast[21] = {0x16, 0x0, 0x2b, 0x0, 0x8, 0x0, 0xf6, 
0x0f,
-                               0xd2, 0x0f, 0x38, 0x0, 0x34, 0x0, 0xcf, 0x0f,
-                               0xfd, 0x0f, 0x0, 0x0, 0x0};
+       
+/*__u8 optical_parameters[] = {0x16, 0x0, 0x2b, 0x0, 0x8, 0x0, 0xf6,
+                               0x0f, 0xd2, 0x0f, 0x38, 0x0, 0x34, 0x0, 0xcf,
+                               0x0f, 0xfd, 0x0f, 0x0, 0x0, 0x0};*/
        __u8 contrast_val = (dev->vsettings.contrast) * 0x25 / 0x100;
        __u8 brightness_val = dev->vsettings.brightness;
-
+       __u8 ret = 0;
+       __s16 value;
+       long tmp_coordinate;
+
+       UDIA_INFO("Array Value: %x %x %x %x %x %x %x \n",       
optical_parameters[0],
+                                                               
optical_parameters[1],
+                                                               
optical_parameters[2],
+                                                               
optical_parameters[3],
+                                                               
optical_parameters[4],
+                                                               
optical_parameters[5],
+                                                               
optical_parameters[6]);
+
+       UDIA_INFO("Array Value1: %x %x %x %x %x %x %x %x \n",   
optical_parameters[7],
+                                                               
optical_parameters[8],
+                                                               
optical_parameters[9],
+                                                               
optical_parameters[10],
+                                                               
optical_parameters[11],
+                                                               
optical_parameters[12],
+                                                               
optical_parameters[13],
+                                                               
optical_parameters[14]);
+
+       UDIA_INFO("Array Value2: %x %x %x %x %x %x  \n",        
optical_parameters[15],
+                                                               
optical_parameters[16],
+                                                               
optical_parameters[17],
+                                                               
optical_parameters[18],
+                                                               
optical_parameters[19],
+                                                               
optical_parameters[20]);
+
+       if (dev->vsettings.hue < -179)
+           dev->vsettings.hue = -180;
+
+       if (dev->vsettings.hue > 179)
+           dev->vsettings.hue = 180;
+
+       value = 180 + dev->vsettings.hue;
+
+       UDIA_INFO("Hue Value: %d\n", value);
+       UDIA_INFO("Hue vsettings.hue: %d\n", value);
+       /* Brighness and contrast settings  */
        brightness_val -= 0x80;
-       brightness_contrast[18] = brightness_val;
+       optical_parameters[18] = brightness_val;
 
        contrast_val += 0x26;
-       brightness_contrast[2] = contrast_val;
-       brightness_contrast[0] = 0x13 + (brightness_contrast[2] - 0x26) * 0x13 
/ 0x25;
-       brightness_contrast[4] = 0x7 + (brightness_contrast[2] - 0x26) * 0x7 / 
0x25;
+       optical_parameters[2] = contrast_val;
+       optical_parameters[0] = 0x13 + (optical_parameters[2] - 0x26)
+                                                       * 0x13 / 0x25;
+       optical_parameters[4] = 0x7 + (optical_parameters[2] - 0x26)
+                                                       * 0x7 / 0x25;
+
+       /* Calculate HUE and SATURATION */
+       tmp_coordinate = (long)(RX[value]);
+       tmp_coordinate = (tmp_coordinate*dev->vsettings.colour) >> 8;
+       optical_parameters[6] = (unsigned char)(tmp_coordinate&0xff);
+       optical_parameters[7] = (unsigned char)((tmp_coordinate>>8)&0x0f);
+
+       tmp_coordinate = (long)(RY[value]);
+       tmp_coordinate = (tmp_coordinate*dev->vsettings.colour) >> 8;
+       optical_parameters[8] = (unsigned char)(tmp_coordinate&0xff);
+       optical_parameters[9] = (unsigned char)((tmp_coordinate>>8)&0x0f);
+
+       tmp_coordinate = (long)(GX[value]);
+       tmp_coordinate = (tmp_coordinate*dev->vsettings.colour) >> 8;
+       optical_parameters[10] = (unsigned char)(tmp_coordinate&0xff);
+       optical_parameters[11] = (unsigned char)((tmp_coordinate>>8)&0x0f);
+
+       tmp_coordinate = (long)(GY[value]);
+       tmp_coordinate = (tmp_coordinate*dev->vsettings.colour) >> 8;
+       optical_parameters[12] = (unsigned char)(tmp_coordinate&0xff);
+       optical_parameters[13] = (unsigned char)((tmp_coordinate>>8)&0x0f);
+
+       tmp_coordinate = (long)(BX[value]);
+       tmp_coordinate = (tmp_coordinate*dev->vsettings.colour) >> 8;
+       optical_parameters[14] = (unsigned char)(tmp_coordinate&0xff);
+       optical_parameters[15] = (unsigned char)((tmp_coordinate>>8)&0x0f);
+
+       tmp_coordinate = (long)(BY[value]);
+       tmp_coordinate = (tmp_coordinate*dev->vsettings.colour) >> 8;
+       optical_parameters[16] = (unsigned char)(tmp_coordinate&0xff);
+       optical_parameters[17] = (unsigned char)((tmp_coordinate>>8)&0x0f);
+
+
+       ret = usb_sn9c20x_control_write(dev, 0x10e1, optical_parameters, 21);
+       return ret;
+}
 
-       return usb_sn9c20x_control_write(dev, 0x10e1, brightness_contrast, 21);
+/**
+ * @brief Set contrast inside sn9c20x chip
+ *
+ * @author Comer352l
+ *
+ * @param dev Pointer to the device
+ *
+ * @return Zero (success) or negative (USB-error value)
+ *
+ */
+int sn9c20x_set_contrast(struct usb_sn9c20x *dev)
+{
+       return sn9c20x_set_optical_parameters(dev);
 }
 
 /**
@@ -526,7 +935,7 @@ int sn9c20x_set_contrast(struct usb_sn9c20x *dev)
  */
 int sn9c20x_set_brightness(struct usb_sn9c20x *dev)
 {
-       return sn9c20x_set_contrast(dev);
+       return sn9c20x_set_optical_parameters(dev);
 }
 
 /**
@@ -571,6 +980,36 @@ int sn9c20x_set_gamma(struct usb_sn9c20x *dev)
 }
 
 /**
+ * @brief Set saturation inside sn9c20x chip
+ *
+ * @author Neekhil
+ *
+ * @param dev Pointer to the device
+ *
+ * @return Zero (success) or negative (USB-error value)
+ *
+ */
+int sn9c20x_set_saturation(struct usb_sn9c20x *dev)
+{
+       return sn9c20x_set_optical_parameters(dev);
+}
+
+/**
+ * @brief Set hue inside sn9c20x chip
+ *
+ * @author Boris Borisov
+ *
+ * @param dev Pointer to the device
+ *
+ * @return Zero (success) or negative (USB-error value)
+ *
+ */
+int sn9c20x_set_hue(struct usb_sn9c20x *dev)
+{
+       return sn9c20x_set_optical_parameters(dev);
+}
+
+/**
  * @brief Set sharpness inside sn9c20x chip
  *
  * @author Comer352l
@@ -914,9 +1353,11 @@ int sn9c20x_initialize(struct usb_sn9c20x *dev)
        dev->camera.set_contrast = sn9c20x_set_contrast;
        dev->camera.set_brightness = sn9c20x_set_brightness;
        dev->camera.set_gamma = sn9c20x_set_gamma;
+       dev->camera.set_saturation = sn9c20x_set_saturation;
        dev->camera.set_sharpness = sn9c20x_set_sharpness;
        dev->camera.set_red_gain = sn9c20x_set_red_gain;
        dev->camera.set_blue_gain = sn9c20x_set_blue_gain;
+       dev->camera.set_hue = sn9c20x_set_hue;
 
        ret = sn9c20x_i2c_initialize(dev);
        if (ret < 0)
@@ -934,7 +1375,7 @@ int sn9c20x_reset_device(struct usb_sn9c20x *dev)
 {
        if (sn9c20x_initialize(dev) < 0)
                return -EINVAL;
-
+       
        sn9c20x_set_camera_control(dev, V4L2_CID_HFLIP,
                                   dev->vsettings.hflip);
        sn9c20x_set_camera_control(dev, V4L2_CID_VFLIP,
diff --git a/sn9c20x-bridge.h b/sn9c20x-bridge.h
index 00e7875..9c6a2a6 100644
--- a/sn9c20x-bridge.h
+++ b/sn9c20x-bridge.h
@@ -48,7 +48,8 @@
 int sn9c20x_initialize(struct usb_sn9c20x *dev);
 int sn9c20x_reset_device(struct usb_sn9c20x *dev);
 int sn9c20x_set_LEDs(struct usb_sn9c20x *dev, int enable);
-int sn9c20x_set_camera_control(struct usb_sn9c20x *dev, __u32 control, __u32 
value);
+int sn9c20x_set_camera_control(struct usb_sn9c20x *dev,
+                                __u32 control, __s32 value);
 int sn9c20x_enable_video(struct usb_sn9c20x *dev, int enable);
 int sn9c20x_i2c_initialize(struct usb_sn9c20x *dev);
 
diff --git a/sn9c20x-dev.c b/sn9c20x-dev.c
index b1eb4d3..29f9217 100644
--- a/sn9c20x-dev.c
+++ b/sn9c20x-dev.c
@@ -172,7 +172,6 @@ int sn9c20x_initialize_sensor(struct usb_sn9c20x *dev)
                sn9c20x_write_i2c_array(dev, ov7660_init, 0);
                dev->camera.set_exposure = ov_set_exposure;
                dev->camera.set_auto_gain = ov_set_autogain;
-               dev->camera.set_gain = ov9650_set_gain;
                dev->camera.hstart = 1;
                dev->camera.vstart = 1;
                UDIA_INFO("Detected OV7660 Sensor.\n");
diff --git a/sn9c20x-sysfs.c b/sn9c20x-sysfs.c
index 15bb13c..ce97ba3 100644
--- a/sn9c20x-sysfs.c
+++ b/sn9c20x-sysfs.c
@@ -400,30 +400,33 @@ static ssize_t store_contrast(struct device *class, 
struct device_attribute *att
 }
 
 
+
+
 /**
- * @brief show_whitebalance
+ * @brief show_saturation
  *
  * @param class Class device
  * @param attr
- * @retval buf Adress of buffer with the 'whitebalance' value
+ * @retval buf Adress of buffer with the 'contrast' value
  *
  * @returns Size of buffer
  */
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
-static ssize_t show_gamma(struct class_device *class, char *buf)
+static ssize_t show_saturation(struct class_device *class, char *buf)
 #else
-static ssize_t show_gamma(struct device *class, struct device_attribute *attr, 
char *buf)
+static ssize_t show_saturation(struct device *class,
+               struct device_attribute *attr, char *buf)
 #endif
 {
        struct video_device *vdev = to_video_device(class);
        struct usb_sn9c20x *dev = video_get_drvdata(vdev);
 
-       return sprintf(buf, "%X\n", dev->vsettings.gamma);
+       return sprintf(buf, "%X\n", dev->vsettings.colour);
 }
 
 
 /**
- * @brief store_gamma
+ * @brief store_saturation
  *
  * @param class Class device
  * @param buf Buffer
@@ -433,10 +436,14 @@ static ssize_t show_gamma(struct device *class, struct 
device_attribute *attr, c
  * @returns Size of buffer
  */
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
-static ssize_t store_gamma(struct class_device *class, const char *buf, size_t 
count)
+static ssize_t store_saturation(struct class_device *class,
+                               const char *buf,
+                               size_t count)
 #else
-static ssize_t store_gamma(struct device *class, struct device_attribute *attr,
-               const char *buf, size_t count)
+static ssize_t store_saturation(struct device *class,
+                               struct device_attribute *attr,
+                               const char *buf,
+                               size_t count)
 #endif
 {
        char *endp;
@@ -448,37 +455,41 @@ static ssize_t store_gamma(struct device *class, struct 
device_attribute *attr,
        value = simple_strtoul(buf, &endp, 16);
 
        sn9c20x_set_camera_control(dev,
-                                  V4L2_CID_GAMMA,
+                                  V4L2_CID_SATURATION,
                                   value);
 
        return strlen(buf);
 }
 
 
-/*
- * @brief show_colour
+
+/**
+ * @brief show_hue
  *
  * @param class Class device
  * @param attr
- * @retval buf Adress of buffer with the 'colour' value
+ * @retval buf Adress of buffer with the 'contrast' value
  *
  * @returns Size of buffer
  */
-/*#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
-static ssize_t show_colour(struct class_device *class, char *buf)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
+static ssize_t show_hue(struct class_device *class,
+                       char *buf)
 #else
-static ssize_t show_colour(struct device *class, struct device_attribute 
*attr, char *buf)
+static ssize_t show_hue(struct device *class,
+                       struct device_attribute *attr,
+                       char *buf)
 #endif
 {
        struct video_device *vdev = to_video_device(class);
        struct usb_sn9c20x *dev = video_get_drvdata(vdev);
 
-       return sprintf(buf, "%X\n", dev->vsettings.colour);
+       return sprintf(buf, "%X\n", dev->vsettings.hue);
 }
-*/
 
-/*
- * @brief store_colour
+
+/**
+ * @brief store_hue
  *
  * @param class Class device
  * @param buf Buffer
@@ -487,11 +498,14 @@ static ssize_t show_colour(struct device *class, struct 
device_attribute *attr,
  *
  * @returns Size of buffer
  */
-/*#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
-static ssize_t store_colour(struct class_device *class, const char *buf, 
size_t count)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
+static ssize_t store_hue(struct class_device *class,
+                       const char *buf,
+                       size_t count)
 #else
-static ssize_t store_colour(struct device *class, struct device_attribute 
*attr,
-               const char *buf, size_t count)
+static ssize_t store_hue(struct device *class,
+                       struct device_attribute *attr,
+                       const char *buf, size_t count)
 #endif
 {
        char *endp;
@@ -502,13 +516,77 @@ static ssize_t store_colour(struct device *class, struct 
device_attribute *attr,
 
        value = simple_strtoul(buf, &endp, 16);
 
-       dev->vsettings.colour = (int) value;
+       sn9c20x_set_camera_control(dev,
+                                  V4L2_CID_HUE,
+                                  value);
+
+       return strlen(buf);
+}
+
+
+
+
+/**
+ * @brief show_whitebalance
+ *
+ * @param class Class device
+ * @param attr
+ * @retval buf Adress of buffer with the 'whitebalance' value
+ *
+ * @returns Size of buffer
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
+static ssize_t show_gamma(struct class_device *class,
+                         char *buf)
+#else
+static ssize_t show_gamma(struct device *class,
+                         struct device_attribute *attr,
+                         char *buf)
+#endif
+{
+       struct video_device *vdev = to_video_device(class);
+       struct usb_sn9c20x *dev = video_get_drvdata(vdev);
+
+       return sprintf(buf, "%X\n", dev->vsettings.gamma);
+}
 
-/      dev_sn9c20x_set_camera_quality(dev); /
+
+/**
+ * @brief store_gamma
+ *
+ * @param class Class device
+ * @param buf Buffer
+ * @param count Counter
+ * @param attr
+ *
+ * @returns Size of buffer
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
+static ssize_t store_gamma(struct class_device *class,
+                          const char *buf,
+                          size_t count)
+#else
+static ssize_t store_gamma(struct device *class,
+                          struct device_attribute *attr,
+                          const char *buf, size_t count)
+#endif
+{
+       char *endp;
+       unsigned long value;
+
+       struct video_device *vdev = to_video_device(class);
+       struct usb_sn9c20x *dev = video_get_drvdata(vdev);
+
+       value = simple_strtoul(buf, &endp, 16);
+
+       sn9c20x_set_camera_control(dev,
+                                  V4L2_CID_GAMMA,
+                                  value);
 
        return strlen(buf);
 }
-*/
+
+
 
 
 /**
@@ -802,10 +880,11 @@ static CLASS_DEVICE_ATTR(fps, S_IRUGO, show_fps, NULL);   
                                                        /**< FPS value */
 static CLASS_DEVICE_ATTR(brightness, S_IRUGO | S_IWUGO, show_brightness, 
store_brightness);                    /**< Brightness value */
 static CLASS_DEVICE_ATTR(exposure, S_IRUGO | S_IWUGO, show_exposure, 
store_exposure);                          /**< Exposure value */
 static CLASS_DEVICE_ATTR(gain, S_IRUGO | S_IWUGO, show_gain, store_gain);      
                                /**< Gain value */
+static CLASS_DEVICE_ATTR(saturation, S_IRUGO | S_IWUGO, show_saturation, 
store_saturation);                    /**< Saturation value */
+static CLASS_DEVICE_ATTR(hue, S_IRUGO | S_IWUGO, show_hue, store_hue);         
                                /**< Hue value */
 static CLASS_DEVICE_ATTR(contrast, S_IRUGO | S_IWUGO, show_contrast, 
store_contrast);                          /**< Contrast value */
 static CLASS_DEVICE_ATTR(gamma, S_IRUGO | S_IWUGO, show_gamma, store_gamma); 
/**< Gamma value */
 static CLASS_DEVICE_ATTR(sharpness, S_IRUGO | S_IWUGO, show_sharpness, 
store_sharpness);                       /**< Sharpness value */
-/*static CLASS_DEVICE_ATTR(colour, S_IRUGO | S_IWUGO, show_colour, 
store_colour);                              /< Hue value */
 static CLASS_DEVICE_ATTR(hflip, S_IRUGO | S_IWUGO, show_hflip, store_hflip);   
                                /**< Horizontal flip value */
 static CLASS_DEVICE_ATTR(vflip, S_IRUGO | S_IWUGO, show_vflip, store_vflip);   
                                /**< Vertical flip value */
 static CLASS_DEVICE_ATTR(auto_exposure, S_IRUGO | S_IWUGO, show_autoexposure, 
store_autoexposure);             /**< Automatic exposure control value */
@@ -819,9 +898,10 @@ static DEVICE_ATTR(brightness, S_IRUGO | S_IWUGO, 
show_brightness, store_brightn
 static DEVICE_ATTR(exposure, S_IRUGO | S_IWUGO, show_exposure, 
store_exposure);                                        /**< Exposure value */
 static DEVICE_ATTR(gain, S_IRUGO | S_IWUGO, show_gain, store_gain);            
                                /**< Gain value */
 static DEVICE_ATTR(contrast, S_IRUGO | S_IWUGO, show_contrast, 
store_contrast);                                        /**< Contrast value */
-static DEVICE_ATTR(gamma, S_IRUGO | S_IWUGO, show_gamma, store_gamma); /**< 
Gamma value */
+static DEVICE_ATTR(saturation, S_IRUGO | S_IWUGO, show_saturation, 
store_saturation);                          /**< Saturation value */
+static DEVICE_ATTR(hue, S_IRUGO | S_IWUGO, show_hue, store_hue);               
                                /**< Hue value */
+static DEVICE_ATTR(gamma, S_IRUGO | S_IWUGO, show_gamma, store_gamma);         
                                        /**< Gamma value */
 static DEVICE_ATTR(sharpness, S_IRUGO | S_IWUGO, show_sharpness, 
store_sharpness);                             /**< Sharpness value */
-/*static DEVICE_ATTR(colour, S_IRUGO | S_IWUGO, show_colour, store_colour);    
                                /< Hue value */
 static DEVICE_ATTR(hflip, S_IRUGO | S_IWUGO, show_hflip, store_hflip);         
                                /**< Horizontal flip value */
 static DEVICE_ATTR(vflip, S_IRUGO | S_IWUGO, show_vflip, store_vflip);         
                                /**< Vertical flip value */
 static DEVICE_ATTR(auto_exposure, S_IRUGO | S_IWUGO, show_autoexposure, 
store_autoexposure);                   /**< Automatic exposure control value */
@@ -851,9 +931,10 @@ int sn9c20x_create_sysfs_files(struct video_device *vdev)
        ret = video_device_create_file(vdev, &class_device_attr_exposure);
        ret = video_device_create_file(vdev, &class_device_attr_gain);
        ret = video_device_create_file(vdev, &class_device_attr_contrast);
+       ret = video_device_create_file(vdev, &class_device_attr_saturation);
+       ret = video_device_create_file(vdev, &class_device_attr_hue);
        ret = video_device_create_file(vdev, &class_device_attr_gamma);
        ret = video_device_create_file(vdev, &class_device_attr_sharpness);
-       /*ret = video_device_create_file(vdev, &class_device_attr_colour);*/
        ret = video_device_create_file(vdev, &class_device_attr_hflip);
        ret = video_device_create_file(vdev, &class_device_attr_vflip);
        ret = video_device_create_file(vdev, &class_device_attr_auto_exposure);
@@ -867,9 +948,10 @@ int sn9c20x_create_sysfs_files(struct video_device *vdev)
        ret = video_device_create_file(vdev, &dev_attr_exposure);
        ret = video_device_create_file(vdev, &dev_attr_gain);
        ret = video_device_create_file(vdev, &dev_attr_contrast);
+       ret = video_device_create_file(vdev, &dev_attr_saturation);
+       ret = video_device_create_file(vdev, &dev_attr_hue);
        ret = video_device_create_file(vdev, &dev_attr_gamma);
        ret = video_device_create_file(vdev, &dev_attr_sharpness);
-       /*ret = video_device_create_file(vdev, &dev_attr_colour);*/
        ret = video_device_create_file(vdev, &dev_attr_hflip);
        ret = video_device_create_file(vdev, &dev_attr_vflip);
        ret = video_device_create_file(vdev, &dev_attr_auto_exposure);
@@ -883,9 +965,10 @@ int sn9c20x_create_sysfs_files(struct video_device *vdev)
        ret = device_create_file(&vdev->dev, &dev_attr_exposure);
        ret = device_create_file(&vdev->dev, &dev_attr_gain);
        ret = device_create_file(&vdev->dev, &dev_attr_contrast);
+       ret = device_create_file(&vdev->dev, &dev_attr_saturation);
+       ret = device_create_file(&vdev->dev, &dev_attr_hue);
        ret = device_create_file(&vdev->dev, &dev_attr_gamma);
        ret = device_create_file(&vdev->dev, &dev_attr_sharpness);
-       /*ret = video_device_create_file(vdev, &dev_attr_colour);*/
        ret = device_create_file(&vdev->dev, &dev_attr_hflip);
        ret = device_create_file(&vdev->dev, &dev_attr_vflip);
        ret = device_create_file(&vdev->dev, &dev_attr_auto_exposure);
@@ -915,9 +998,10 @@ void sn9c20x_remove_sysfs_files(struct video_device *vdev)
        video_device_remove_file(vdev, &class_device_attr_exposure);
        video_device_remove_file(vdev, &class_device_attr_gain);
        video_device_remove_file(vdev, &class_device_attr_contrast);
+       video_device_remove_file(vdev, &class_device_attr_saturation);
+       video_device_remove_file(vdev, &class_device_attr_hue);
        video_device_remove_file(vdev, &class_device_attr_gamma);
        video_device_remove_file(vdev, &class_device_attr_sharpness);
-       /*video_device_remove_file(vdev, &class_device_attr_colour);*/
        video_device_remove_file(vdev, &class_device_attr_hflip);
        video_device_remove_file(vdev, &class_device_attr_vflip);
        video_device_remove_file(vdev, &class_device_attr_auto_exposure);
@@ -931,9 +1015,10 @@ void sn9c20x_remove_sysfs_files(struct video_device *vdev)
        video_device_remove_file(vdev, &dev_attr_exposure);
        video_device_remove_file(vdev, &dev_attr_gain);
        video_device_remove_file(vdev, &dev_attr_contrast);
+       video_device_remove_file(vdev, &dev_attr_saturation);
+       video_device_remove_file(vdev, &dev_attr_hue);
        video_device_remove_file(vdev, &dev_attr_gamma);
        video_device_remove_file(vdev, &dev_attr_sharpness);
-       /*video_device_remove_file(vdev, &dev_attr_colour);*/
        video_device_remove_file(vdev, &dev_attr_hflip);
        video_device_remove_file(vdev, &dev_attr_vflip);
        video_device_remove_file(vdev, &dev_attr_auto_exposure);
@@ -947,9 +1032,10 @@ void sn9c20x_remove_sysfs_files(struct video_device *vdev)
        device_remove_file(&vdev->dev, &dev_attr_exposure);
        device_remove_file(&vdev->dev, &dev_attr_gain);
        device_remove_file(&vdev->dev, &dev_attr_contrast);
+       device_remove_file(&vdev->dev, &dev_attr_saturation);
+       device_remove_file(&vdev->dev, &dev_attr_hue);
        device_remove_file(&vdev->dev, &dev_attr_gamma);
        device_remove_file(&vdev->dev, &dev_attr_sharpness);
-       /*video_device_remove_file(vdev, &dev_attr_colour);*/
        device_remove_file(&vdev->dev, &dev_attr_hflip);
        device_remove_file(&vdev->dev, &dev_attr_vflip);
        device_remove_file(&vdev->dev, &dev_attr_auto_exposure);
diff --git a/sn9c20x-usb.c b/sn9c20x-usb.c
index 59abfbf..485aa1c 100644
--- a/sn9c20x-usb.c
+++ b/sn9c20x-usb.c
@@ -101,6 +101,18 @@ static __u16 brightness = SN9C20X_PERCENT(50, 0xFF);
 static __u16 gamma = SN9C20X_PERCENT(20, 0xFF);
 
 /**
+ * @var saturation
+ *   Module parameter to set the gamma
+ */
+static __u16 saturation = SN9C20X_PERCENT(50, 0xFF);
+
+/**
+ * @var hue
+ *   Module parameter to set the gamma
+ */
+static __s16 hue;
+
+/**
  * @var contrast
  *   Module parameter to set the contrast
  */
@@ -116,7 +128,7 @@ static __u16 exposure = SN9C20X_PERCENT(20, 0xFF);
  * @var gain
  *   Module parameter to set the gain
  */
-static __u16 gain = SN9C20X_PERCENT(20, 0xFF);
+static int gain = SN9C20X_PERCENT(20, 0xFF);
 
 /**
  * @var sharpness
@@ -734,6 +746,8 @@ static int usb_sn9c20x_default_settings(struct usb_sn9c20x 
*dev)
        v4l2_set_control_default(dev, V4L2_CID_BRIGHTNESS, brightness);
        v4l2_set_control_default(dev, V4L2_CID_CONTRAST, contrast);
        v4l2_set_control_default(dev, V4L2_CID_GAMMA, gamma);
+       v4l2_set_control_default(dev, V4L2_CID_SATURATION, saturation);
+       v4l2_set_control_default(dev, V4L2_CID_HUE, hue);
        v4l2_set_control_default(dev, V4L2_CID_SHARPNESS, sharpness);
        v4l2_set_control_default(dev, V4L2_CID_RED_BALANCE, red_gain);
        v4l2_set_control_default(dev, V4L2_CID_BLUE_BALANCE, blue_gain);
@@ -1073,6 +1087,7 @@ module_param(auto_gain, byte, 0444);              /**< 
@brief Module parameter automatic gai
 module_param(auto_whitebalance, byte, 0444);   /**< @brief Module parameter 
automatic whitebalance control */
 module_param(brightness, ushort, 0444);                /**< @brief Module 
parameter brightness */
 module_param(gamma, ushort, 0444);             /**< @brief Module parameter 
gamma */
+module_param(saturation, ushort, 0444);                /**< @brief Module 
parameter saturation */
 module_param(contrast, ushort, 0444);          /**< @brief Module parameter 
contrast */
 module_param(exposure, ushort, 0444);          /**< @brief Module parameter 
exposure */
 module_param(sharpness, ushort, 0444);         /**< @brief Module parameter 
sharpness */
@@ -1221,6 +1236,7 @@ MODULE_PARM_DESC(auto_gain, "Automatic gain control");    
        /**< @brief Description
 MODULE_PARM_DESC(auto_whitebalance, "Automatic whitebalance"); /**< @brief 
Description of 'auto_whitebalance' parameter */
 MODULE_PARM_DESC(brightness, "Brightness setting");            /**< @brief 
Description of 'brightness' parameter */
 MODULE_PARM_DESC(gamma, "Gamma setting");                      /**< @brief 
Description of 'gamma' parameter */
+MODULE_PARM_DESC(saturation, "Saturation setting");            /**< @brief 
Description of 'saturation' parameter */
 MODULE_PARM_DESC(exposure, "Exposure setting");                        /**< 
@brief Description of 'exposure' parameter */
 MODULE_PARM_DESC(gain, "Gain setting");                                /**< 
@brief Description of 'gain' parameter */
 MODULE_PARM_DESC(contrast, "Contrast setting");                        /**< 
@brief Description of 'contrast' parameter */
diff --git a/sn9c20x-v4l2.c b/sn9c20x-v4l2.c
index 6eada10..3feaadd 100644
--- a/sn9c20x-v4l2.c
+++ b/sn9c20x-v4l2.c
@@ -68,7 +68,7 @@ static struct v4l2_queryctrl sn9c20x_controls[] = {
                .maximum = 0xff,
                .step    = 1,
        },
-/*
+
        {
                .id      = V4L2_CID_SATURATION,
                .type    = V4L2_CTRL_TYPE_INTEGER,
@@ -77,7 +77,16 @@ static struct v4l2_queryctrl sn9c20x_controls[] = {
                .maximum = 0xff,
                .step    = 1,
        },
-*/
+
+       {
+               .id      = V4L2_CID_HUE,
+               .type    = V4L2_CTRL_TYPE_INTEGER,
+               .name    = "Hue",
+               .minimum = -180,
+               .maximum = 180,
+               .step    = 1,
+       },
+
        {
                .id      = V4L2_CID_CONTRAST,
                .type    = V4L2_CTRL_TYPE_INTEGER,
@@ -856,11 +865,15 @@ int sn9c20x_vidioc_g_ctrl(struct file *file, void *priv,
        case V4L2_CID_GAMMA:
                ctrl->value = dev->vsettings.gamma;
                break;
-/*
+
        case V4L2_CID_SATURATION:
                ctrl->value = dev->vsettings.colour;
                break;
-*/
+
+       case V4L2_CID_HUE:
+               ctrl->value = dev->vsettings.hue;
+               break;
+
        case V4L2_CID_CONTRAST:
                ctrl->value = dev->vsettings.contrast;
                break;
diff --git a/sn9c20x.h b/sn9c20x.h
index a9aa513..6086b53 100644
--- a/sn9c20x.h
+++ b/sn9c20x.h
@@ -328,9 +328,11 @@ struct sn9c20x_camera {
        int (*set_contrast) (struct usb_sn9c20x *dev);
        int (*set_brightness) (struct usb_sn9c20x *dev);
        int (*set_gamma) (struct usb_sn9c20x *dev);
+       int (*set_saturation) (struct usb_sn9c20x *dev);
        int (*set_sharpness) (struct usb_sn9c20x *dev);
        int (*set_red_gain) (struct usb_sn9c20x *dev);
        int (*set_blue_gain) (struct usb_sn9c20x *dev);
+       int (*set_hue) (struct usb_sn9c20x *dev);
 };
 
 /**
        __u8 optical_parameters[21] = {0x16, 0x0, 0x2b, 0x0, 0x8, 0x0, 0xf6,
                                0x0f, 0xd2, 0x0f, 0x38, 0x0, 0x34, 0x0, 0xcf,
                                0x0f, 0xfd, 0x0f, 0x0, 0x0, 0x0};

    0x08048393 <main+19>:   lea    -0x2a(%ebp),%edi             - 3 cycles x 1 
times
    0x08048396 <main+22>:   mov    $0x80486fc,%esi              - 2 cycles x 1 
times
    0x0804839b <main+27>:   cld                                 - 2 cycles x 1 
times
    0x0804839c <main+28>:   mov    $0x15,%ecx                   - 2 cycles x 1 
times
    0x080483a1 <main+33>:   rep movsb %ds:(%esi),%es:(%edi)     - 2 cycles x 21 
times

Total cycles time 50 cycles 7.6%

__u8 contrast_val = (contrast) * 0x25 / 0x100;

    0x080483a3 <main+35>:   mov    0x804a044,%edx               - 2 cycles x 1 
times
    0x080483a9 <main+41>:   mov    %edx,%eax                    - 2 cycles x 1 
times
    0x080483ab <main+43>:   shl    $0x3,%eax                    - 4 cycles x 1 
times
    0x080483ae <main+46>:   add    %edx,%eax                    - 1 cycles x 1 
times
    0x080483b0 <main+48>:   shl    $0x2,%eax                    - 4 cycles x 1 
times
    0x080483b3 <main+51>:   add    %edx,%eax                    - 1 cycles x 1 
times
    0x080483b5 <main+53>:   lea    0xff(%eax),%edx              - 3 cycles x 1 
times
    0x080483bb <main+59>:   test   %eax,%eax                    - 1 cycles x 1 
times
    0x080483bd <main+61>:   cmovs  %edx,%eax                    ????? 2 
estimated
    0x080483c0 <main+64>:   sar    $0x8,%eax                    - 4 cycles x 1 
times
    0x080483c3 <main+67>:   mov    %al,-0x15(%ebp)              - 2 cycles x 1 
times

Total cycles time 26 cycles 3.9%

__u8 brightness_val = brightness;

    0x080483c6 <main+70>:   mov    0x804a048,%eax               - 2 cycles x 1 
times
    0x080483cb <main+75>:   mov    %al,-0x14(%ebp)              - 2 cycles x 1 
times

Total cycles time 4 cycles

__u8 ret = 0;

    0x080483ce <main+78>:   movb   $0x0,-0x13(%ebp)             - 2 cycles x 1 
times

Total cycles time 2 cycles


__s16 value;
long tmp_coordinate;

if (hue < -179)
hue = -180;
    0x080483d2 <main+82>:   mov    0x804a04c,%eax               - 2 cycles x 1 
times
    0x080483d7 <main+87>:   cmp    $0xffffff4d,%eax             - 2 cycles x 1 
times
    0x080483dc <main+92>:   jge    0x80483e8 <main+104>         - 3 cycles x 1 
times

    0x080483de <main+94>:   movl   $0xffffff4c,0x804a04c        - 2 cycles x 1 
times

Total cycles time 9 cycles

if (hue > 179)
hue = 180;

    0x080483e8 <main+104>:  mov    0x804a04c,%eax               - 2 cycles x 1 
times
    0x080483ed <main+109>:  cmp    $0xb3,%eax                   - 2 cycles x 1 
times
    0x080483f2 <main+114>:  jle    0x80483fe <main+126>         - 3 cycles x 1 
times
    0x080483f4 <main+116>:  movl   $0xb4,0x804a04c              - 2 cycles x 1 
times

Total cycles time 9 cycles

value = 180 + hue;

    0x080483fe <main+126>:  mov    0x804a04c,%eax               - 2 cycles x 1 
times
    0x08048403 <main+131>:  movzwl %ax,%eax                     - 3 cycles x 1 
times
    0x08048406 <main+134>:  add    $0xb4,%eax                   - 3 cycles x 1 
times
    0x0804840b <main+139>:  movzwl %ax,%eax                     - 3 cycles x 1 
times
    0x0804840e <main+142>:  mov    %ax,-0x12(%ebp)              - 2 cycles x 1 
times    

Total cycles time 13 cycles 2%

brightness_val -= 0x80;

    0x08048412 <main+146>:  addb   $0x80,-0x14(%ebp)            - 3 cycles x 1 
times

Total cycles time 3 cycles

optical_parameters[18] = brightness_val;

    0x08048416 <main+150>:  movzbl -0x14(%ebp),%eax             - 3 cycles x 1 
times
    0x0804841a <main+154>:  mov    %al,-0x18(%ebp)              - 2 cycles x 1 
times

Total cycles time 5 cycles

contrast_val += 0x26;

    0x0804841d <main+157>:  addb   $0x26,-0x15(%ebp)            - 3 cycles x 1 
times

Total cycles time 3 cycles

optical_parameters[2] = contrast_val;

    0x08048421 <main+161>:  movzbl -0x15(%ebp),%eax             - 3 cycles x 1 
times
    0x08048425 <main+165>:  mov    %al,-0x28(%ebp)              - 2 cycles x 1 
times

Total cycles time 5 cycles

optical_parameters[0] = 0x13 + (optical_parameters[2] - 0x26)
                                                         * 0x13 / 0x25;

    0x08048428 <main+168>:  movzbl -0x28(%ebp),%eax             - 3 cycles x 1 
times
    0x0804842c <main+172>:  movzbl %al,%edx                     - 3 cycles x 1 
times
    0x0804842f <main+175>:  mov    %edx,%eax                    - 2 cycles x 1 
times
    0x08048431 <main+177>:  shl    $0x3,%eax                    - 4 cycles x 1 
times
    0x08048434 <main+180>:  add    %edx,%eax                    - 1 cycles x 1 
times
    0x08048436 <main+182>:  add    %eax,%eax                    - 1 cycles x 1 
times
    0x08048438 <main+184>:  add    %edx,%eax                    - 1 cycles x 1 
times
    0x0804843a <main+186>:  lea    -0x2d2(%eax),%ecx            - 3 cycles x 1 
times
    0x08048440 <main+192>:  movl   $0xdd67c8a7,-0x30(%ebp)      - 2 cycles x 1 
times
    0x08048447 <main+199>:  mov    -0x30(%ebp),%eax             - 2 cycles x 1 
times
    0x0804844a <main+202>:  imul   %ecx                         - 13-26 cycles 
x 1 times
    0x0804844c <main+204>:  lea    (%edx,%ecx,1),%eax           - 2 cycles x 1 
times
    0x0804844f <main+207>:  mov    %eax,%edx                    - 2 cycles x 1 
times
    0x08048451 <main+209>:  sar    $0x5,%edx                    - 1 cycles x 1 
times
    0x08048454 <main+212>:  mov    %ecx,%eax                    - 2 cycles x 1 
times
    0x08048456 <main+214>:  sar    $0x1f,%eax                   - 1 cycles x 1 
times
    0x08048459 <main+217>:  mov    %edx,%ecx                    - 2 cycles x 1 
times
    0x0804845b <main+219>:  sub    %eax,%ecx                    - 1 cycles x 1 
times
    0x0804845d <main+221>:  mov    %ecx,%eax                    - 2 cycles x 1 
times
    0x0804845f <main+223>:  add    $0x13,%al                    - 3 cycles x 1 
times
    0x08048461 <main+225>:  mov    %al,-0x2a(%ebp)              - 2 cycles x 1 
times

Total cycles time 66 cycles 10%

optical_parameters[4] = 0x7 + (optical_parameters[2] - 0x26)
                                               * 0x7 / 0x25;

    0x08048464 <main+228>:  movzbl -0x28(%ebp),%eax             
    0x08048468 <main+232>:  movzbl %al,%edx
    0x0804846b <main+235>:  mov    %edx,%eax
    0x0804846d <main+237>:  shl    $0x3,%eax
    0x08048470 <main+240>:  sub    %edx,%eax
    0x08048472 <main+242>:  lea    -0x10a(%eax),%ecx
    0x08048478 <main+248>:  movl   $0xdd67c8a7,-0x30(%ebp)
    0x0804847f <main+255>:  mov    -0x30(%ebp),%eax
    0x08048482 <main+258>:  imul   %ecx
    0x08048484 <main+260>:  lea    (%edx,%ecx,1),%eax
    0x08048487 <main+263>:  mov    %eax,%edx
    0x08048489 <main+265>:  sar    $0x5,%edx
    0x0804848c <main+268>:  mov    %ecx,%eax
    0x0804848e <main+270>:  sar    $0x1f,%eax
    0x08048491 <main+273>:  mov    %edx,%ecx
    0x08048493 <main+275>:  sub    %eax,%ecx
    0x08048495 <main+277>:  mov    %ecx,%eax
    0x08048497 <main+279>:  add    $0x7,%al
    0x08048499 <main+281>:  mov    %al,-0x26(%ebp)

Total cycles time 66 cycles 10%
-----------------------------------------------------------------------------------------|
tmp_coordinate = (long)(RX[value]);                                             
         |
                                                                                
         |
    0x08048497 <main+279>:  add    $0x7,%al                     - 3 cycles x 1 
times     |
    0x08048499 <main+281>:  mov    %al,-0x26(%ebp)              - 2 cycles x 1 
times     |
    0x0804849c <main+284>:  movswl -0x12(%ebp),%eax             - 3 cycles x 1 
times     |
    0x080484a0 <main+288>:  mov    0x804a014(,%eax,4),%eax      - 2 cycles x 1 
times     |
    0x080484a7 <main+295>:  mov    %eax,-0x10(%ebp)             - 2 cycles x 1 
times     |
                                                                                
         |
Total cycles time 12 cycles                                                     
         |
                                                                                
         |
tmp_coordinate = (tmp_coordinate*colour) >> 8;                                  
         |
                                                                                
         |
    0x080484aa <main+298>:  mov    0x804a050,%eax               - 2 cycles x 1 
times     |
    0x080484af <main+303>:  imul   -0x10(%ebp),%eax             - 13-26 cycles 
x 1 times |
    0x080484b3 <main+307>:  sar    $0x8,%eax                    - 1 cycles x 1 
times     |
    0x080484b6 <main+310>:  mov    %eax,-0x10(%ebp)             - 2 cycles x 1 
times     |
                                                                                
         |
Total cycles time 31 cycles                                                     
         |
                                                                                
         |
optical_parameters[6] = (unsigned char)(tmp_coordinate*0xff);                   
         |
                                                                                
         |
    0x080484b9 <main+313>:  mov    -0x10(%ebp),%edx             - 2 cycles x 1 
times     |
    0x080484bc <main+316>:  mov    %edx,%eax                    - 2 cycles x 1 
times     |
    0x080484be <main+318>:  shl    $0x8,%eax                    - 4 cycles x 1 
times     |
    0x080484c1 <main+321>:  sub    %edx,%eax                    - 1 cycles x 1 
times     |
    0x080484c3 <main+323>:  mov    %al,-0x24(%ebp)              - 2 cycles x 1 
times     |
                                                                                
         |
Total cycles time 11 cycles                                                     
         |
                                                                                
         |
optical_parameters[7] = (unsigned char)((tmp_coordinate>>8)*0x0f);              
         |
                                                                                
         |
    0x080484c6 <main+326>:  mov    -0x10(%ebp),%eax             - 2 cycles x 1 
times     |
    0x080484c9 <main+329>:  mov    %eax,%edx                    - 2 cycles x 1 
times     |
    0x080484cb <main+331>:  sar    $0x8,%edx                    - 1 cycles x 1 
times     |
    0x080484ce <main+334>:  mov    %edx,%eax                    - 2 cycles x 1 
times     |
    0x080484d0 <main+336>:  shl    $0x4,%eax                    - 4 cycles x 1 
times     |
    0x080484d3 <main+339>:  sub    %edx,%eax                    - 1 cycles x 1 
times     |
    0x080484d5 <main+341>:  mov    %al,-0x23(%ebp)              - 2 cycles x 1 
times     |
                                                                                
         |
Total cycles time 14 cycles                                                     
         |
Cycle of one set 66 10%                                                         
<<<<<<<<<|

tmp_coordinate = (long)(RY[value]);
tmp_coordinate = (tmp_coordinate*colour) >> 8;
optical_parameters[8] = (unsigned char)(tmp_coordinate*0xff);
optical_parameters[9] = (unsigned char)((tmp_coordinate>>8)*0x0f);

Total cycles time 66 cycles 10%

tmp_coordinate = (long)(GX[value]);
tmp_coordinate = (tmp_coordinate*colour) >> 8;
optical_parameters[10] = (unsigned char)(tmp_coordinate*0xff);
optical_parameters[11] = (unsigned char)((tmp_coordinate>>8)*0x0f);

Total cycles time 66 cycles 10%

tmp_coordinate = (long)(GY[value]);
tmp_coordinate = (tmp_coordinate*colour) >> 8;
optical_parameters[12] = (unsigned char)(tmp_coordinate*0xff);
optical_parameters[13] = (unsigned char)((tmp_coordinate>>8)*0x0f);

Total cycles time 66 cycles 10%

tmp_coordinate = (long)(BX[value]);
tmp_coordinate = (tmp_coordinate*colour) >> 8;
optical_parameters[14] = (unsigned char)(tmp_coordinate*0xff);
optical_parameters[15] = (unsigned char)((tmp_coordinate>>8)*0x0f);

Total cycles time 66 cycles 10%

tmp_coordinate = (long)(BY[value]);
tmp_coordinate = (tmp_coordinate*colour) >> 8;
optical_parameters[16] = (unsigned char)(tmp_coordinate*0xff);
optical_parameters[17] = (unsigned char)((tmp_coordinate>>8)*0x0f);

Total cycles time 66 cycles 10%

Execution time 657 cycles
if the clock frequency is 2G for i486 1 cycle= (1/f)*16 = 8nS + acces time to 
memory 400MHZ DDR2 -> 800MHz 1.25nS ~ total time for 1 cycle 2nS
Worst case time for cycle 10nS
Total worst case execution time of function 6.57uS.
 

Reply via email to