Ver Fonte

Add invalid checking for gsensor mode.

Alfa há 1 mês atrás
pai
commit
e355a4bf8b
2 ficheiros alterados com 59 adições e 25 exclusões
  1. 59 7
      gsensor.c
  2. 0 18
      gsensor.h

+ 59 - 7
gsensor.c

@@ -32,6 +32,7 @@ enum gsensor_orientation_hex
 
 #define GSENSOR_MODE_SOFT_RESET           BIT(2)
 #define GSENSOR_MODE_INITIALIZED          BIT(1)
+#define GSENSOR_MODE_INTERRUPT            BIT(0)
 
 /* Register Definitions */
 #define ST_ACCEL_WHO_AM_I_ADDR            0x0F
@@ -364,19 +365,70 @@ static ssize_t mode_store(struct kobject *kobj, struct kobj_attribute *attr,
     if (!data)
         return -ENODEV;
 
-    if (kstrtoul(buf, 0, &val))
+    int ret = kstrtoul(buf, 0, &val);
+    if (ret) {
+        return -EINVAL;
+    }
+
+    /* Valid mode values check
+     * 0x01 - interrupt mode (BIT0)
+     * 0x04 - soft reset (BIT2)
+     * 0x05 - interrupt mode + soft reset (BIT0 | BIT2)
+     */
+    if (val != 0x01 && val != 0x04 && val != 0x05) {
+        dev_err(data->client ? &data->client->dev : NULL,
+                "Invalid mode value: 0x%02lx. Valid values: 0x01 (interrupt), "
+                "0x04 (soft reset), 0x05 (interrupt + soft reset)\n", val);
         return -EINVAL;
+    }
+
+    mutex_lock(&data->lock);
 
+    /* Handle soft reset (BIT2) */
     if (val & GSENSOR_MODE_SOFT_RESET) {
-        mutex_lock(&data->lock);
-        gsensor_init_sensor(data);
-        data->orientation_hex = GSENSOR_ORIENT_LANDSCAPE_HEX;
-        strcpy(data->orientation_str, GSENSOR_ORIENT_LANDSCAPE_STR);
-        mutex_unlock(&data->lock);
+        bool was_enabled = data->enabled;
+
+        /* Disable sensor if enabled */
+        if (was_enabled) {
+            cancel_delayed_work_sync(&data->poll_work);
+            gsensor_set_enable(data, false);
+            data->enabled = false;
+        }
+
+        /* Reinitialize sensor */
+        ret = gsensor_init_sensor(data);
+        if (ret == 0) {
+            data->orientation_hex = GSENSOR_ORIENT_LANDSCAPE_HEX;
+            strcpy(data->orientation_str, GSENSOR_ORIENT_LANDSCAPE_STR);
+            dev_info(&data->client->dev, "Soft reset completed\n");
+
+            /* Re-enable if it was enabled before */
+            if (was_enabled) {
+                ret = gsensor_set_enable(data, true);
+                if (ret == 0) {
+                    data->enabled = true;
+                    schedule_delayed_work(&data->poll_work, 0);
+                    gsensor_update_orientation(data);
+                }
+            }
+        } else {
+            dev_err(&data->client->dev, "Soft reset failed: %d\n", ret);
+        }
     }
 
-    return count;
+    /* Handle interrupt mode (BIT0) - currently driver uses polling mode */
+    if (val & GSENSOR_MODE_INTERRUPT) {
+        dev_info(
+            &data->client->dev,
+            "Interrupt mode requested (0x01), but driver uses polling mode\n");
+        /* Interrupt mode support can be added here if needed */
+    }
+
+    mutex_unlock(&data->lock);
+
+    return ret < 0 ? ret : count;
 }
+
 static struct kobj_attribute mode_attr = __ATTR_RW(mode);
 
 static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,

+ 0 - 18
gsensor.h

@@ -2,24 +2,6 @@
 #ifndef __GSENSOR_H
 #define __GSENSOR_H
 
-/* Gsensor orientation values (hex per API spec) */
-enum gsensor_orientation_hex
-{
-    GSENSOR_ORIENT_UNKNOWN_HEX        = 0x00,
-    GSENSOR_ORIENT_PORTRAIT_HEX       = 0x14,
-    GSENSOR_ORIENT_LANDSCAPE_HEX      = 0x15,
-    GSENSOR_ORIENT_PORTRAIT_FLIP_HEX  = 0x16,
-    GSENSOR_ORIENT_LANDSCAPE_FLIP_HEX = 0x17,
-};
-
-#define GSENSOR_ORIENT_PORTRAIT_STR       "portrait"
-#define GSENSOR_ORIENT_LANDSCAPE_STR      "landscape"
-#define GSENSOR_ORIENT_PORTRAIT_FLIP_STR  "portrait_flip"
-#define GSENSOR_ORIENT_LANDSCAPE_FLIP_STR "landscape_flip"
-
-#define GSENSOR_MODE_SOFT_RESET           BIT(2)
-#define GSENSOR_MODE_INITIALIZED          BIT(1)
-
 /* Function prototypes */
 int gsensor_init_main(void);
 void gsensor_exit_main(void);