[PATCH v4 23/24] hid: Port hid-lg4ff to ff-memless-next

2014-04-26 Thread Michal Malý
Port hid-lg4ff to ff-memless-next

Signed-off-by: Michal Malý 
Tested-by: Tested-by: Elias Vanderstuyft 
---
 drivers/hid/Kconfig |  2 +-
 drivers/hid/hid-lg4ff.c | 93 ++---
 2 files changed, 59 insertions(+), 36 deletions(-)

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 5e70519..546ac4a 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -399,7 +399,7 @@ config LOGIG940_FF
 config LOGIWHEELS_FF
bool "Logitech wheels configuration and force feedback support"
depends on HID_LOGITECH
-   select INPUT_FF_MEMLESS
+   select INPUT_FF_MEMLESS_NEXT
default LOGITECH_FF
help
  Say Y here if you want to enable force feedback and range setting
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index 24883b4..d629093 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -25,6 +25,7 @@
 
 
 #include 
+#include 
 #include 
 #include 
 
@@ -45,6 +46,8 @@
 #define G27_REV_MIN 0x38
 #define G27_2_REV_MIN 0x39
 
+#define FF_UPDATE_RATE 8
+
 #define to_hid_device(pdev) container_of(pdev, struct hid_device, dev)
 
 static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range);
@@ -69,6 +72,13 @@ struct lg4ff_device_entry {
 
 static const signed short lg4ff_wheel_effects[] = {
FF_CONSTANT,
+   FF_RAMP,
+   FF_PERIODIC,
+   FF_SQUARE,
+   FF_TRIANGLE,
+   FF_SINE,
+   FF_SAW_UP,
+   FF_SAW_DOWN,
FF_AUTOCENTER,
-1
 };
@@ -184,47 +194,60 @@ int lg4ff_adjust_input_event(struct hid_device *hid, 
struct hid_field *field,
}
 }
 
-static int hid_lg4ff_play(struct input_dev *dev, void *data, struct ff_effect 
*effect)
+static int hid_lg4ff_start_combined(struct hid_device *hid, struct hid_report 
*report,
+   const struct mlnx_simple_force *force)
+{
+   __s32 *value = report->field[0]->value;
+   int scaled_x;
+
+   /* Scale down from MLNX range */
+   scaled_x = 0x80 - (force->x * 0xff / 0x);
+
+   value[0] = 0x11;/* Slot 1 */
+   value[1] = 0x08;
+   value[2] = scaled_x;
+   value[3] = 0x80;
+   value[4] = 0x00;
+   value[5] = 0x00;
+   value[6] = 0x00;
+
+   hid_hw_request(hid, report, HID_REQ_SET_REPORT);
+   return 0;
+}
+
+static int hid_lg4ff_stop_combined(struct hid_device *hid, struct hid_report 
*report)
+{
+   __s32 *value = report->field[0]->value;
+
+   value[0] = 0x13;/* Slot 1 */
+   value[1] = 0x00;
+   value[2] = 0x00;
+   value[3] = 0x00;
+   value[4] = 0x00;
+   value[5] = 0x00;
+   value[6] = 0x00;
+
+   hid_hw_request(hid, report, HID_REQ_SET_REPORT);
+   return 0;
+}
+
+static int hid_lg4ff_control(struct input_dev *dev, void *data, const struct 
mlnx_effect_command *command)
 {
struct hid_device *hid = input_get_drvdata(dev);
struct list_head *report_list = 
&hid->report_enum[HID_OUTPUT_REPORT].report_list;
struct hid_report *report = list_entry(report_list->next, struct 
hid_report, list);
-   __s32 *value = report->field[0]->value;
-   int x;
-
-#define CLAMP(x) do { if (x < 0) x = 0; else if (x > 0xff) x = 0xff; } while 
(0)
-
-   switch (effect->type) {
-   case FF_CONSTANT:
-   x = effect->u.ramp.start_level + 0x80;  /* 0x80 is no force */
-   CLAMP(x);
-
-   if (x == 0x80) {
-   /* De-activate force in slot-1*/
-   value[0] = 0x13;
-   value[1] = 0x00;
-   value[2] = 0x00;
-   value[3] = 0x00;
-   value[4] = 0x00;
-   value[5] = 0x00;
-   value[6] = 0x00;
-
-   hid_hw_request(hid, report, HID_REQ_SET_REPORT);
-   return 0;
-   }
-
-   value[0] = 0x11;/* Slot 1 */
-   value[1] = 0x08;
-   value[2] = x;
-   value[3] = 0x80;
-   value[4] = 0x00;
-   value[5] = 0x00;
-   value[6] = 0x00;
 
-   hid_hw_request(hid, report, HID_REQ_SET_REPORT);
+   switch (command->cmd) {
+   case MLNX_START_COMBINED:
+   return hid_lg4ff_start_combined(hid, report, 
&command->u.simple_force);
+   break;
+   case MLNX_STOP_COMBINED:
+   return hid_lg4ff_stop_combined(hid, report);
break;
+   default:
+   dbg_hid("Unsupported effect command");
+   return -EINVAL;
}
-   return 0;
 }
 
 /* Sends default autocentering command compatible with
@@ -610,7 +633,7 @@ int lg4ff_init(struct hid_device *hid)
for (j = 0; lg4ff_devices[i].ff_effects[j] >= 0; j++)
set_bit(lg4ff_devices[i].ff_effects[j], dev->ffbit);
 
-   error = input_ff_create_memless(dev, NULL, hid_lg4ff_

Re: [PATCH v4 23/24] hid: Port hid-lg4ff to ff-memless-next

2014-04-29 Thread simon
> Port hid-lg4ff to ff-memless-next
>
> Signed-off-by: Michal Malý 
> Tested-by: Tested-by: Elias Vanderstuyft 

Signed-off-by: Simon Wood 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/