From 72946c9d98f6554f8d6225324545c38a41df70d0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Mal=C3=BD?= Date: Sun, 2 Aug 2015 23:31:53 +0200 Subject: [PATCH] Add support for autocentering --- klgd_ff_plugin.c | 35 ++++++++++++++++++++++++++++++++++- klgd_ff_plugin.h | 6 ++++-- klgd_ff_plugin_p.h | 7 +++++-- klgdff.c | 21 ++++++++++++++++++++- 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/klgd_ff_plugin.c b/klgd_ff_plugin.c index d797529..3a2b7c0 100644 --- a/klgd_ff_plugin.c +++ b/klgd_ff_plugin.c @@ -495,6 +495,14 @@ static int ffpl_upload_effect(struct klgd_plugin_private *priv, struct klgd_comm return 0; } +static int ffpl_set_autocenter(struct klgd_plugin_private *priv, struct klgd_command_stream *s) +{ + union ffpl_control_data data; + + data.autocenter = priv->autocenter; + return priv->control(priv->dev, s, FFPL_SET_AUTOCENTER, data); +} + static int ffpl_set_gain(struct klgd_plugin_private *priv, struct klgd_command_stream *s) { union ffpl_control_data data; @@ -610,6 +618,19 @@ static int ffpl_upload_rq(struct input_dev *dev, struct ff_effect *effect, struc return 0; } +static void ffpl_set_autocenter_rq(struct input_dev *dev, u16 autocenter) +{ + struct klgd_plugin *self = dev->ff->private; + struct klgd_plugin_private *priv = self->private; + + klgd_lock_plugins(self->plugins_lock); + + priv->autocenter = autocenter; + priv->change_autocenter = true; + + klgd_unlock_plugins_sched(self->plugins_lock); +} + static void ffpl_set_gain_rq(struct input_dev *dev, u16 gain) { struct klgd_plugin *self = dev->ff->private; @@ -921,6 +942,12 @@ static int ffpl_get_commands(struct klgd_plugin *self, struct klgd_command_strea if (!s) return -EAGAIN; + if (priv->change_autocenter) { + ret = ffpl_set_autocenter(priv, *s); + if (ret) + goto out; + priv->change_autocenter = false; + } if (priv->change_gain) { ret = ffpl_set_gain(priv, *s); if (ret) @@ -966,7 +993,7 @@ static bool ffpl_get_update_time(struct klgd_plugin *self, const unsigned long n unsigned long events = 0; /* Handle device-wide changes first */ - if (priv->change_gain) { + if (priv->change_gain || priv->change_autocenter) { *t = now; return true; } @@ -1213,6 +1240,7 @@ static int ffpl_init(struct klgd_plugin *self) dev->ff->playback = ffpl_playback_rq; dev->ff->upload = ffpl_upload_rq; dev->ff->set_gain = ffpl_set_gain_rq; + dev->ff->set_autocenter = ffpl_set_autocenter_rq; dev->ff->destroy = ffpl_destroy_rq; printk(KERN_NOTICE "KLGDFF: Init complete\n"); @@ -1294,6 +1322,11 @@ int ffpl_init_plugin(struct klgd_plugin **plugin, struct input_dev *dev, const s priv->has_native_gain = true; printk(KERN_NOTICE "KLGDFF: Using HAS_NATIVE_GAIN\n"); } + if (FFPL_HAS_AUTOCENTER & flags) { + priv->has_autocenter = true; + set_bit(FF_AUTOCENTER, dev->ffbit); + printk(KERN_NOTICE "KLGDFF: Using HAS_AUTOCENTER\n"); + } set_bit(FF_GAIN, dev->ffbit); for (idx = 0; idx <= (FF_WAVEFORM_MAX - FF_EFFECT_MIN); idx++) { diff --git a/klgd_ff_plugin.h b/klgd_ff_plugin.h index aee7378..748163b 100644 --- a/klgd_ff_plugin.h +++ b/klgd_ff_plugin.h @@ -11,6 +11,7 @@ #define FFPL_REPLACE_UPLOADED BIT(4) /* Device can accept a new effect to UPLOADED state without the need to explicitly stop and erase the previously uploaded effect beforehand */ #define FFPL_REPLACE_STARTED BIT(5) /* Device can accept a new effect to STARTED state without the need to explicitly stop and erase the previously uploaded effect beforehand */ #define FFPL_HAS_NATIVE_GAIN BIT(15) /* Device can adjust the gain by itself */ +#define FFPL_HAS_AUTOCENTER BIT(16) /* Device supports autocentering */ enum ffpl_control_command { /* Force feedback state transitions */ @@ -25,7 +26,8 @@ enum ffpl_control_command { FFPL_OWR_TO_UPL, /* Overwrite an effect with a new one and set its state to UPLOADED */ FFPL_OWR_TO_SRT, /* Overwrite an effect with a new one and set its state to STARTED */ - FFPL_SET_GAIN /* Set gain */ + FFPL_SET_GAIN, /* Set gain */ + FFPL_SET_AUTOCENTER /*Set autocenter */ }; struct ffpl_effects { @@ -36,7 +38,7 @@ struct ffpl_effects { union ffpl_control_data { struct ffpl_effects effects; - u16 ac_magnitude; + u16 autocenter; u16 gain; }; diff --git a/klgd_ff_plugin_p.h b/klgd_ff_plugin_p.h index 5a0c9a9..bd0f4f3 100644 --- a/klgd_ff_plugin_p.h +++ b/klgd_ff_plugin_p.h @@ -53,6 +53,7 @@ struct klgd_plugin_private { struct input_dev *dev; int (*control)(struct input_dev *dev, struct klgd_command_stream *s, const enum ffpl_control_command cmd, const union ffpl_control_data data); u16 gain; + u16 autocenter; /* Optional device capabilities */ bool has_emp_to_srt; bool has_srt_to_emp; @@ -61,8 +62,10 @@ struct klgd_plugin_private { bool has_owr_to_upl; bool has_owr_to_srt; bool has_native_gain; - u32 padding_caps:25; + bool has_autocenter; + u32 padding_caps:24; /* Device-wide state changes */ bool change_gain; - u32 padding_dw:31; + bool change_autocenter; + u32 padding_dw:30; }; diff --git a/klgdff.c b/klgdff.c index 1b9012e..747ad01 100644 --- a/klgdff.c +++ b/klgdff.c @@ -13,6 +13,7 @@ static struct input_dev *dev; static struct klgd_main klgd; static struct klgd_plugin *ff_plugin; static u16 gain; +static u16 autocenter; static int klgdff_erase(struct klgd_command_stream *s, const struct ff_effect *effect) { @@ -70,6 +71,22 @@ static int klgdff_er_stop(struct klgd_command_stream *s, const struct ff_effect return klgd_append_cmd(s, c); } +static int klgdff_set_autocenter(struct klgd_command_stream *s, const u16 _autocenter) +{ + char *text = kasprintf(GFP_KERNEL, "Setting autocenter to: %u", _autocenter); + size_t len = strlen(text); + struct klgd_command *c = klgd_alloc_cmd(len + 1); + + if (!c) + return -ENOMEM; + + autocenter = _autocenter; + + memcpy(c->bytes, text, len); + kfree(text); + return klgd_append_cmd(s, c); +} + static int klgdff_set_gain(struct klgd_command_stream *s, const u16 _gain) { char *text = kasprintf(GFP_KERNEL, "Setting gain to: %u", _gain); @@ -271,6 +288,8 @@ int klgdff_control(struct input_dev *dev, struct klgd_command_stream *s, const e break; case FFPL_SET_GAIN: return klgdff_set_gain(s, data.gain); + case FFPL_SET_AUTOCENTER: + return klgdff_set_autocenter(s, data.autocenter); default: printk(KERN_NOTICE "KLGDFF-TD - Unhandled command\n"); break; @@ -333,7 +352,7 @@ static int __init klgdff_init(void) input_set_abs_params(dev, ABS_Y, -0x7fff, 0x7fff, 0, 0); ret = ffpl_init_plugin(&ff_plugin, dev, EFFECT_COUNT, ffbits, - FFPL_HAS_EMP_TO_SRT | FFPL_REPLACE_STARTED, + FFPL_HAS_EMP_TO_SRT | FFPL_REPLACE_STARTED | FFPL_HAS_AUTOCENTER, klgdff_control); if (ret) { printk(KERN_ERR "KLGDFF-TD: Cannot init plugin\n"); -- 2.43.5