This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit d43f0272e5072d3b364101333a78f632cf033e9a
Author: wangjianyu3 <[email protected]>
AuthorDate: Tue Nov 7 20:12:32 2023 +0800

    Thermal: Add dummy driver
    
    Signed-off-by: wangjianyu3 <[email protected]>
---
 drivers/thermal/Kconfig         |  23 +++
 drivers/thermal/Make.defs       |   4 +
 drivers/thermal/thermal_core.c  |   9 ++
 drivers/thermal/thermal_core.h  |   6 +
 drivers/thermal/thermal_dummy.c | 347 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 389 insertions(+)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 4f795a97b2..9808707006 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -37,4 +37,27 @@ config THERMAL_PROCFS
        ---help---
                Enable thermal procfs.
 
+config THERMAL_DUMMY
+       bool "Thermal dummy driver"
+       default n
+       ---help---
+               Enable thermal dummy driver.
+
+if THERMAL_DUMMY
+
+config THERMAL_DUMMY_POLLING_DELAY
+       int "Polling delay"
+       default 200
+       ---help---
+               Polling delay(tick).
+
+config THERMAL_DUMMY_CPUFREQ
+       bool "Dummy cpufreq driver"
+       default n
+       depends on CPUFREQ
+       ---help---
+               Enable cpufreq dummy driver.
+
+endif # THERMAL_DUMMY
+
 endif # THERMAL
diff --git a/drivers/thermal/Make.defs b/drivers/thermal/Make.defs
index 9e95fe4cfe..28b0af0c63 100644
--- a/drivers/thermal/Make.defs
+++ b/drivers/thermal/Make.defs
@@ -36,6 +36,10 @@ ifeq ($(CONFIG_THERMAL_PROCFS),y)
 CSRCS += thermal_procfs.c
 endif
 
+ifeq ($(CONFIG_THERMAL_DUMMY),y)
+CSRCS += thermal_dummy.c
+endif
+
 DEPPATH += --dep-path thermal
 VPATH += thermal
 
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 741bd9a84a..d430c01200 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -926,6 +926,15 @@ int thermal_init(void)
     }
 #endif
 
+#ifdef CONFIG_THERMAL_DUMMY
+  ret = thermal_dummy_init();
+  if (ret < 0)
+    {
+      therr("Dummy driver init failed!\n");
+      return ret;
+    }
+#endif
+
 #ifdef CONFIG_THERMAL_CDEV_CPUFREQ
   if (NULL == thermal_cpufreq_cooling_register())
     {
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index 8b7bcc37f5..e60ac51417 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -89,4 +89,10 @@ int thermal_zone_procfs_register(FAR struct 
thermal_zone_device_s *zdev);
 void thermal_zone_procfs_unregister(FAR struct thermal_zone_device_s *zdev);
 #endif
 
+/* Dummy Driver */
+
+#ifdef CONFIG_THERMAL_DUMMY
+int thermal_dummy_init(void);
+#endif
+
 #endif /* __DRIVERS_THERMAL_THERMAL_CORE_H */
diff --git a/drivers/thermal/thermal_dummy.c b/drivers/thermal/thermal_dummy.c
new file mode 100644
index 0000000000..fa45968b9c
--- /dev/null
+++ b/drivers/thermal/thermal_dummy.c
@@ -0,0 +1,347 @@
+/****************************************************************************
+ * drivers/thermal/thermal_dummy.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/cpufreq.h>
+#include <nuttx/thermal.h>
+
+#include <sys/param.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define DUMMY_TEMP_RANGE_LOW  45
+#define DUMMY_TEMP_RANGE_HIGH 90
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct dummy_zone_device_s
+{
+  int temperature;
+  bool raising;
+};
+
+struct dummy_cooling_device_s
+{
+  unsigned int cur_state;
+  unsigned int max_state;
+};
+
+struct dummy_cpufreq_driver_s
+{
+  struct cpufreq_driver driver;
+  const struct cpufreq_frequency_table *table;
+  size_t table_len;
+  int current;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Zone Device */
+
+static int dummy_zdev_get_temp (FAR struct thermal_zone_device_s *zdev,
+                                FAR int *temp);
+static int dummy_zdev_set_trips(FAR struct thermal_zone_device_s *zdev,
+                                int low, int high);
+
+/* Cooling Device */
+
+static int
+dummy_cdev_get_max_state(FAR struct thermal_cooling_device_s *cdev,
+                         FAR unsigned int *state);
+static int
+dummy_cdev_get_state    (FAR struct thermal_cooling_device_s *cdev,
+                         FAR unsigned int *state);
+static int
+dummy_cdev_set_state    (FAR struct thermal_cooling_device_s *cdev,
+                         unsigned int state);
+
+/* CPU Freq */
+
+#ifdef CONFIG_THERMAL_DUMMY_CPUFREQ
+FAR static const struct cpufreq_frequency_table *
+dummy_cpufreq_get_table(FAR struct cpufreq_policy *driver);
+static int dummy_cpufreq_target_index(FAR struct cpufreq_policy *driver,
+                                      unsigned int index);
+static int dummy_cpufreq_get_frequency(FAR struct cpufreq_policy *driver);
+static int dummy_cpufreq_suspend(FAR struct cpufreq_policy *driver);
+static int dummy_cpufreq_resume (FAR struct cpufreq_policy *driver);
+#endif /* CONFIG_THERMAL_DUMMY_CPUFREQ */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Bind */
+
+static const struct thermal_zone_trip_s g_dummy_trips[] =
+{
+  {.name = "cpu_crit",   .temp = 90, .hyst = 10, .type = THERMAL_CRITICAL},
+  {.name = "cpu_alert1", .temp = 70, .hyst = 10, .type = THERMAL_NORMAL},
+  {.name = "cpu_alert0", .temp = 60, .hyst = 10, .type = THERMAL_NORMAL},
+};
+
+static const struct thermal_zone_map_s g_dummy_maps[] =
+{
+  {
+    .trip_name = "cpu_alert1",
+    .cdev_name = "cpufreq",
+    .low    = 3,
+    .high   = THERMAL_NO_LIMIT,
+    .weight = 20
+  },
+  {
+    .trip_name = "cpu_alert1",
+    .cdev_name = "fan0",
+    .low    = THERMAL_NO_LIMIT,
+    .high   = THERMAL_NO_LIMIT,
+    .weight = 20
+  },
+  {
+    .trip_name = "cpu_alert0",
+    .cdev_name = "cpufreq",
+    .low    = THERMAL_NO_LIMIT,
+    .high   = 2,
+    .weight = 20
+  },
+};
+
+static const struct thermal_zone_params_s g_dummy_params =
+{
+  .gov_name = "step_wise",
+  .polling_delay = CONFIG_THERMAL_DUMMY_POLLING_DELAY,
+  .trips = g_dummy_trips,
+  .num_trips = nitems(g_dummy_trips),
+  .maps = g_dummy_maps,
+  .num_maps = nitems(g_dummy_maps),
+};
+
+/* Zone device */
+
+static const struct thermal_zone_device_ops_s g_dummy_zone_ops =
+{
+  .get_temp  = dummy_zdev_get_temp,
+  .set_trips = dummy_zdev_set_trips,
+};
+
+static struct dummy_zone_device_s g_dummy_zone =
+{
+  .temperature = 45,
+  .raising = true,
+};
+
+/* Cooling Device - fan0 */
+
+static struct dummy_cooling_device_s g_dummy_fan0_data =
+{
+  .cur_state = 0,
+  .max_state = 16,
+};
+
+static const struct thermal_cooling_device_ops_s g_dummy_fan0_ops =
+{
+  .set_state     = dummy_cdev_set_state,
+  .get_state     = dummy_cdev_get_state,
+  .get_max_state = dummy_cdev_get_max_state,
+};
+
+/* Cooling Device - cpufreq */
+
+#ifdef CONFIG_THERMAL_DUMMY_CPUFREQ
+static const struct cpufreq_frequency_table g_dummy_cpufreq_table[] =
+{
+  {100},
+  {300},
+  {500},
+  {700},
+  {900},
+  {CPUFREQ_TABLE_END},
+};
+static struct dummy_cpufreq_driver_s g_dummy_cpufreq_driver =
+{
+  .driver =
+    {
+      dummy_cpufreq_get_table,
+      dummy_cpufreq_target_index,
+      dummy_cpufreq_get_frequency,
+      dummy_cpufreq_suspend,
+      dummy_cpufreq_resume,
+    },
+  .table = g_dummy_cpufreq_table,
+  .table_len = nitems(g_dummy_cpufreq_table),
+};
+#endif /* CONFIG_THERMAL_DUMMY_CPUFREQ */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Dummy Cooling Device Operations */
+
+static int dummy_cdev_set_state(FAR struct thermal_cooling_device_s *cdev,
+                                unsigned int state)
+{
+  FAR struct dummy_cooling_device_s *c = cdev->devdata;
+
+  c->cur_state = state;
+  return OK;
+}
+
+static int dummy_cdev_get_state(FAR struct thermal_cooling_device_s *cdev,
+                                FAR unsigned int *state)
+{
+  FAR struct dummy_cooling_device_s *c = cdev->devdata;
+
+  *state = c->cur_state;
+  return OK;
+}
+
+static int
+dummy_cdev_get_max_state(FAR struct thermal_cooling_device_s *cdev,
+                         FAR unsigned int *state)
+{
+  FAR struct dummy_cooling_device_s *c = cdev->devdata;
+
+  *state = c->max_state;
+  return OK;
+}
+
+/* Sensor */
+
+static int dummy_zdev_get_temp(FAR struct thermal_zone_device_s *zdev,
+                               FAR int *temp)
+{
+  FAR struct dummy_zone_device_s *s = zdev->devdata;
+
+  if (s->temperature >= DUMMY_TEMP_RANGE_HIGH)
+    {
+      s->raising = false;
+    }
+  else if (s->temperature <= DUMMY_TEMP_RANGE_LOW)
+    {
+      s->raising = true;
+    }
+
+  if (s->raising)
+    {
+      s->temperature++;
+    }
+  else
+    {
+      s->temperature--;
+    }
+
+  *temp = s->temperature;
+  return OK;
+}
+
+static int dummy_zdev_set_trips(FAR struct thermal_zone_device_s *zdev,
+                                int low, int high)
+{
+  return OK;
+}
+
+#ifdef CONFIG_THERMAL_DUMMY_CPUFREQ
+static FAR const struct cpufreq_frequency_table *dummy_cpufreq_get_table(
+                            FAR struct cpufreq_policy *driver)
+{
+  FAR struct dummy_cpufreq_driver_s **dummy =
+                                (FAR struct dummy_cpufreq_driver_s **)driver;
+  return (*dummy)->table;
+}
+
+static int dummy_cpufreq_target_index(FAR struct cpufreq_policy *driver,
+                                      unsigned int index)
+{
+  FAR struct dummy_cpufreq_driver_s **dummy =
+                                (FAR struct dummy_cpufreq_driver_s **)driver;
+
+  DEBUGASSERT(index >= 0 && index < (*dummy)->table_len);
+
+  (*dummy)->current = (*dummy)->table[index].frequency;
+  return 0;
+}
+
+static int dummy_cpufreq_get_frequency(FAR struct cpufreq_policy *driver)
+{
+  FAR struct dummy_cpufreq_driver_s **dummy =
+                                (FAR struct dummy_cpufreq_driver_s **)driver;
+
+  return (*dummy)->current;
+}
+
+static int dummy_cpufreq_suspend(FAR struct cpufreq_policy *driver)
+{
+  return 0;
+}
+
+static int dummy_cpufreq_resume(FAR struct cpufreq_policy *driver)
+{
+  return 0;
+}
+#endif /* CONFIG_THERMAL_DUMMY_CPUFREQ */
+
+int thermal_dummy_init(void)
+{
+  FAR struct thermal_cooling_device_s *cdev;
+  FAR struct thermal_zone_device_s *zdev;
+  int ret = OK;
+
+  /* Driver - CPUFreq */
+
+#ifdef CONFIG_THERMAL_DUMMY_CPUFREQ
+  ret = cpufreq_init(&g_dummy_cpufreq_driver.driver);
+  if (ret < 0)
+    {
+      therr("Dummy cpufreq driver init failed!\n");
+      return ret;
+    }
+#endif /* CONFIG_THERMAL_DUMMY_CPUFREQ */
+
+  /* Cooling Device */
+
+  cdev = thermal_cooling_device_register("fan0", &g_dummy_fan0_data,
+                                         &g_dummy_fan0_ops);
+  if (cdev == NULL)
+    {
+      therr("Register cooling device fan0 failed!\n");
+      return -ENOTSUP;
+    }
+
+  /* Zone Device */
+
+  zdev = thermal_zone_device_register("cpu-thermal", &g_dummy_zone,
+                                      &g_dummy_zone_ops, &g_dummy_params);
+  if (zdev == NULL)
+    {
+      therr("Register zone deivce failed!\n");
+      return -ENOTSUP;
+    }
+
+  return ret;
+}

Reply via email to