Index: uspace/lib/usb/src/hidparser.c
===================================================================
--- uspace/lib/usb/src/hidparser.c	(revision 57d9c05edc9538826f5cee0e24dd67049c5a02b9)
+++ uspace/lib/usb/src/hidparser.c	(revision 841e6e5b8b02d95d5bcb393f7dde3e59d9c79846)
@@ -71,4 +71,5 @@
 inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
 int usb_hid_translate_data(usb_hid_report_item_t *item, const uint8_t *data, size_t j);
+int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int32_t value);
 int usb_pow(int a, int b);
 
@@ -402,5 +403,4 @@
  * @return Error code
  */
-
 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
@@ -1103,5 +1103,5 @@
 	}
 	
-	// read the last outpu report item
+	// read the last output report item
 	usb_hid_report_item_t *last;
 	link_t *link;
@@ -1113,4 +1113,7 @@
 
 		uint8_t *buffer = malloc(sizeof(uint8_t) * (*size));
+		memset(buffer, 0, sizeof(uint8_t) * (*size));
+		usb_log_debug("output buffer: %s\n", usb_debug_str_buffer(buffer, *size, 0));
+
 		return buffer;
 	}
@@ -1128,4 +1131,5 @@
  */
 void usb_hid_report_output_free(uint8_t *output)
+
 {
 	if(output != NULL) {
@@ -1153,5 +1157,5 @@
 	
 	item = parser->output.next;
-	while(&parser->input != item) {
+	while(&parser->output != item) {
 		report_item = list_get_instance(item, usb_hid_report_item_t, link);
 		if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
@@ -1183,20 +1187,12 @@
                                     int32_t *data, size_t data_size)
 {
-	//TODO
-	//
-	//go throught output descriptor and 
-	// if path match then take data from the begin, translate them and
-	// or to the buffer
-	//
-	// it should be the reverse process to input translation
-	
 	usb_hid_report_item_t *report_item;
 	link_t *item;	
 	size_t idx=0;
 	int i=0;
-	int32_t field_value=0;
 	int32_t value=0;
-	int8_t mask;
-	int8_t offset;
+	int offset;
+	int length;
+	int32_t tmp_value;
 	
 	if(parser == NULL) {
@@ -1206,26 +1202,111 @@
 	item = parser->output.next;	
 	while(item != &parser->output) {
-		report_item = list_get_instance(item, usb_hid_report_item_t ,link);
-
-		if(idx > size) {
-			return EINVAL;
+		report_item = list_get_instance(item, usb_hid_report_item_t, link);
+
+		for(i=0; i<report_item->count; i++, idx++) {
+
+			if(idx >= data_size) {
+				break;
+			}
+
+			// translate data
+			if(USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)) {
+				value = report_item->logical_minimum;
+			}
+			else {
+				//variable item
+				value = usb_hid_translate_data_reverse(report_item, data[idx]);
+			}
+
+			if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) ||
+				((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
+//				// variable item
+				offset = report_item->offset + (i * report_item->size);
+				length = report_item->size;
+			}
+			else {
+				//bitmap
+				offset = report_item->offset;
+				length = report_item->size * report_item->count;
+			}
+
+			if((offset/8) == ((offset+length)/8)) {
+				// je to v jednom bytu
+				if(((size_t)(offset/8) >= size) || ((size_t)(offset+length)/8) >= size) {
+					break; // TODO ErrorCode
+				}
+
+				value = value << (8- ((offset+length)%8));
+				value = value & (((1 << length)-1) << (8- ((offset+length)%8)));
+				buffer[offset/8] = buffer[offset/8] | value;
+
+			}
+			else {
+				// je to ve dvou!! FIXME: melo by to umet delsi jak 2
+
+				// konec prvniho
+				tmp_value = value;
+				tmp_value = tmp_value >> (8 - (offset%8));
+				tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);
+				buffer[offset/8] = buffer[offset/8] | tmp_value;
+
+				// a ted druhej
+				value = value & (((1 << report_item->size) - ((8 - (offset%8))))-1);
+				buffer[(offset+length)/8] = buffer[(offset+length)/8] | value;
+			}
+
 		}
 
-		for(i=0; i<report_item->count; i++, idx++) {
-			// translate data
-			value = usb_hid_translate_data_output(report_item, data[idx]);
-
-			// pres kazdy byte v bufferu kteryho se to tyka
-			for(){
-				// vybrat ktera cast value patri do tohodle bytu
-				// shiftnout podle pozice
-				
-				//samotny vlozeni do bufferu
-				buffer[x+j] |= value[j];
-			}			
+		item = item->next;
+	}
+
+
+	return EOK;
+}
+
+/**
+ *
+ * @param item
+ * @param value
+ * @return
+ */
+int32_t usb_hid_translate_data_reverse(usb_hid_report_item_t *item, int value)
+{
+	int ret=0;
+	int resolution;
+
+	if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) ||
+		((item->usage_minimum == 0) && (item->usage_maximum == 0))) {
+
+		// variable item
+		if((item->physical_minimum == 0) && (item->physical_maximum == 0)) {
+			item->physical_minimum = item->logical_minimum;
+			item->physical_maximum = item->logical_maximum;
 		}
-	}
-
-	return EOK;
+
+		if(item->physical_maximum == item->physical_minimum){
+		    resolution = 1;
+		}
+		else {
+		    resolution = (item->logical_maximum - item->logical_minimum) /
+			((item->physical_maximum - item->physical_minimum) *
+			(usb_pow(10,(item->unit_exponent))));
+		}
+
+		ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum;
+	}
+	else {
+		// bitmapa
+		if(value == 0) {
+			ret = 0;
+		}
+		else {
+			size_t bitmap_idx = (value - item->usage_minimum);
+			ret = 1 << bitmap_idx;
+		}
+	}
+
+
+	return ret;
 }
 
