gfrm210: correct key logging and mapping.

The Home key sends 0002-0066-0009, which gets looked up in
hid_keyboard[] and was turning into keycode 116, which is
KEY_POWER. Send KEY_HOME instead.

We'll followup of whether GFRM210 can send the keycode on
a different usage page instead, not HID_UP_KEYBOARD.

Enable the other three keys KEY_PLAYPAUSE, KEY_VCR, and
KEY_VOICECOMMAND to be propagated up not turned into
KEY_UNKNOWN.

Fixes b/32577172

Change-Id: I9647bb22c13a8cde1d2d46170b0bbfcaf74dae34
diff --git a/drivers/hid/hid-gfrm.c b/drivers/hid/hid-gfrm.c
index 2950d9c..5992a92 100644
--- a/drivers/hid/hid-gfrm.c
+++ b/drivers/hid/hid-gfrm.c
@@ -29,6 +29,8 @@
 
 static u8 search_key_dn[3] = {0x40, 0x21, 0x02};
 static u8 search_key_up[3] = {0x40, 0x00, 0x00};
+static u8 home_key_dn[3] = {0x03, 0x66, 0x00};
+static u8 home_key_up[3] = {0x03, 0x66, 0x00};
 
 static const char* rawEventToButton(u8* data, int size)
 {
@@ -62,6 +64,7 @@
 		case 0x50:    return "LEFT";
 		case 0x51:    return "DOWN";
 		case 0x52:    return "UP";
+		case 0x66:    return "HOME";
 		}
 		break;
 
@@ -82,6 +85,7 @@
 		case 0x97:    return "INPUT";
 		case 0x9C:    return "CH_UP";
 		case 0x9D:    return "CH_DOWN";
+		case 0xA4:    return "PLAYPAUSE";
 		case 0xB0:    return "PLAY";
 		case 0xB1:    return "PAUSE";
 		case 0xB2:    return "RECORD";
@@ -93,8 +97,10 @@
 		case 0xE2:    return "MUTE";
 		case 0xE9:    return "VOL_UP";
 		case 0xEA:    return "VOL_DOWN";
+		case 0x17B:   return "DVR";
 		case 0x221:   return "SEARCH";
 		case 0x224:   return "BACK";
+		case 0x246:   return "VOICECOMMAND";
 		}
 		break;
 
@@ -274,36 +280,79 @@
 
 	logButton(hdev, report, data, size);
 
-	if (hdev_type != GFRM100)
+	if (hdev_type == GFRM100) {
+		if (size < 2 || data[0] != GFRM100_SEARCH_KEY_REPORT_ID)
+			return 0;
+
+		/*
+		 * Convert GFRM100 Search key reports into Consumer.0221
+		 * (Key.Search) reports. Send the audio data through unmodified.
+		 */
+		switch (data[1]) {
+		case GFRM100_SEARCH_KEY_DOWN:
+			ret = hid_report_raw_event(hdev, HID_INPUT_REPORT,
+						   search_key_dn,
+						   sizeof(search_key_dn), 1);
+			break;
+
+		case GFRM100_SEARCH_KEY_AUDIO_DATA:
+			ret = hid_report_raw_event(hdev, HID_INPUT_REPORT,
+						   data, size, 1);
+			break;
+
+		case GFRM100_SEARCH_KEY_UP:
+			ret = hid_report_raw_event(hdev, HID_INPUT_REPORT,
+						   search_key_up,
+						   sizeof(search_key_up), 1);
+			break;
+
+		default:
+			break;
+		}
+
+		return (ret < 0) ? ret : -1;
+	} else if (hdev_type == GFRM210) {
+		static int pending_release = 0;
+		/* GFRM210 rev 0.8/0.24 sends 020000660000000000 for the Home
+		 * button, which is mapped to the Keyboard usage page keycode
+		 * 116 which is a Power key.
+		 *
+		 * Remap it to 036600, which is the Consumer usage page. */
+		if ((size == 9) && (data[0] == 0x02) && (data[1] == 0x00) &&
+		    (data[2] == 0x00) && (data[3] == 0x66) &&
+		    (data[4] == 0x00) && (data[5] == 0x00) &&
+		    (data[6] == 0x00) && (data[7] == 0x00) &&
+		    (data[8] == 0x00)) {
+			pending_release = 1;
+			ret = hid_report_raw_event(hdev, HID_INPUT_REPORT,
+						   home_key_dn,
+						   sizeof(home_key_dn), 1);
+			/* -1 to suppress the original HID event report */
+			return (ret < 0) ? ret : -1;
+		} else if (pending_release && (size == 9) &&
+		    (data[0] == 0x02) && (data[1] == 0x00) &&
+		    (data[2] == 0x00) && (data[3] == 0x00) &&
+		    (data[4] == 0x00) && (data[5] == 0x00) &&
+		    (data[6] == 0x00) && (data[7] == 0x00) &&
+		    (data[8] == 0x00)) {
+			pending_release = 0;
+			ret = hid_report_raw_event(hdev, HID_INPUT_REPORT,
+						   home_key_up,
+						   sizeof(home_key_up), 1);
+			/* -1 to suppress the original HID event report */
+			return (ret < 0) ? ret : -1;
+		} else {
+			/* The RELEASE3 is supposed to come immediately after
+			 * the keypress. If there is any other event we must
+			 * have missed the release. Let the higher layer handle
+			 * it via timeout of the key repeat.
+			 */
+			pending_release = 0;
+			return 0;
+		}
+	} else {
 		return 0;
-
-	if (size < 2 || data[0] != GFRM100_SEARCH_KEY_REPORT_ID)
-		return 0;
-
-	/*
-	 * Convert GFRM100 Search key reports into Consumer.0221 (Key.Search)
-	 * reports. Send the audio data through unmodified.
-	 */
-	switch (data[1]) {
-	case GFRM100_SEARCH_KEY_DOWN:
-		ret = hid_report_raw_event(hdev, HID_INPUT_REPORT, search_key_dn,
-					   sizeof(search_key_dn), 1);
-		break;
-
-	case GFRM100_SEARCH_KEY_AUDIO_DATA:
-		ret = hid_report_raw_event(hdev, HID_INPUT_REPORT, data, size, 1);
-		break;
-
-	case GFRM100_SEARCH_KEY_UP:
-		ret = hid_report_raw_event(hdev, HID_INPUT_REPORT, search_key_up,
-					   sizeof(search_key_up), 1);
-		break;
-
-	default:
-		break;
 	}
-
-	return (ret < 0) ? ret : -1;
 }
 
 static int gfrm_input_configured(struct hid_device *hid, struct hid_input *hidinput)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 0975741..1003c05 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -772,6 +772,7 @@
 		case 0x061: map_key_clear(KEY_SUBTITLE);	break; /* Closed Caption */
 		case 0x063: map_key_clear(KEY_VCR);		break; /* VCR/TV */
 		case 0x065: map_key_clear(KEY_CAMERA);		break; /* Snapshot */
+		case 0x066: map_key_clear(KEY_HOME);		break;
 		case 0x069: map_key_clear(KEY_RED);		break;
 		case 0x06a: map_key_clear(KEY_GREEN);		break;
 		case 0x06b: map_key_clear(KEY_BLUE);		break;
@@ -810,6 +811,7 @@
 		case 0x09c: map_key_clear(KEY_CHANNELUP);	break;
 		case 0x09d: map_key_clear(KEY_CHANNELDOWN);	break;
 		case 0x0a0: map_key_clear(KEY_VCR2);		break;
+		case 0x0a4: map_key_clear(KEY_PLAYPAUSE);	break; /* GFRM210 Play/Pause */
 
 		case 0x0b0: map_key_clear(KEY_PLAY);		break;
 		case 0x0b1: map_key_clear(KEY_PAUSE);		break;
@@ -833,6 +835,8 @@
 		case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);	break;
 		case 0x0f5: map_key_clear(KEY_SLOW);		break;
 
+		case 0x17b: map_key_clear(KEY_VCR);		break; /* GFRM210 Dvr */
+
 		case 0x181: map_key_clear(KEY_BUTTONCONFIG);	break;
 		case 0x182: map_key_clear(KEY_BOOKMARKS);	break;
 		case 0x183: map_key_clear(KEY_CONFIG);		break;
@@ -899,6 +903,7 @@
 		case 0x234: map_key_clear(KEY_SCROLLDOWN);	break;
 		case 0x238: map_rel(REL_HWHEEL);		break;
 		case 0x23d: map_key_clear(KEY_EDIT);		break;
+		case 0x246: map_key_clear(KEY_VOICECOMMAND);	break; /* GFRM210 Voice search */
 		case 0x25f: map_key_clear(KEY_CANCEL);		break;
 		case 0x269: map_key_clear(KEY_INSERT);		break;
 		case 0x26a: map_key_clear(KEY_DELETE);		break;