]> Devoid-pointer.net GitWeb - KLGD_FF_plugin.git/commitdiff
First take at implementation of combinable effects.
authorMichal Malý <madcatxster@devoid-pointer.net>
Sun, 21 Jun 2015 00:41:48 +0000 (02:41 +0200)
committerMichal Malý <madcatxster@devoid-pointer.net>
Sun, 21 Jun 2015 00:41:48 +0000 (02:41 +0200)
Lots of stuff changed and moved around. Debugging messages have been
updated to a more standardized form. Only FF_CONSTANT can be combined at
this point and the combining is not configurable.

klgd_ff_plugin.c
klgd_ff_plugin_p.h
klgdff.c

index 43c63bbfa81e3948d72e87862a37d435e21e7bd9..0c647ed29b825e43ca93070f0de84d1728c12129 100644 (file)
@@ -1,9 +1,164 @@
 #include "klgd_ff_plugin_p.h"
 #include <linux/slab.h>
+#include <linux/fixp-arith.h>
 
+#define DIR_TO_DEGREES(dir) (360 - ((((dir > 0xc000) ? (u32)dir + 0x4000 - 0xffff : (u32)dir + 0x4000) * 360) / 0xffff))
+
+static int ffpl_handle_state_change(struct klgd_plugin_private *priv, struct klgd_command_stream *s, struct ffpl_effect *eff,
+                                   const bool ignore_combined);
 static bool ffpl_has_gain(const struct ff_effect *eff);
 static bool ffpl_needs_replacing(const struct ff_effect *ac_eff, const struct ff_effect *la_eff);
 
+static u16 ffpl_degrees_from_x_y(const int x, const int y)
+{
+       u16 degrees;
+       /* Precalculated tan() values expanded by FRAC_N */
+       static const unsigned int precalc_tan[] = {0, 4, 8, 13, 17, 22, 26, 31, 35, 40,                                 /* 0 - 9 deg */
+                                                  45, 49, 54, 59, 63, 68, 73, 78, 83, 88,                              /* 10 - 19 deg */
+                                                  93, 98, 108, 113, 119, 124, 130, 136, 141,                           /* 20 - 29 deg */
+                                                  147, 153, 159, 166, 172, 179, 185, 192, 200, 207,                    /* 30 - 39 deg */
+                                                  214, 222, 230, 238, 247, 255, 265, 274, 284, 294,                    /* 40 - 49 deg */
+                                                  305, 316, 327, 339, 352, 365, 379, 394, 409, 426,                    /* 50 - 59 deg */
+                                                  443, 461, 481, 502, 524, 548, 574, 603, 633, 666,                    /* 60 - 69 deg */
+                                                  703, 743, 787, 837, 892, 955, 1026, 1108, 1204, 1317,                /* 70 - 79 deg */
+                                                  1451, 1616, 1821, 2084, 2435, 2926, 3660, 4884, 7330, 14666};        /* 80 - 89 deg */
+
+       for (degrees = 0; degrees < ARRAY_SIZE(precalc_tan); degrees++) {
+               unsigned int tan = (abs(y) << FRAC_N) / abs(x);
+               if (tan <= precalc_tan[degrees])
+                       return degrees;
+       }
+
+       return 90;
+}
+
+static void ffpl_x_y_to_lvl_dir(const int x, const int y, s16 *level, u16 *direction)
+{
+       const u16 angle = (x == 0) ? 90 : ffpl_degrees_from_x_y(x, y);
+
+       printk(KERN_NOTICE "KLGDFF: Angle = %u\n", angle);
+       *level = int_sqrt(x * x + y * y);
+       /* 1st quadrant */
+       if (x >= 0 && y >= 0)
+               *direction = ((270 - angle) * 0xffff) / 360;
+       /* 2nd quadrant */
+       else if (x < 0 && y >= 0)
+               *direction = ((90 + angle) * 0xffff) / 360;
+       /* 3rd quadrant */
+       else if (x < 0 && y < 0)
+               *direction = ((90 - angle) * 0xffff) / 360;
+       /* 4th quadrant */
+       else if (x > 0 && y < 0)
+               *direction = ((270 + angle) * 0xffff) / 360;
+       else
+               *direction = 0;
+}
+
+static bool ffpl_is_combinable(const struct ff_effect *eff)
+{
+       /* TODO: Proper decision of what is a combinable effect */
+       return eff->type == FF_CONSTANT;
+}
+
+
+bool ffpl_constant_force_to_x_y(const struct ff_effect *eff, int *x, int *y)
+{
+       int degrees;
+
+       if (eff->type != FF_CONSTANT)
+               return false;
+
+       degrees = DIR_TO_DEGREES(eff->direction);
+       printk(KERN_NOTICE "KLGDFF: DIR_TO_DEGREES > Dir: %u, Deg: %u\n", eff->direction, degrees);
+       *x += (eff->u.constant.level * fixp_cos(degrees)) >> FRAC_N;
+       *y += (eff->u.constant.level * fixp_sin(degrees)) >> FRAC_N;
+
+       return true;
+}
+
+static void ffpl_recalc_combined(struct klgd_plugin_private *priv)
+{
+       size_t idx;
+       struct ff_effect *cb_latest = &priv->combined_effect.latest;
+       int x = 0;
+       int y = 0;
+
+       for (idx = 0; idx < priv->effect_count; idx++) {
+               const struct ffpl_effect *eff = &priv->effects[idx];
+
+               switch (eff->change) {
+               case FFPL_DONT_TOUCH:
+                       if (eff->state != FFPL_STARTED)
+                               break;
+               case FFPL_TO_START:
+               case FFPL_TO_UPDATE:
+                       ffpl_constant_force_to_x_y(&eff->latest, &x, &y);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ffpl_x_y_to_lvl_dir(x, y, &cb_latest->u.constant.level, &cb_latest->direction);
+       cb_latest->type = FF_CONSTANT;
+       printk(KERN_NOTICE "KLGDFF: Resulting combined CF effect > x: %d, y: %d, level: %d, direction: %d\n", x, y, cb_latest->u.constant.level,
+              cb_latest->direction);
+}
+
+static int ffpl_handle_combinable_effects(struct klgd_plugin_private *priv, struct klgd_command_stream *s)
+{
+       size_t idx;
+       bool needs_update = false;
+       size_t active_effects = 0;
+
+       for (idx = 0; idx < priv->effect_count; idx++) {
+               struct ffpl_effect *eff = &priv->effects[idx];
+
+               if (!ffpl_is_combinable(&eff->latest))
+                       continue;
+
+               switch (eff->change) {
+               case FFPL_DONT_TOUCH:
+                       if (eff->state == FFPL_STARTED)
+                               active_effects++;
+                       printk(KERN_NOTICE "KLGDFF: Unchanged combinable effect, total active effects %lu\n", active_effects);
+                       break;
+               case FFPL_TO_START:
+                       eff->state = FFPL_STARTED;
+                       eff->active = eff->latest;
+               case FFPL_TO_UPDATE:
+                       active_effects++;
+                       needs_update = true;
+                       printk(KERN_NOTICE "KLGDFF: Altered combinable effect, total active effects %lu\n", active_effects);
+                       break;
+               default:
+                       needs_update = true;
+                       eff->state = FFPL_EMPTY;
+                       printk(KERN_NOTICE "KLGDFF: Stopped combinable effect, total active effects %lu\n", active_effects);
+                       break;
+               }
+       }
+
+       /* Combined effect needs recalculation */
+       if (needs_update) {
+               if (active_effects) {
+                       printk(KERN_NOTICE "KLGDFF: Combined effect needs an update, total effects active: %lu\n", active_effects);
+                       ffpl_recalc_combined(priv);
+                       if (priv->combined_effect.state == FFPL_STARTED)
+                               priv->combined_effect.change = FFPL_TO_UPDATE;
+                       else
+                               priv->combined_effect.change = FFPL_TO_START;
+
+                       return 0;
+               }
+               /* No combinable effects are active, remove the effect from device */
+               printk(KERN_NOTICE "KLGDFF: No combinable effects are active, erase the combined effect from device\n");
+               priv->combined_effect.change = FFPL_TO_ERASE;
+       }
+
+       return 0;
+}
+
 static int ffpl_erase_effect(struct klgd_plugin_private *priv, struct klgd_command_stream *s, struct ffpl_effect *eff)
 {
        if (eff->uploaded_to_device) {
@@ -204,6 +359,7 @@ static int ffpl_upload_rq(struct input_dev *dev, struct ff_effect *effect, struc
        eff->latest = *effect;
 
        if (eff->state != FFPL_EMPTY) {
+               printk(KERN_NOTICE "KLGDFF: Updating effect in slot %d\n", effect->id);
                if (ffpl_needs_replacing(&eff->active, &eff->latest)) {
                        eff->replace = true;
                        eff->change = FFPL_TO_UPLOAD;
@@ -251,200 +407,246 @@ static struct klgd_command_stream * ffpl_get_commands(struct klgd_plugin *self,
        struct klgd_plugin_private *priv = self->private;
        struct klgd_command_stream *s;
        size_t idx;
+       int ret;
 
        s = klgd_alloc_stream();
        if (!s)
                return NULL; /* TODO: Error handling */
   
+       ret = ffpl_handle_combinable_effects(priv, s);
+       if (ret)
+               printk(KERN_WARNING "KLGDFF: Cannot process combinable effects, ret %d\n", ret);
+
        for (idx = 0; idx < priv->effect_count; idx++) {
                struct ffpl_effect *eff = &priv->effects[idx];
-               int ret = 0;
-
-               printk(KERN_NOTICE "KLGDFF - Processing effect %lu\n", idx);
-               /* Latest effect is of different type than currently active effect,
-                * remove it from the device and upload the latest one */
-               if (eff->replace) {
-                       switch (eff->change) {
-                       case FFPL_TO_ERASE:
-                               printk("KLGDFF - Rpl chg - TO_ERASE\n");
-                               switch (eff->state) {
-                               case FFPL_STARTED:
-                                       ret = ffpl_stop_effect(priv, s, eff);
-                                       if (ret)
-                                               break;
-                               case FFPL_UPLOADED:
-                                       ret = ffpl_erase_effect(priv, s, eff);
-                                       /* TODO: Handle error */
-                               default:
-                                       /* Nothing to do - the effect that is replacing the old effect is about to be erased anyway 
-                                        * State of the effect to be replaced should also never be EMPTY */
-                                       break;
-                               }
-                               break;
-                       case FFPL_TO_UPLOAD:
-                       case FFPL_TO_STOP: /* There is no difference between stopping or uploading an effect when we are replacing it */
-                               printk("KLGDFF - Rpl chg - TO_UPLOAD/TO_STOP\n");
-                               switch (eff->state) {
-                               case FFPL_STARTED:
-                                       /* Overwrite the currently active effect and set it to UPLOADED state */
-                                       if (priv->has_owr_to_upl) {
-                                               ret = ffpl_replace_effect(priv, s, eff, FFPL_OWR_TO_UPL);
-                                               if (ret)
-                                                       break;
-                                               continue;
-                                       }
-                                       ret = ffpl_stop_effect(priv, s, eff);
-                                       if (ret)
-                                               break;
-                               case FFPL_UPLOADED:
-                                       ret = ffpl_erase_effect(priv, s, eff);
-                                       if (ret)
-                                               break;
-                               case FFPL_EMPTY: /* State cannot actually be FFPL_EMPTY becuase only uploaded or started effects have to be replaced like this */
-                                       ret = ffpl_upload_effect(priv, s, eff);
-                                       break;
-                               }
-                               break;
-                       case FFPL_TO_START:
-                       case FFPL_TO_UPDATE: /* There is no difference between staring or updating an effect when we are replacing it */
-                               printk("KLGDFF - Rpl chg - TO_START/TO_UPDATE\n");
-                               switch (eff->state) {
-                               case FFPL_STARTED:
-                                       if (priv->has_owr_to_srt) {
-                                               ret = ffpl_replace_effect(priv, s, eff, FFPL_OWR_TO_SRT);
-                                               if (ret)
-                                                       break;
-                                               continue;
-                                       }
-                                       ret = ffpl_stop_effect(priv, s, eff);
-                                       if (ret)
-                                               break;
-                               case FFPL_UPLOADED:
-                                       ret = ffpl_erase_effect(priv, s, eff);
-                                       if (ret)
-                                               break;
-                               case FFPL_EMPTY: /* State cannot actually be FFPL_EMPTY - same as above applies */
-                                       ret = ffpl_upload_effect(priv, s, eff);
-                                       if (ret)
-                                               break;
-                                       ret = ffpl_start_effect(priv, s, eff);
-                                       break;
-                               }
-                               break;
-                       case FFPL_DONT_TOUCH:
-                               printk(KERN_WARNING "Got FFPL_DONT_TOUCH change for effect that should be replaced - this should not happen!\n");
-                               break;
-                       default:
-                               printk(KERN_WARNING "Unhandled state change while replacing effect\n");
-                               break;
-                       }
-                       if (ret)
-                               printk(KERN_WARNING "Error %d while replacing effect %lu\n", ret, idx);
-                       else {
-                               eff->replace = false;
-                               eff->change = FFPL_DONT_TOUCH;
-                               continue;
-                       }
-               }
 
+               printk(KERN_NOTICE "KLGDFF: Processing effect %lu\n", idx);
+               ret = ffpl_handle_state_change(priv, s, eff, true);
+               /* TODO: Do something useful with the return code */
+               if (ret)
+                       printk(KERN_WARNING "KLGDFF: Cannot get command stream effect %lu\n", idx);
+       }
+
+       /* Handle combined effect here */
+       ret = ffpl_handle_state_change(priv, s, &priv->combined_effect, false);
+       if (ret)
+               printk(KERN_WARNING "KLGDFF: Cannot get command stream for combined effect\n");
+
+       return s;
+}
+
+static bool ffpl_get_update_time(struct klgd_plugin *self, const unsigned long now, unsigned long *t)
+{
+       struct klgd_plugin_private *priv = self->private;
+       size_t idx, events = 0;
+
+       for (idx = 0; idx < priv->effect_count; idx++) {
+               struct ffpl_effect *eff = &priv->effects[idx];
+
+               /* Tell KLGD to attend to us as soon as possible if an effect has to change state */
+               if (eff->change == FFPL_DONT_TOUCH)
+                       continue;
+               *t = now;
+               events++;
+       }
+
+       return events ? true : false;
+}
+
+static int ffpl_handle_state_change(struct klgd_plugin_private *priv, struct klgd_command_stream *s, struct ffpl_effect *eff,
+                                   const bool ignore_combined)
+{
+       int ret;
+       
+       /* Latest effect is of different type than currently active effect,
+        * remove it from the device and upload the latest one */
+       if (eff->replace) {
                switch (eff->change) {
-               case FFPL_TO_UPLOAD:
-                       printk(KERN_INFO "KLGDFF - Chg TO_UPLOAD\n");
+               case FFPL_TO_ERASE:
+                       printk(KERN_NOTICE "KLGDFF: Rpl chg - TO_ERASE\n");
                        switch (eff->state) {
-                       case FFPL_EMPTY:
-                               ret = ffpl_upload_effect(priv, s, eff);
-                               break;
                        case FFPL_STARTED:
                                ret = ffpl_stop_effect(priv, s, eff);
-                               break;
+                               if (ret)
+                                       break;
+                       case FFPL_UPLOADED:
+                               ret = ffpl_erase_effect(priv, s, eff);
+                               if (ret)
+                                       break;
                        default:
+                               /* Nothing to do - the effect that is replacing the old effect is about to be erased anyway 
+                                * State of the effect to be replaced should also never be EMPTY */
+                               ret = 0;
                                break;
                        }
                        break;
-               case FFPL_TO_START:
-                       printk(KERN_INFO "KLGDFF - Chg TO_START\n");
+               case FFPL_TO_UPLOAD:
+               case FFPL_TO_STOP: /* There is no difference between stopping or uploading an effect when we are replacing it */
+                       printk("KLGDFF: Rpl chg - TO_UPLOAD/TO_STOP\n");
                        switch (eff->state) {
-                       case FFPL_EMPTY:
-                               if (priv->has_emp_to_srt) {
-                                       ret = ffpl_start_effect(priv, s, eff);
+                       case FFPL_STARTED:
+                               /* Overwrite the currently active effect and set it to UPLOADED state */
+                               if (priv->has_owr_to_upl) {
+                                       ret = ffpl_replace_effect(priv, s, eff, FFPL_OWR_TO_UPL);
                                        break;
                                }
-                               ret = ffpl_upload_effect(priv, s, eff);
+                               ret = ffpl_stop_effect(priv, s, eff);
                                if (ret)
                                        break;
                        case FFPL_UPLOADED:
-                               ret = ffpl_start_effect(priv, s, eff);
+                               ret = ffpl_erase_effect(priv, s, eff);
+                               if (ret)
+                                       break;
+                       case FFPL_EMPTY: /* State cannot actually be FFPL_EMPTY becuase only uploaded or started effects have to be replaced like this */
+                               /* Combinable effects are taken care of elsewhere and should not be uploaded individually */
+                               if (!ffpl_is_combinable(&eff->latest))
+                                       ret = ffpl_upload_effect(priv, s, eff);
+                               else
+                                       ret = 0;
                                break;
                        default:
-                               break;
+                               printk(KERN_WARNING "KLGDFF: Unhandled effect state\n");
+                               ret = -EINVAL;
                        }
                        break;
-               case FFPL_TO_STOP:
-                       printk(KERN_INFO "KLGDFF - Chg TO_STOP\n");
+               case FFPL_TO_START:
+               case FFPL_TO_UPDATE: /* There is no difference between staring or updating an effect when we are replacing it */
+                       printk("KLGDFF: Rpl chg - TO_START/TO_UPDATE\n");
                        switch (eff->state) {
                        case FFPL_STARTED:
+                               if (priv->has_owr_to_srt) {
+                                       ret = ffpl_replace_effect(priv, s, eff, FFPL_OWR_TO_SRT);
+                                       break;
+                               }
                                ret = ffpl_stop_effect(priv, s, eff);
-                               break;
-                       case FFPL_EMPTY:
-                               ret = ffpl_upload_effect(priv, s, eff);
-                               break;
-                       default:
-                               break;
-                       }
-                       break;
-               case FFPL_TO_ERASE:
-                       printk(KERN_INFO "KLGDFF - Chg TO_ERASE\n");
-                       switch (eff->state) {
+                               if (ret)
+                                       break;
                        case FFPL_UPLOADED:
                                ret = ffpl_erase_effect(priv, s, eff);
-                               break;
-                       case FFPL_STARTED:
-                               ret = ffpl_stop_effect(priv, s, eff);
                                if (ret)
                                        break;
-                               ret = ffpl_erase_effect(priv, s, eff);
+                       case FFPL_EMPTY: /* State cannot actually be FFPL_EMPTY - same as above applies */
+                               /* Combinable effects are taken care of elsewhere and should not be uploaded and started individually */
+                               if (ffpl_is_combinable(&eff->latest)) {
+                                       ret = 0;
+                                       break;
+                               }
+                               ret = ffpl_upload_effect(priv, s, eff);
+                               if (ret)
+                                       break;
+                               ret = ffpl_start_effect(priv, s, eff);
                                break;
                        default:
+                               printk(KERN_WARNING "KLGDFF: Unhandled effect state\n");
+                               ret = -EINVAL;
                                break;
                        }
                        break;
-               case FFPL_TO_UPDATE:
-                       printk(KERN_INFO "KLGDFF - Chg TO_UPDATE\n");
-                       ret = ffpl_update_effect(priv, s, eff);
-                       break;
                case FFPL_DONT_TOUCH:
-                       printk(KERN_INFO "KLGDFF - Chg - NO CHANGE\n");
-                       continue;
+                       printk(KERN_WARNING "KLGDFF: Got FFPL_DONT_TOUCH change for effect that should be replaced - this should not happen!\n");
+                       ret = -EINVAL;
+                       break;
                default:
-                       pr_debug("Unhandled state\n");
+                       printk(KERN_WARNING "KLGDFF: Unhandled state change while replacing effect\n");
+                       ret = -EINVAL;
+                       break;
                }
-
-               /* TODO: Handle errors */
                if (ret)
-                       printk(KERN_WARNING "Error %d while processing effect %lu\n", ret, idx);
-               else
-                       eff->change = FFPL_DONT_TOUCH;
-       }
-
-       return s;
-}
+                       printk(KERN_WARNING "KLGDFF: Error %d while replacing effect\n", ret);
 
-static bool ffpl_get_update_time(struct klgd_plugin *self, const unsigned long now, unsigned long *t)
-{
-       struct klgd_plugin_private *priv = self->private;
-       size_t idx, events = 0;
+               eff->replace = false;
+               eff->change = FFPL_DONT_TOUCH;
+               return ret;
+       }
 
-       for (idx = 0; idx < priv->effect_count; idx++) {
-               struct ffpl_effect *eff = &priv->effects[idx];
+       /* Combinable effects have already been handled, do not try to handle then again individually */
+       if (ffpl_is_combinable(&eff->latest) && ignore_combined) {
+               printk(KERN_NOTICE "KLGDFF: Effect is combinable\n");
+               ret = 0;
+               goto out;
+       }
 
-               /* Tell KLGD to attend to us as soon as possible if an effect has to change state */
-               if (eff->change == FFPL_DONT_TOUCH)
-                       continue;
-               *t = now;
-               events++;
+       switch (eff->change) {
+       case FFPL_TO_UPLOAD:
+               printk(KERN_INFO "KLGDFF: Chg TO_UPLOAD\n");
+               switch (eff->state) {
+               case FFPL_EMPTY:
+                       ret = ffpl_upload_effect(priv, s, eff);
+                       break;
+               case FFPL_STARTED:
+                       ret = ffpl_stop_effect(priv, s, eff);
+                       break;
+               default:
+                       ret = 0;
+                       break;
+               }
+               break;
+       case FFPL_TO_START:
+               printk(KERN_INFO "KLGDFF: Chg TO_START\n");
+               switch (eff->state) {
+               case FFPL_EMPTY:
+                       if (priv->has_emp_to_srt) {
+                               ret = ffpl_start_effect(priv, s, eff);
+                               break;
+                       }
+                       ret = ffpl_upload_effect(priv, s, eff);
+                       if (ret)
+                               return ret;
+               case FFPL_UPLOADED:
+                       ret = ffpl_start_effect(priv, s, eff);
+                       break;
+               default:
+                       ret = 0;
+                       break;
+               }
+               break;
+       case FFPL_TO_STOP:
+               printk(KERN_INFO "KLGDFF: Chg TO_STOP\n");
+               switch (eff->state) {
+               case FFPL_STARTED:
+                       ret = ffpl_stop_effect(priv, s, eff);
+                       break;
+               case FFPL_EMPTY:
+                       ret = ffpl_upload_effect(priv, s, eff);
+                       break;
+               default:
+                       ret = 0;
+                       break;
+               }
+               break;
+       case FFPL_TO_ERASE:
+               printk(KERN_INFO "KLGDFF: Chg TO_ERASE\n");
+               switch (eff->state) {
+               case FFPL_UPLOADED:
+                       ret = ffpl_erase_effect(priv, s, eff);
+                       break;
+               case FFPL_STARTED:
+                       ret = ffpl_stop_effect(priv, s, eff);
+                       if (ret)
+                               break;
+                       ret = ffpl_erase_effect(priv, s, eff);
+                       break;
+               default:
+                       ret = 0;
+                       break;
+               }
+               break;
+       case FFPL_TO_UPDATE:
+               printk(KERN_INFO "KLGDFF: Chg TO_UPDATE\n");
+               ret = ffpl_update_effect(priv, s, eff);
+               break;
+       case FFPL_DONT_TOUCH:
+               printk(KERN_INFO "KLGDFF: Chg - NO CHANGE\n");
+               return 0;
+       default:
+               return -EINVAL;
+               pr_debug("KLGDFF: Unhandled effect state change\n");
        }
 
-       return events ? true : false;
+out:
+       eff->change = FFPL_DONT_TOUCH;
+
+       return ret;
 }
 
 static bool ffpl_has_gain(const struct ff_effect *eff)
@@ -559,6 +761,7 @@ int ffpl_init_plugin(struct klgd_plugin **plugin, struct input_dev *dev, const s
                        input_set_capability(dev, EV_FF, idx + FF_EFFECT_MIN);
                }
        }
+
        return 0;
 
 err_out2:
@@ -571,17 +774,17 @@ err_out1:
 static bool ffpl_needs_replacing(const struct ff_effect *ac_eff, const struct ff_effect *la_eff)
 {
        if (ac_eff->type != la_eff->type) {
-               printk(KERN_NOTICE "KLGDFF - Effects are of different type - replacing (%d x %d)\n", ac_eff->type, la_eff->type);
+               printk(KERN_NOTICE "KLGDFF: Effects are of different type - replacing (%d x %d)\n", ac_eff->type, la_eff->type);
                return true;
        }
 
        if (ac_eff->type == FF_PERIODIC) {
                if (ac_eff->u.periodic.waveform != la_eff->u.periodic.waveform) {
-                       printk(KERN_NOTICE "KLGDFF - Effects have different waveforms - replacing\n");
+                       printk(KERN_NOTICE "KLGDFF: Effects have different waveforms - replacing\n");
                        return true;
                }
        }
 
-       printk(KERN_NOTICE "KLGDFF - Effect does not have to be replaced, updating\n");
+       printk(KERN_NOTICE "KLGDFF: Effect does not have to be replaced, updating\n");
        return false;
 }
index c45c8c678e51a75e42135655e558057ff47ba99f..14e53d8728163efe9d7481e5cc019263222689be 100644 (file)
@@ -29,6 +29,7 @@ struct ffpl_effect {
 
 struct klgd_plugin_private {
        struct ffpl_effect *effects;
+       struct ffpl_effect combined_effect;
        unsigned long supported_effects;
        size_t effect_count;
        struct input_dev *dev;
index 7a3772cb4d407d222a0b21ec3dfab7b892b64da2..4508920e6fb171ac69c98244a182fba8ad85635f 100644 (file)
--- a/klgdff.c
+++ b/klgdff.c
@@ -145,7 +145,7 @@ int klgdff_callback(void *data, const struct klgd_command_stream *s)
 
        printk(KERN_NOTICE "KLGDTM - EFF...\n");
        for (idx = 0; idx < s->count; idx++)
-               printk(KERN_NOTICE "KLGDTM - EFF %s\n", s->commands[idx]->bytes);
+               printk(KERN_NOTICE "KLGDFF-TD: EFF %s\n", s->commands[idx]->bytes);
 
        /* Simulate default USB polling rate of 125 Hz */
        /*usleep_range(7500, 8500);*/
@@ -161,7 +161,7 @@ int klgdff_control(struct input_dev *dev, struct klgd_command_stream *s, const e
                return -EINVAL;
 
        if (!data.effects.cur) {
-               printk(KERN_WARNING "KLGDTM - NULL effect, this _cannot_ happen!\n");
+               printk(KERN_WARNING "KLGDFF-TM: NULL effect, this _cannot_ happen!\n");
                return -EINVAL;
        }
 
@@ -196,7 +196,7 @@ int klgdff_control(struct input_dev *dev, struct klgd_command_stream *s, const e
                return klgdff_owr_upload(s, data.effects.cur, data.effects.old);
                break;
        default:
-               printk(KERN_NOTICE "KLGDTM - Unhandled command\n");
+               printk(KERN_NOTICE "KLGDFF-TD - Unhandled command\n");
                break;
        }
 
@@ -222,14 +222,14 @@ static int __init klgdff_init(void)
 
        ret = klgd_init(&klgd, NULL, klgdff_callback, 1);
        if (ret) {
-               printk(KERN_ERR "Cannot initialize KLGD\n");
+               printk(KERN_ERR "KLGDFF-TD: Cannot initialize KLGD\n");
                goto errout_klgd;
        }
 
        dev = input_allocate_device();
        if (!dev) {
                ret = -ENODEV;
-               printk(KERN_ERR "Cannot allocate input device\n");
+               printk(KERN_ERR "KLGDFF-TD: Cannot allocate input device\n");
                goto errout_idev;
        }
        dev->id.bustype = BUS_VIRTUAL;
@@ -251,24 +251,24 @@ static int __init klgdff_init(void)
                               FFPL_HAS_EMP_TO_SRT | FFPL_REPLACE_STARTED,
                               klgdff_control);
        if (ret) {
-               printk(KERN_ERR "KLGDFF: Cannot init plugin\n");
+               printk(KERN_ERR "KLGDFF-TD: Cannot init plugin\n");
                goto errout_idev;
        }
        ret = input_register_device(dev);
        if (ret) {
-               printk(KERN_ERR "Cannot register input device\n");
+               printk(KERN_ERR "KLGDFF-TD: Cannot register input device\n");
                goto errout_regdev;
        }
        
        ret = klgd_register_plugin(&klgd, 0, ff_plugin, true);
        if (ret) {
-               printk(KERN_ERR "KLGDFF: Cannot register plugin\n");
+               printk(KERN_ERR "KLGDFF-TD: Cannot register plugin\n");
                goto errout_idev;
        }
 
 
 
-       printk(KERN_NOTICE "KLGD FF sample module loaded\n");
+       printk(KERN_NOTICE "KLGDFF-TD: Sample module loaded\n");
        return 0;
 
 errout_regdev: