drivers/sensors: s5j/ppd42ns: modify ppd42ns dust sensor driver
authorWonsang Ryou <wonsang.yoo@samsung.com>
Mon, 24 Jul 2017 06:14:34 +0000 (15:14 +0900)
committerEunBong Song <eunb.song@samsung.com>
Wed, 30 Aug 2017 04:15:46 +0000 (21:15 -0700)
This patch modifies ppd42ns driver according to Tizen RT device driver
model. The previous ppd42ns driver has implemented according to common
sensor API definition (os/include/tinyara/sensors/sensor.h). The common
sensor API will be removed.

The details are as follows.

 1. remove common sensor API definition
      : os/include/tinyara/sensors/sensor.h
 2. modify ppd42ns driver according to Tizen RT device driver model
    - implement open, close and read operations
    - implement board dependent functions as callback
    - implement the function for registering character driver
      : os/drivers/sensors/ppd42ns.c
        os/include/tinyara/sensors/ppd42ns.h
 3. add Samsung S5JT200 code for implementing board dependent callback
      : os/arch/arm/src/s5j/s5j_ppd42ns.c
        os/arch/arm/src/s5j/s5j_ppd42ns.h
 4. add sensor driver registering code on board initialization
      : os/arch/arm/src/artik053/src/artik053_boot.c,
        os/arch/arm/src/sidk_s5jt200/src/s5jt200_boot.c
 5. modify ppd42ns example application using file operation
      : apps/examples/sensor_test/ppd42ns_test.c

Change-Id: I14ae5e10a3624cf8bb7125137323fcc3bb6c50ca
Signed-off-by: Wonsang Ryou <wonsang.yoo@samsung.com>
12 files changed:
apps/examples/sensor_test/Kconfig [new file with mode: 0644]
apps/examples/sensor_test/ppd42ns_test.c [new file with mode: 0644]
os/arch/arm/src/artik053/src/artik053_boot.c
os/arch/arm/src/s5j/Kconfig
os/arch/arm/src/s5j/Make.defs
os/arch/arm/src/s5j/s5j_ppd42ns.c [new file with mode: 0644]
os/arch/arm/src/s5j/s5j_ppd42ns.h [new file with mode: 0644]
os/arch/arm/src/sidk_s5jt200/src/s5jt200_boot.c
os/drivers/sensors/Kconfig
os/drivers/sensors/ppd42ns.c
os/include/tinyara/sensors/ppd42ns.h
os/include/tinyara/sensors/sensor.h [deleted file]

diff --git a/apps/examples/sensor_test/Kconfig b/apps/examples/sensor_test/Kconfig
new file mode 100644 (file)
index 0000000..9f4d5b1
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# For a description of the syntax of this configuration file,
+# see kconfig-language at https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
+#
+
+config EXAMPLES_SENSOR_TEST
+       bool "\"Sensor Test\" example"
+       default n
+       depends on SENSOR
+       ---help---
+               Enable the \"Sensor Test\" example
+
+
+if EXAMPLES_SENSOR_TEST
+config EXAMPLES_SENSOR_TEST_PPD42NS
+       bool "PPD42NS Dust Sensor Example"
+       default n
+       ---help---
+               Enable PPD42NS Dust Sensor Example Application
+
+config EXAMPLES_SENSOR_TEST_PPD42NS_MQTT_TRANSMISSION
+       bool "Support MQTT transmission for sending sensor data"
+       default n
+       depends on EXAMPLES_SENSOR_TEST_PPD42NS
+       depends on EXAMPLES_MQTT_TEST
+       ---help---
+               Enable to dust send sensor data using MQTT transmission
+
+endif # EXAMPLES_SENSOR_TEST
+
+config USER_ENTRYPOINT
+       string
+       default "ppd42ns_test_main" if ENTRY_SENSOR_TEST
diff --git a/apps/examples/sensor_test/ppd42ns_test.c b/apps/examples/sensor_test/ppd42ns_test.c
new file mode 100644 (file)
index 0000000..d3065bd
--- /dev/null
@@ -0,0 +1,178 @@
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ ****************************************************************************/
+/**
+ * @file ppd42ns_test.c
+ * @brief the program for testing ppd42ns dust sensor
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <tinyara/config.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <tinyara/sensors/ppd42ns.h>
+
+#define DUST_SENSOR_DEVNAME            "/dev/dust0"
+
+#if defined(CONFIG_EXAMPLES_SENSOR_TEST_PPD42NS_MQTT_TRANSMISSION)
+/**************
+ * Definitions
+ **************/
+#define MQTT_BROKER_IP_ADDRESS         "192.168.1.14"
+#define MQTT_BROKER_PORT                       "1883"
+#define MQTT_TOPIC                                     "/test/sensor"
+
+/**************
+ * Structure
+ **************/
+struct mqtt_pub_input {
+       int argc;
+       char **argv;
+};
+
+/**************
+ * Private Data
+ **************/
+char g_argv_buf[30][100];
+char *g_argv_cur[30];
+
+/******************
+ * function prototype
+ ******************/
+int mqtt_client_pub_task(void *arg);
+
+/******************
+ * static function
+ ******************/
+static void create_arg(struct mqtt_pub_input *arg, char **argv_cur, char(*argv)[100], char *cmd)
+{
+       int i, len, idx1, idx2;
+
+       len = (int)strlen(cmd);
+       idx1 = idx2 = 0;
+       for (i = 0; i < len; i++) {
+               if (cmd[i] == ' ') {
+                       argv[idx1][idx2] = '\0';
+                       idx1++;
+                       idx2 = 0;
+                       i++;
+               }
+               argv[idx1][idx2++] = cmd[i];
+       }
+       argv[idx1][idx2] = '\0';
+
+       arg->argc = idx1 + 1;
+       for (i = 0; i < arg->argc; i++) {
+               argv_cur[i] = argv[i];
+       }
+       arg->argv = argv_cur;
+}
+
+static int send_sensor_data(char *data)
+{
+       struct mqtt_pub_input arg;
+       char mqtt_str[128];
+
+       snprintf(mqtt_str, 128, "mqtt_pub -h %s -t %s -p %s -m %s", MQTT_BROKER_IP_ADDRESS, MQTT_TOPIC, MQTT_BROKER_PORT, data);
+
+       create_arg(&arg, g_argv_cur, g_argv_buf, mqtt_str);
+       mqtt_client_pub_task(&arg);
+
+       return 0;
+}
+#endif                                                 /* CONFIG_EXAMPLES_SENSOR_TEST_PPD42NS_MQTT_TRANSMISSION */
+
+/****************************************************************************
+ * main
+ ****************************************************************************/
+
+#ifdef CONFIG_BUILD_KERNEL
+int main(int argc, FAR char *argv[])
+#else
+int ppd42ns_test_main(int argc, char *argv[])
+#endif
+{
+       int result = -1;
+       int fd = -1;
+       float sensor_data;
+       char msg[64];
+       int sampling_interval_ms;
+       int test_cnt;
+       int loop_cnt;
+
+       if (argc != 3) {
+               printf("USAGE: sensor_ppd42ns [sampling_interval_in_ms] [loop_count] \n");
+               goto done;
+       }
+
+       sampling_interval_ms = atoi(argv[1]);
+       test_cnt = atoi(argv[2]);
+       loop_cnt = test_cnt;
+
+       /* open ppd42ns sensor driver */
+       fd = open(DUST_SENSOR_DEVNAME, O_RDONLY);
+       if (fd < 0) {
+               printf("ERROR: open() failed. devname=%s\n", DUST_SENSOR_DEVNAME);
+               goto done;
+       }
+
+       printf(">>> Start ppd42ns dust sensor test\n");
+       printf(" - interval: %d ms\n", sampling_interval_ms);
+       printf(" - loop_count: %d\n", loop_cnt);
+       printf(" - mqtt transmission: ");
+#if defined(CONFIG_EXAMPLES_SENSOR_TEST_PPD42NS_MQTT_TRANSMISSION)
+       printf("ON\n");
+#else
+       printf("OFF\n");
+#endif
+
+       while (loop_cnt) {
+               usleep(sampling_interval_ms * 1000);
+               if (read(fd, (void *)&sensor_data, sizeof(float)) == sizeof(float)) {
+                       /* make sensor data message with json style */
+                       snprintf(msg, sizeof(msg), "{\"dust\":%.2f}", sensor_data);
+                       printf("[%d] %s \n", (test_cnt - loop_cnt + 1), msg);
+
+#if defined(CONFIG_EXAMPLES_SENSOR_TEST_PPD42NS_MQTT_TRANSMISSION)
+                       send_sensor_data(msg);
+#endif
+               } else {
+                       printf("ERROR: read() failed. devname=%s, remaining loop_cnt=%d\n", DUST_SENSOR_DEVNAME, loop_cnt - 1);
+               }
+
+               loop_cnt--;
+       }
+       printf("<<< End ppd42ns dust sensor test\n");
+
+       /* close ppd42ns sensor driver */
+       if (fd != -1) {
+               close(fd);
+               fd = -1;
+       }
+
+       result = 0;
+
+done:
+       return result;
+}
index 4f5901d..9ae76b6 100644 (file)
@@ -64,6 +64,7 @@
 #include <arch/board/artik053_alc5658_i2c.h>
 #include "up_arch.h"
 #include "s5j_gpio.h"
+#include "s5j_ppd42ns.h"
 
 /*****************************************************************************
  * Private Functions
@@ -123,7 +124,7 @@ static void board_gpio_initialize(void)
  * Name: board_i2c_initialize
  *
  * Description:
- *  Expose board dependent I2Cs
+ *  Expose board dependent I2Cs 
  ****************************************************************************/
 static void board_i2c_initialize(void)
 {
@@ -133,6 +134,19 @@ static void board_i2c_initialize(void)
 #endif
 }
 
+/****************************************************************************
+ * Name: board_sensor_initialize
+ *
+ * Description:
+ *  Expose board dependent Sensors
+ ****************************************************************************/
+static void board_sensor_initialize(void)
+{
+#if defined(CONFIG_SENSOR_PPD42NS) && defined(CONFIG_S5J_SENSOR_PPD42NS)
+       s5j_ppd42ns_initialize();
+#endif
+}
+
 /*****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -215,7 +229,6 @@ void board_initialize(void)
        board_gpio_initialize();
        board_i2c_initialize();
 
-
 #if defined(CONFIG_AUDIO_ALC5658)
        s5j_alc5658_initialize(0);
 #elif defined(CONFIG_AUDIO_ALC5658CHAR)
@@ -224,5 +237,6 @@ void board_initialize(void)
        alc5658_i2c_initialize();
        i2schar_devinit();
 #endif
+       board_sensor_initialize();
 }
 #endif /* CONFIG_BOARD_INITIALIZE */
index 9599aa2..ff1d47d 100644 (file)
@@ -378,4 +378,8 @@ config S5J_PWR_SLEEP
 
 endmenu
 
+config S5J_SENSOR_PPD42NS
+       bool "PPD42NS Dust Sensor"
+       default n
+
 endmenu
index 89299a4..541635d 100644 (file)
@@ -187,3 +187,7 @@ CHIP_CSRCS += sss_driver_io.c
 # built-in static library
 EXTRA_LIBS += chip/sss/libispdriver.a
 endif
+
+ifeq ($(CONFIG_S5J_SENSOR_PPD42NS),y)
+CHIP_CSRCS += s5j_ppd42ns.c
+endif
diff --git a/os/arch/arm/src/s5j/s5j_ppd42ns.c b/os/arch/arm/src/s5j/s5j_ppd42ns.c
new file mode 100644 (file)
index 0000000..4944b2a
--- /dev/null
@@ -0,0 +1,282 @@
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * arch/arm/src/s5j/s5j_ppd42ns.c
+ *
+ *   Copyright (C) 2009-2010, 2014-2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+#include <tinyara/config.h>
+#include <tinyara/irq.h>
+#include <tinyara/sensors/ppd42ns.h>
+#include <debug.h>
+#include <errno.h>
+#include "s5j_gpio.h"
+
+#ifdef CONFIG_SENSOR_PPD42NS
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+#define DEVNAME_FORMAT "/dev/dust%d"
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct s5j_gpio_info_s {
+       uint8_t pinnum;
+       uint16_t pincfg;
+};
+
+struct s5j_ppd42ns_priv_s {
+       uint32_t irqvector;
+       uint32_t pincfg;
+       int event_on_rising;
+       int event_on_falling;
+};
+
+struct s5j_ppd42ns_dev_s {
+       /* Configuration structure as seen by the ppd42ns driver */
+       struct ppd42ns_config_s config;
+
+       /* Additional private definitions only known to this driver */
+       ppd42ns_handler_t handler;
+       FAR void *arg;
+};
+
+/****************************************************************************
+ * Private Functions Prototype
+ ****************************************************************************/
+static int s5j_ppd42ns_gpio_read(struct ppd42ns_config_s *config);
+static int s5j_ppd42ns_irq_attach(struct ppd42ns_config_s *config, ppd42ns_handler_t handler, FAR char *arg);
+static int s5j_ppd42ns_irq_enable(struct ppd42ns_config_s *config, int enable);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+static struct s5j_ppd42ns_dev_s g_s5j_dev = {
+       .config = {
+               .gpionum = CONFIG_SENSOR_PPD42NS_GPIO_NUM,
+               .read_gpio = s5j_ppd42ns_gpio_read,
+               .attach = s5j_ppd42ns_irq_attach,
+               .enable = s5j_ppd42ns_irq_enable,
+               .priv = NULL,
+       },
+
+       .handler = NULL
+};
+
+static struct s5j_gpio_info_s g_gpio_info[] = {
+       {57, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTA0 | GPIO_PIN0},     /* XEINT0 */
+       {58, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTA0 | GPIO_PIN1},     /* XEINT1 */
+       {59, GPIO_INPUT | GPIO_PULLDOWN | GPIO_PORTA0 | GPIO_PIN2},     /* XEINT2 */
+};
+
+static struct s5j_ppd42ns_priv_s g_s5j_priv;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+static int s5j_ppd42ns_gpio_read(struct ppd42ns_config_s *config)
+{
+       struct s5j_ppd42ns_dev_s *dev = (struct s5j_ppd42ns_dev_s *)config;
+       struct s5j_ppd42ns_priv_s *priv = dev ? (struct s5j_ppd42ns_priv_s *)dev->config.priv : NULL;
+
+       if (priv == NULL) {
+               lldbg("ERROR: s5j_ppd42ns_gpio_read() is failed.\n");
+               return -1;
+       }
+
+       return s5j_gpioread(priv->pincfg) ? 1 : 0;
+}
+
+static int s5j_ppd42ns_irq_handler(int irq, FAR void *context, FAR void *arg)
+{
+       struct s5j_ppd42ns_dev_s *dev = (struct s5j_ppd42ns_dev_s *)arg;
+       struct s5j_ppd42ns_priv_s *priv = dev ? (struct s5j_ppd42ns_priv_s *)dev->config.priv : NULL;
+
+       if (priv == NULL) {
+               return -1;
+       }
+
+       s5j_gpio_clear_pending(priv->pincfg);
+
+       if (dev->handler) {
+               dev->handler(dev->arg);
+       }
+
+       return 0;
+}
+
+static int s5j_ppd42ns_irq_attach(struct ppd42ns_config_s *config, ppd42ns_handler_t handler, FAR char *arg)
+{
+       struct s5j_ppd42ns_dev_s *dev = (struct s5j_ppd42ns_dev_s *)config;
+       struct s5j_ppd42ns_priv_s *priv = dev ? (struct s5j_ppd42ns_priv_s *)dev->config.priv : NULL;
+
+       if (priv == NULL) {
+               lldbg("ERROR: s5j_ppd42ns_irq_attach() is failed.\n");
+               return -1;
+       }
+
+       dev->handler = handler;
+       dev->arg = arg;
+
+       return 0;
+}
+
+static int s5j_ppd42ns_irq_enable(struct ppd42ns_config_s *config, int enable)
+{
+       int result = -1;
+       struct s5j_ppd42ns_dev_s *dev = (struct s5j_ppd42ns_dev_s *)config;
+       struct s5j_ppd42ns_priv_s *priv = dev ? (struct s5j_ppd42ns_priv_s *)dev->config.priv : NULL;
+       uint32_t pincfg;
+       irqstate_t flags;
+
+       if (priv == NULL) {
+               lldbg("ERROR: s5j_ppd42ns_irq_enable() is failed.\n");
+               return -1;
+       }
+
+       /* disable interrupt */
+       flags = irqsave();
+
+       pincfg = priv->pincfg;
+       pincfg &= ~GPIO_FUNC_MASK;
+       if (priv->event_on_rising && priv->event_on_falling) {
+               pincfg |= GPIO_EINT | GPIO_EINT_BOTH_EDGE;
+       } else if (priv->event_on_rising) {
+               pincfg |= GPIO_EINT | GPIO_EINT_RISING_EDGE;
+       } else if (priv->event_on_falling) {
+               pincfg |= GPIO_EINT | GPIO_EINT_FALLING_EDGE;
+       }
+
+       if (enable) {
+               irq_attach(priv->irqvector, s5j_ppd42ns_irq_handler, dev);
+               up_enable_irq(priv->irqvector);
+
+       } else {
+               up_disable_irq(priv->irqvector);
+               irq_detach(priv->irqvector);
+       }
+
+       if (s5j_configgpio(pincfg) != 0) {
+               goto done;
+       }
+
+       result = 0;
+
+done:
+       /* enable interrupt */
+       irqrestore(flags);
+
+       return result;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: s5j_ppd42ns_initialize
+ *
+ * Description:
+ *   Initialize the ppd42ns dust sensor driver.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+int s5j_ppd42ns_initialize(void)
+{
+       int result = -1;
+       int i;
+       int total_pins = sizeof(g_gpio_info) / sizeof(g_gpio_info[0]);
+       char devpath[32];
+
+       for (i = 0; i < total_pins; i++) {
+               if (g_gpio_info[i].pinnum == CONFIG_SENSOR_PPD42NS_GPIO_NUM) {
+                       g_s5j_priv.pincfg = g_gpio_info[i].pincfg;
+                       g_s5j_priv.irqvector = s5j_gpio_irqvector(g_s5j_priv.pincfg);
+                       break;
+               }
+       }
+       if (i == total_pins) {
+               result = -EINVAL;
+               goto done;
+       }
+       /* set both edge */
+       g_s5j_priv.event_on_rising = true;
+       g_s5j_priv.event_on_falling = true;
+
+       /* set ppd42ns config */
+       g_s5j_dev.config.priv = (void *)&g_s5j_priv;
+
+       /* register ppd42ns driver */
+       snprintf(devpath, sizeof(devpath), DEVNAME_FORMAT, 0);
+       if (ppd42ns_register(devpath, &g_s5j_dev.config) != 0) {
+               goto done;
+       }
+
+       /* result is success */
+       result = 0;
+
+done:
+       return result;
+}
+
+#endif                                                 /* CONFIG_SENSOR_PPD42NS */
diff --git a/os/arch/arm/src/s5j/s5j_ppd42ns.h b/os/arch/arm/src/s5j/s5j_ppd42ns.h
new file mode 100644 (file)
index 0000000..87889b6
--- /dev/null
@@ -0,0 +1,104 @@
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ ****************************************************************************/
+/****************************************************************************
+ * arch/arm/src/s5j/s5j_ppd42ns.h
+ *
+ *   Copyright (C) 2009-2010, 2014-2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_S5J_S5J_PPD42NS_H
+#define __ARCH_ARM_SRC_S5J_S5J_PPD42NS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+#include <tinyara/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: s5j_ppd42ns_initialize
+ *
+ * Description:
+ *      Initialize the ppd42ns dust sensor driver.
+ *
+ * Input Parameters:
+ *      None
+ *
+ * Returned Value:
+ *      Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+int s5j_ppd42ns_initialize(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif                                                 /* __ASSEMBLY__ */
+#endif                                                 /* __ARCH_ARM_SRC_S5J_S5J_PPD42NS_H */
index 799b7e4..a322c2d 100644 (file)
@@ -71,6 +71,7 @@
 
 #include "sidk_s5jt200.h"
 #include "s5j_gpio.h"
+#include "s5j_ppd42ns.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -134,6 +135,19 @@ static void board_gpio_initialize(void)
 }
 
 /****************************************************************************
+ * Name: board_sensor_initialize
+ *
+ * Description:
+ *  initialize board dependent sensor driver code
+ ****************************************************************************/
+static void board_sensor_initialize(void)
+{
+#if defined(CONFIG_SENSOR_PPD42NS) && defined(CONFIG_S5J_SENSOR_PPD42NS)
+       s5j_ppd42ns_initialize();
+#endif
+}
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -224,5 +238,7 @@ void board_initialize(void)
 #ifdef CONFIG_SIDK_S5JT200_EEPROM
        sidk_s5jt200_eeprom_init();
 #endif
+
+       board_sensor_initialize();
 }
 #endif /* CONFIG_BOARD_INITIALIZE */
index f033b12..b100785 100644 (file)
@@ -3,10 +3,6 @@
 # see kconfig-language at https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
 #
 
-comment "Sensor Drivers"
-
-if SENSOR
-
 config SENSOR_PPD42NS
        bool "Shinyei PPD42NS Dust Sensor"
        default n
@@ -21,7 +17,10 @@ config SENSOR_PPD42NS_GPIO_NUM
        ---help---
                the pin number of GPIO that is connected to PPD42NS's Dust Signal Pin
 
-endif # SENSOR_PPD42NS
-
-endif # SENSOR
+config SENSOR_PPD42NS_DEBUG
+       bool "PPD42NS driver debug message"
+       default n
+       ---help---
+               enable PPD42ns dust sensor driver's debug message
 
+endif # SENSOR_PPD42NS
index 52f0e6d..d68f542 100644 (file)
  ****************************************************************************/
 #include <tinyara/config.h>
 #include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
 #include <errno.h>
+#include <debug.h>
 #include <math.h>
-#include <semaphore.h>
-#include <poll.h>
-#include <tinyara/gpio.h>
-#include <tinyara/sensors/sensor.h>
+
 #include <tinyara/sensors/ppd42ns.h>
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+#define PPD42NS_TIME_GET(time)          gettimeofday(&time, NULL)
+#define PPD42NS_TIME_DIFF_USEC(old_time, cur_time) \
+       ((cur_time.tv_sec * 1000000 + cur_time.tv_usec) - (old_time.tv_sec * 1000000 + old_time.tv_usec))
+
 #define GPIO_SIGNAL_LOW                                0
 #define GPIO_SIGNAL_HIGH                       1
 
 /****************************************************************************
- * Structures
+ * Private Types
  ****************************************************************************/
-typedef struct {
-       int initialized;
-       int activated;
-       sem_t exclsem;
-       int fd;
-       char devpath[16];
-       int old_signal;
-       int lowpulseoccupancy;
-       struct timeval start_time;
-       struct timeval lowpulse_start_time;
-       int pipe_evt_task[2];
-       int evt_task_loop;
-} ppd42ns_priv;
+struct ppd42ns_dev_s {
+       FAR struct ppd42ns_config_s *config;    /* ppd42ns driver config */
+       int crefs;                                      /* reference count on the driver instance */
+       sem_t exclsem;                          /* exclusive access to the device */
+       sem_t datasem;                          /* exclusive access while reading sensor data */
+       int old_signal;                         /* previous gpio signal */
+       int lowpulseoccupancy;          /* low pulse signal time */
+       struct timeval start_time;      /* start time of total period */
+       struct timeval lowpulse_start_time;     /* start time of low pulse signal period */
+};
 
 /****************************************************************************
- * Static Function Prototype
+ * Private Functions Prototype
  ****************************************************************************/
-static int ppd42ns_init(sensor_device_t *sensor);
-static int ppd42ns_deinit(sensor_device_t *sensor);
-static int ppd42ns_activate(sensor_device_t *sensor);
-static int ppd42ns_deactivate(sensor_device_t *sensor);
-static int ppd42ns_ioctl(sensor_device_t *sensor, int id, sensor_ioctl_value_t *val);
-static int ppd42ns_get_data(sensor_device_t *sensor, sensor_data_t *data);
+static int ppd42ns_open(FAR struct file *filep);
+static int ppd42ns_close(FAR struct file *filep);
+static ssize_t ppd42ns_read(FAR struct file *filep, FAR char *buffer, size_t len);
 
 /****************************************************************************
- * Variables
+ * Private Data
  ****************************************************************************/
-static sensor_operations_t g_ops = {
-       .init = ppd42ns_init,
-       .deinit = ppd42ns_deinit,
-       .activate = ppd42ns_activate,
-       .deactivate = ppd42ns_deactivate,
-       .ioctl = ppd42ns_ioctl,
-       .set_trigger = NULL,
-       .get_data = ppd42ns_get_data,
-};
 
-static ppd42ns_priv g_priv;
+/* ppd42ns driver instance */
+static FAR struct ppd42ns_dev_s g_ppd42ns_priv;
+
+/* This the vtable that supports the character driver interface */
+static const struct file_operations g_ppd42ns_fops = {
+       ppd42ns_open,                           /* open */
+       ppd42ns_close,                          /* close */
+       ppd42ns_read,                           /* read */
+       0,                                                      /* write */
+       0,                                                      /* seek */
+       0,                                                      /* ioctl */
+};
 
 /****************************************************************************
- * Static Function
+ * Private Function
  ****************************************************************************/
 
-static void ppd42ns_event_handler(sensor_device_t *sensor)
+/****************************************************************************
+ * Name: ppd42ns_takesem
+ *
+ * Description:
+ *    Take the lock, waiting as necessary
+ *
+ ****************************************************************************/
+static inline int ppd42ns_takesem(FAR sem_t *sem)
 {
-       /* this is both edge interrupt handler on ppd42ns's digital signal pin */
-
-       struct timeval time;
-       ppd42ns_priv *priv;
-
-       if (sensor && sensor->priv) {
-               priv = (ppd42ns_priv *) sensor->priv;
-       } else {
-               return;
+       /* Take a count from the semaphore, possibly waiting */
+       if (sem_wait(sem) < 0) {
+               /* EINTR is the only error that we expect */
+               int errcode = get_errno();
+               DEBUGASSERT(errcode == EINTR);
+               return errcode;
        }
 
-       if (priv->old_signal == GPIO_SIGNAL_LOW) {
-               /* signal LOW -> HIGH */
-               SENSOR_TIME_GET(time);
-               priv->lowpulseoccupancy += SENSOR_TIME_DIFF_USEC(priv->lowpulse_start_time, time);
-               priv->old_signal = GPIO_SIGNAL_HIGH;
-#if PPD42NS_DEBUG_ON
-               SENSOR_DEBUG("LOW -> HIGH : tv_sec=%d, tv_usec=%d, lowpulse_time=%d\n", time.tv_sec, time.tv_usec, SENSOR_TIME_DIFF_USEC(priv->lowpulse_start_time, time));
-#endif
-       } else {
-               /* signal HIGH -> LOW */
-               SENSOR_TIME_GET(priv->lowpulse_start_time);
-               priv->old_signal = GPIO_SIGNAL_LOW;
-#if PPD42NS_DEBUG_ON
-               SENSOR_DEBUG("HIGH -> LOW : tv_sec=%d, tv_usec=%d\n", priv->lowpulse_start_time.tv_sec, priv->lowpulse_start_time.tv_usec);
-#endif
-       }
+       return 0;
 }
 
-static void ppd42ns_event_task(sensor_device_t *sensor)
+/****************************************************************************
+ * Name: ppd42ns_givesem
+ *
+ * Description:
+ *    release the lock
+ *
+ ****************************************************************************/
+static inline void ppd42ns_givesem(sem_t *sem)
 {
-       int ret;
-       ppd42ns_priv *priv;
-       struct pollfd fds[2];
-       int size;
-       int timeout;
-
-#if PPD42NS_DEBUG_ON
-       SENSOR_DEBUG("start event task \n");
-#endif
-
-       if (sensor && sensor->priv) {
-               priv = (ppd42ns_priv *) sensor->priv;
-       } else {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               return;
-       }
-
-       /* initializes pollfd */
-       memset(fds, 0, sizeof(fds));
-       fds[0].fd = priv->pipe_evt_task[1];
-       fds[0].events = POLLIN;
-       fds[1].fd = priv->fd;
-       fds[1].events = POLLIN;
-
-       timeout = 1000;
-       size = sizeof(fds) / sizeof(struct pollfd);
-       priv->evt_task_loop = 1;
-       while (priv->evt_task_loop) {
-               ret = poll(fds, size, timeout);
-               if (ret < 0) {
-                       SENSOR_DEBUG("ERROR: %s is NULL.\n");
-                       return;
-               } else if (ret == 0) {
-                       /* poll timeout */
-                       continue;
-               }
-
-               /* stop message via pipe */
-               if (fds[0].revents & POLLIN) {
-#if PPD42NS_DEBUG_ON
-                       SENSOR_DEBUG("received stop message via pipe.\n");
-#endif
-                       priv->evt_task_loop = 0;
-                       break;
-               }
-
-               /* gpio interrupt */
-               if (fds[1].revents & POLLIN) {
-#if PPD42NS_DEBUG_ON
-                       SENSOR_DEBUG("gpio interrupt occurred.\n");
-#endif
-                       ppd42ns_event_handler(sensor);
-               }
-       }
-
-#if PPD42NS_DEBUG_ON
-       SENSOR_DEBUG("stop event task \n");
-#endif
+       sem_post(sem);
 }
 
-static int ppd42ns_event_task_start(sensor_device_t *sensor)
+/****************************************************************************
+ * Name: ppd42ns_interrupt_handler
+ *
+ * Description:
+ *    handle ppd42ns's digital pin interrupt
+ *
+ ****************************************************************************/
+static void ppd42ns_interrupt_handler(FAR void *arg)
 {
-       int result = -1;
-       int ret;
-       pthread_t tid;
-       ppd42ns_priv *priv;
-
-       if (sensor && sensor->priv) {
-               priv = (ppd42ns_priv *) sensor->priv;
-       } else {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               return -1;
-       }
-
-       /* create pipe which is connected to event task */
-       priv->pipe_evt_task[0] = -1;
-       priv->pipe_evt_task[1] = -1;
-       ret = pipe(priv->pipe_evt_task);
-       if (ret == -1) {
-               SENSOR_DEBUG("ERROR: pipe() failed.\n");
-               goto done;
-       }
+       /* this is both edge interrupt handler on ppd42ns's digital signal pin */
+       FAR struct ppd42ns_dev_s *priv = (FAR struct ppd42ns_dev_s *)arg;
+       struct timeval time;
+       irqstate_t flags;
 
-       /* create event task */
-       ret = pthread_create(&tid, NULL, (pthread_startroutine_t) ppd42ns_event_task, (void *)sensor);
-       if (ret != 0) {
-               SENSOR_DEBUG("ERROR: pthread_create() failed. (ret=%d)\n", ret);
-               goto done;
-       }
-       ret = pthread_detach(tid);
-       if (ret != 0) {
-               SENSOR_DEBUG("ERROR: pthread_detach() failed. (ret=%d)\n", ret);
+       if (priv == NULL) {
+               return;
        }
 
-       /* result is success */
-       result = 0;
-
-done:
-       if (result != 0) {
-               if (priv->pipe_evt_task[0] != -1) {
-                       close(priv->pipe_evt_task[0]);
-                       priv->pipe_evt_task[0] = -1;
-               }
-
-               if (priv->pipe_evt_task[1] != -1) {
-                       close(priv->pipe_evt_task[1]);
-                       priv->pipe_evt_task[1] = -1;
-               }
-
-               SENSOR_DEBUG("ERROR: fail to start event task\n");
+       /* This ISR handles only when gpio signal is changed. */
+       if (priv->config->read_gpio(priv->config) == priv->old_signal) {
+               return;
        }
 
-       return result;
-
-}
+       /* disable interrupt */
+       flags = irqsave();
 
-static int ppd42ns_event_task_stop(sensor_device_t *sensor)
-{
-       ppd42ns_priv *priv;
-
-       if (sensor && sensor->priv) {
-               priv = (ppd42ns_priv *) sensor->priv;
+       if (priv->old_signal == GPIO_SIGNAL_LOW) {
+               /* signal LOW -> HIGH */
+               PPD42NS_TIME_GET(time);
+               priv->lowpulseoccupancy += PPD42NS_TIME_DIFF_USEC(priv->lowpulse_start_time, time);
+               priv->old_signal = GPIO_SIGNAL_HIGH;
        } else {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               return -1;
-       }
-
-       if (priv->evt_task_loop) {
-               if (write(priv->pipe_evt_task[1], "#", 1) < 0) {
-                       SENSOR_DEBUG("ERROR: pipe write() failed. (errno=%d)\n", errno);
-               }
-
-               while (priv->evt_task_loop) {
-                       usleep(100 * 1000);
-               }
-       }
-
-       if (priv->pipe_evt_task[0] != -1) {
-               close(priv->pipe_evt_task[0]);
-               priv->pipe_evt_task[0] = -1;
-       }
-
-       if (priv->pipe_evt_task[1] != -1) {
-               close(priv->pipe_evt_task[1]);
-               priv->pipe_evt_task[1] = -1;
-       }
-
-       return 0;
-}
-
-static int ppd42ns_init(sensor_device_t *sensor)
-{
-       int result = -1;
-       ppd42ns_priv *priv;
-
-       if (sensor == NULL || sensor->priv == NULL) {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               goto done;
-       }
-       priv = sensor->priv;
-
-       if (priv->initialized) {
-               SENSOR_DEBUG("ERROR: ppd42ns driver has already been initialized.\n");
-               goto done;
-       }
-
-       /* set gpio device */
-       snprintf(priv->devpath, 16, "/dev/gpio%d", CONFIG_SENSOR_PPD42NS_GPIO_NUM);
-
-       /* init semaphore */
-       sem_init(&priv->exclsem, 0, 1);
-
-       /* init private variables */
-       priv->activated = 0;
-       priv->evt_task_loop = 0;
-       priv->pipe_evt_task[0] = -1;
-       priv->pipe_evt_task[1] = -1;
-
-       /* initialized flag is set */
-       priv->initialized = 1;
-
-       /* result is success */
-       result = 0;
-
-done:
-       return result;
-}
-
-static int ppd42ns_deinit(sensor_device_t *sensor)
-{
-       int result = -1;
-       ppd42ns_priv *priv;
-
-       if (sensor == NULL || sensor->priv == NULL) {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               goto done;
-       }
-       priv = sensor->priv;
-
-       /* deactivate if activated currently */
-       if (priv->activated) {
-               ppd42ns_deactivate(sensor);
+               /* signal HIGH -> LOW */
+               PPD42NS_TIME_GET(priv->lowpulse_start_time);
+               priv->old_signal = GPIO_SIGNAL_LOW;
        }
 
-       /* deinit semaphore */
-       sem_destroy(&priv->exclsem);
-
-       /* clear priv data */
-       memset(priv, 0, sizeof(*priv));
-
-       /* result is success */
-       result = 0;
-
-done:
-       return result;
+       /* enable interrupt */
+       irqrestore(flags);
 }
 
-static int ppd42ns_activate(sensor_device_t *sensor)
+/****************************************************************************
+ * Name: ppd42ns_open
+ *
+ * Description:
+ *   Standard character driver open method.
+ *
+ ****************************************************************************/
+static int ppd42ns_open(FAR struct file *filep)
 {
-       int result = -1;
        int ret;
-       int signal;
-       ppd42ns_priv *priv;
-       struct gpio_pollevents_s pollevents;
+       FAR struct inode *inode = filep->f_inode;
+       FAR struct ppd42ns_dev_s *priv = inode->i_private;
 
-       if (sensor == NULL || sensor->priv == NULL) {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               goto done_without_sem;
-       }
-
-       if (sensor == NULL || sensor->priv == NULL) {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               goto done_without_sem;
-       }
-       priv = sensor->priv;
-
-       if (priv->activated) {
-               SENSOR_DEBUG("ERROR: ppd42ns driver has already been activated.\n");
-               goto done_without_sem;
+       ret = ppd42ns_takesem(&priv->exclsem);
+       if (ret < 0) {
+               /*
+                * A signal received while waiting for the last close
+                * operation.
+                */
+               lldbg("ERROR: ppd42ns_takesem() failed: %d\n", ret);
+               return ret;
        }
 
-       do {
-               ret = sem_wait(&priv->exclsem);
-       } while (ret != 0 && errno == EINTR);
-
-       if (ret != 0) {
-               SENSOR_DEBUG("ERROR: sem_wait() failed.\n");
-               goto done_without_sem;
+       /* ppd42ns driver allows only 1 instance */
+       if (priv->crefs > 0) {
+               lldbg("ERROR: ppd42ns driver is already opened.\n");
+               goto errout_with_sem;
        }
 
-       /* open gpio pin */
-       priv->fd = open(priv->devpath, O_RDWR);
-       if (priv->fd < 0) {
-               SENSOR_DEBUG("ERROR: open() failed. (dev: %s)\n", priv->devpath);
-               goto done;
-       }
+       /* set reference count */
+       priv->crefs = 1;
 
-       /* set gpio direction */
-       ret = ioctl(priv->fd, GPIOIOC_SET_DIRECTION, GPIO_DIRECTION_IN);
+       /* enable the gpio pin interrupt */
+       ret = priv->config->enable(priv->config, 1);
        if (ret < 0) {
-               SENSOR_DEBUG("ERROR: ioctl() failed. (dev: %s, ioctl_id: %d, errno: %d)\n", priv->devpath, GPIOIOC_SET_DIRECTION, errno);
-               goto done;
+               lldbg("ERROR: failed to enable the interrupt handler. (ret=%d)\n", ret);
+               goto errout_with_sem;
        }
 
        /* set start time */
-       SENSOR_TIME_GET(priv->start_time);
+       PPD42NS_TIME_GET(priv->start_time);
+       priv->lowpulse_start_time = priv->start_time;
 
        /* get initial signal */
-       ret = read(priv->fd, (void *)&signal, sizeof(int));
-       if (ret < 0) {
-               SENSOR_DEBUG("ERROR: read() failed. (fd: %d, errno: %d)\n", priv->fd, errno);
-               goto done;
-       }
+       priv->old_signal = priv->config->read_gpio(priv->config);
 
-       if (signal == GPIO_SIGNAL_LOW) {
-               SENSOR_TIME_GET(priv->lowpulse_start_time);
-       }
+       /* initialize lowpulseoccupancy */
        priv->lowpulseoccupancy = 0;
-       priv->old_signal = signal;
 
-       /* set interrupt on both edge and poll event */
-       pollevents.gp_rising = true;
-       pollevents.gp_falling = true;
-       ret = ioctl(priv->fd, GPIOIOC_POLLEVENTS, (unsigned long)&pollevents);
-       if (ret < 0) {
-               SENSOR_DEBUG("ERROR: ioctl() failed. (dev: %s, ioctl_id: %d, errno: %d)\n", priv->devpath, GPIOIOC_POLLEVENTS, errno);
-               goto done;
-       }
+       ret = 0;
 
-       if (ppd42ns_event_task_start(sensor) != 0) {
-               SENSOR_DEBUG("ERROR: ppd42ns_event_task_start() failed. (dev: %s)\n", priv->devpath);
-               goto done;
-       }
-
-       /* activated flag is set */
-       priv->activated = 1;
-
-       /* result is success */
-       result = 0;
-
-done:
-       sem_post(&priv->exclsem);
-
-done_without_sem:
-       return result;
-}
-
-static int ppd42ns_deactivate(sensor_device_t *sensor)
-{
-       int result = -1;
-       int ret;
-       ppd42ns_priv *priv;
-
-       if (sensor == NULL || sensor->priv == NULL) {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               goto done_without_sem;
-       }
-       priv = sensor->priv;
-
-       do {
-               ret = sem_wait(&priv->exclsem);
-       } while (ret != 0 && errno == EINTR);
-
-       if (ret != 0) {
-               SENSOR_DEBUG("ERROR: sem_wait() failed.\n");
-               goto done_without_sem;
-       }
-
-       ppd42ns_event_task_stop(sensor);
-
-       /* close gpio */
-       close(priv->fd);
-
-       /* activated flag is unset */
-       priv->activated = 0;
-
-       /* result is success */
-       result = 0;
-
-       sem_post(&priv->exclsem);
-
-done_without_sem:
-       return result;
+errout_with_sem:
+       ppd42ns_givesem(&priv->exclsem);
+       return ret;
 }
 
-static int ppd42ns_ioctl(sensor_device_t *sensor, int id, sensor_ioctl_value_t *val)
+/****************************************************************************
+ * Name: ppd42ns_close
+ *
+ * Description:
+ *   Standard character driver close method.
+ *
+ ****************************************************************************/
+static int ppd42ns_close(FAR struct file *filep)
 {
-       int result = -1;
        int ret;
-       ppd42ns_priv *priv;
+       FAR struct inode *inode = filep->f_inode;
+       FAR struct ppd42ns_dev_s *priv = inode->i_private;
 
-       if (sensor == NULL || sensor->priv == NULL) {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               goto done_without_sem;
-       }
-       priv = sensor->priv;
-
-       if (!priv->initialized) {
-               SENSOR_DEBUG("ERROR: ppd42ns driver is not initialized.\n");
-               goto done_without_sem;
+       /* Get exclusive access to the driver structure */
+       ret = ppd42ns_takesem(&priv->exclsem);
+       if (ret < 0) {
+               lldbg("ERROR: ppd42ns_takesem() failed: %d\n", ret);
+               return ret;
        }
 
-       if (val == NULL) {
-               SENSOR_DEBUG("ERROR: ioctl val is null.\n");
-               goto done_without_sem;
+       if (priv->crefs == 0) {
+               lldbg("ERROR: ppd42ns driver is already closed.\n");
+               goto errout_with_sem;
        }
 
-       do {
-               ret = sem_wait(&priv->exclsem);
-       } while (ret != 0 && errno == EINTR);
-
-       if (ret != 0) {
-               SENSOR_DEBUG("ERROR: sem_wait() failed.\n");
-               goto done_without_sem;
-       }
+       priv->crefs = 0;
 
-       switch (id) {
-       case PPD42NS_IOCTL_ID_GET_GPIO_DEVPATH:
-               val->p_str = priv->devpath;
-               break;
-       default:
-               SENSOR_DEBUG("ERROR: unknown ioctl id. (id: %d)\n", id);
-               goto done;
+       /* disable the gpio pin interrupt */
+       ret = priv->config->enable(priv->config, 0);
+       if (ret < 0) {
+               lldbg("ERROR: failed to disable the interrupt handler. (ret=%d)\n", ret);
+               goto errout_with_sem;
        }
 
-       /* result is success */
-       result = 0;
-
-done:
-       sem_post(&priv->exclsem);
+       ret = 0;
 
-done_without_sem:
-       return result;
+errout_with_sem:
+       ppd42ns_givesem(&priv->exclsem);
+       return ret;
 }
 
-static int ppd42ns_get_data(sensor_device_t *sensor, sensor_data_t *data)
+/****************************************************************************
+ * Name: ppd42ns_read
+ *
+ * Description:
+ *   Standard character driver read method.
+ *
+ ****************************************************************************/
+static ssize_t ppd42ns_read(FAR struct file *filep, FAR char *buffer, size_t len)
 {
-       int result = -1;
+       int ret;
+       FAR struct inode *inode = filep->f_inode;
+       FAR struct ppd42ns_dev_s *priv = inode->i_private;
+       int signal;
        float ratio = 0.0;
        float concentration;
        struct timeval time;
-       int ret;
-       int signal;
-       ppd42ns_priv *priv;
-
-       if (sensor == NULL || sensor->priv == NULL) {
-               SENSOR_DEBUG("ERROR: %s is NULL.\n", sensor == NULL ? "sensor" : "sensor->priv");
-               goto done_without_sem;
-       }
-       priv = sensor->priv;
 
-       if (!priv->activated) {
-               SENSOR_DEBUG("ERROR: ppd42ns driver is not activated.\n");
-               goto done_without_sem;
+       ret = ppd42ns_takesem(&priv->datasem);
+       if (ret < 0) {
+               lldbg("ERROR: ppd42ns_takesem() failed: %d\n", ret);
+               return ret;
        }
 
-       do {
-               ret = sem_wait(&priv->exclsem);
-       } while (ret != 0 && errno == EINTR);
-
-       if (ret != 0) {
-               SENSOR_DEBUG("ERROR: sem_wait() failed.\n");
-               goto done_without_sem;
-       }
+       /* disable gpio pin interrupt */
+       priv->config->enable(priv->config, 0);
 
-       lseek(priv->fd, 0, SEEK_SET);
-       ret = read(priv->fd, (void *)&signal, sizeof(int));
-       if (ret < 0) {
-               SENSOR_DEBUG("ERROR: read() failed. (fd: %d, errno: %d)\n", priv->fd, errno);
-               goto done;
-       }
+       /* get gpio signal */
+       signal = priv->config->read_gpio(priv->config);
 
-       SENSOR_TIME_GET(time);
+       PPD42NS_TIME_GET(time);
        if (signal == GPIO_SIGNAL_LOW) {
-               priv->lowpulseoccupancy += SENSOR_TIME_DIFF_USEC(priv->lowpulse_start_time, time);
+               priv->lowpulseoccupancy += PPD42NS_TIME_DIFF_USEC(priv->lowpulse_start_time, time);
                priv->lowpulse_start_time = time;
        }
 
        if (priv->lowpulseoccupancy != 0) {
-               ratio = (float)priv->lowpulseoccupancy / (float)SENSOR_TIME_DIFF_USEC(priv->start_time, time) * 100.0;  /* Integer percentage 0=>100 */
+               ratio = (float)priv->lowpulseoccupancy / (float)PPD42NS_TIME_DIFF_USEC(priv->start_time, time) * 100.0; /* percentage 0~100 */
                concentration = 1.1 * pow(ratio, 3) - 3.8 * pow(ratio, 2) + 520 * ratio + 0.62; /* using spec sheet curve */
        } else {
                concentration = 0.0;
        }
-       data->fval = concentration;
 
-#if PPD42NS_DEBUG_ON
-       SENSOR_DEBUG("lowpulse_time=%d, total_time=%d, ratio=%.2f \n", priv->lowpulseoccupancy, SENSOR_TIME_DIFF_USEC(priv->start_time, time), ratio);
+#ifdef CONFIG_SENSOR_PPD42NS_DEBUG
+       lldbg("lowpulse_time=%d, total_time=%d, ratio=%.2f, concentration=%.2f \n", priv->lowpulseoccupancy, PPD42NS_TIME_DIFF_USEC(priv->start_time, time), ratio, concentration);
 #endif
 
        priv->start_time = time;
        priv->lowpulseoccupancy = 0;
        priv->old_signal = signal;
 
-       /* result is success */
-       result = 0;
+       /* enable gpio pin interrupt */
+       priv->config->enable(priv->config, 1);
 
-done:
-       sem_post(&priv->exclsem);
+       memcpy(buffer, &concentration, sizeof(float));
 
-done_without_sem:
-       return result;
+       ppd42ns_givesem(&priv->datasem);
+
+       return sizeof(float);
 }
 
 /****************************************************************************
- * Create Sensor Instance
+ * Public Function
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ppd42ns_register
+ *
+ * Description:
+ *  This function will register ppd42ns dust sensor driver as /dev/dustN where N
+ *  is the minor device number
+ *
+ * Input Parameters:
+ *   devname  - The full path to the driver to register. E.g., "/dev/dust0"
+ *   config      - configuration for the ppd42ns driver.
+ *
+ * Returned Value:
+ *   Zero is returned on success.  Otherwise, a negated errno value is
+ *   returned to indicate the nature of the failure.
+ *
  ****************************************************************************/
-SENSOR_CREATE_INSTANCE(SENSOR_NAME_PPD42NS, SENSOR_DEVICE_TYPE_DUST, &g_ops, &g_priv);
+int ppd42ns_register(FAR const char *devname, FAR struct ppd42ns_config_s *config)
+{
+       int ret;
+       struct ppd42ns_dev_s *priv = &g_ppd42ns_priv;
+
+       /* validate ppd42ns config */
+       if (config == NULL || config->read_gpio == NULL || config->attach == NULL || config->enable == NULL) {
+               ret = EINVAL;
+               lldbg("ERROR: invalid ppd42ns config\n");
+               return ret;
+       }
+
+       /* set ppd42ns config */
+       priv->config = config;
+
+       /* reference count is set to 0 */
+       priv->crefs = 0;
+
+       /* init semaphore */
+       sem_init(&priv->exclsem, 0, 1);
+       sem_init(&priv->datasem, 0, 1);
+
+       /* attach the interrupt handler */
+       ret = priv->config->attach(priv->config, ppd42ns_interrupt_handler, (FAR void *)priv);
+       if (ret < 0) {
+               lldbg("ERROR: failed to attach the interrupt handler. (ret=%d)\n", ret);
+               sem_destroy(&priv->exclsem);
+               sem_destroy(&priv->datasem);
+               return ret;
+       }
+
+       /* register the character device driver */
+       ret = register_driver(devname, &g_ppd42ns_fops, 0666, priv);
+       if (ret < 0) {
+               lldbg("ERROR: failed to register driver %s. (ret=%d)\n", devname, ret);
+               sem_destroy(&priv->exclsem);
+               sem_destroy(&priv->datasem);
+               return ret;
+       }
+
+       lldbg("Registered %s\n", devname);
+
+       return 0;
+}
index 1616b13..fc0aa5f 100644 (file)
 /****************************************************************************
  * Included Files
  ****************************************************************************/
-#include <tinyara/sensors/sensor.h>
 
-#define SENSOR_NAME_PPD42NS                            ppd42ns
-SENSOR_EXTERNAL_FUNCTION_PROTOTYPE(SENSOR_NAME_PPD42NS);
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+typedef void (*ppd42ns_handler_t)(FAR void *arg);
+
+struct ppd42ns_config_s {
+       /* gpio pin number */
+       int gpionum;
+
+       /* callback function: read gpio pin signal */
+       int (*read_gpio)(struct ppd42ns_config_s *config);
 
-/********************
-   definitions
- ********************/
-#define PPD42NS_DEBUG_ON                       0
+       /* callback function: attach the ppd42ns interrupt handler to the GPIO interrupt */
+       int (*attach)(struct ppd42ns_config_s *config, ppd42ns_handler_t handler, FAR char *arg);
 
-/********************
-   custom ioctl id
- ********************/
-#define PPD42NS_IOCTL_ID_GET_GPIO_DEVPATH                      (SENSOR_IOCTL_ID_CUSTOM + 0)
+       /* callback function: enable or disable gpio pin interrupt */
+       int (*enable)(struct ppd42ns_config_s *config, int enable);
+
+       /* board specific data */
+       void *priv;
+};
+
+/****************************************************************************
+ * Public Function
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ppd42ns_register
+ *
+ * Description:
+ *  This function will register ppd42ns dust sensor driver as /dev/dustN where N
+ *  is the minor device number
+ *
+ * Input Parameters:
+ *   devname  - The full path to the driver to register. E.g., "/dev/dust0"
+ *   config      - configuration for the ppd42ns driver.
+ *
+ * Returned Value:
+ *   Zero is returned on success.  Otherwise, a negated errno value is
+ *   returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+int ppd42ns_register(FAR const char *devname, FAR struct ppd42ns_config_s *config);
 
 #endif                                                 /* __PPD42NS_H__ */
diff --git a/os/include/tinyara/sensors/sensor.h b/os/include/tinyara/sensors/sensor.h
deleted file mode 100644 (file)
index d4cc509..0000000
+++ /dev/null
@@ -1,431 +0,0 @@
-/****************************************************************************
- *
- * Copyright 2017 Samsung Electronics All Rights Reserved.
- *
- * Licensed 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.
- *
- ****************************************************************************/
-/**
- * @file sensor.h
- * @brief Sensor API definition
- * @version 0.3
- */
-
-#ifndef __SENSOR_H__
-#define __SENSOR_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <debug.h>
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-/**
- * @brief Enumeration of sensor device type
- */
-typedef enum {
-       SENSOR_DEVICE_TYPE_ACCELEROMETER,
-       SENSOR_DEVICE_TYPE_GYROSCOPE,
-       SENSOR_DEVICE_TYPE_MAGNETIC_FIELD,
-       SENSOR_DEVICE_TYPE_TEMPERATURE,
-       SENSOR_DEVICE_TYPE_HUMIDITY,
-       SENSOR_DEVICE_TYPE_PRESSURE,
-       SENSOR_DEVICE_TYPE_LIGHT,
-       SENSOR_DEVICE_TYPE_DUST,
-       SENSOR_DEVICE_TYPE_END
-}
-sensor_device_type_e;
-
-/**
- * @brief Enumeration of sensor device attribute
- */
-typedef enum {
-       SENSOR_IOCTL_ID_GET_TRIGGER_TYPE,
-       SENSOR_IOCTL_ID_FREQUENCY,
-       SENSOR_IOCTL_ID_CUSTOM = 0x8000,
-} sensor_ioctl_id_e;
-
-/**
- * @brief Enumeration of sensor trigger type
- */
-typedef enum {
-       SENSOR_TRIGGER_TYPE_DATA_READY,
-       SENSOR_TRIGGER_TYPE_TIMER,
-       SENSOR_TRIGGER_TYPE_END
-} sensor_trigger_type_e;
-
-/**
- * @brief Structure of sensor value
- */
-typedef struct {
-       union {
-               int ival;
-               float fval;
-               double dval;
-               char *p_str;
-               void *p;
-       };
-} sensor_ioctl_value_t;
-
-/**
- * @brief Structure of sensor data
- */
-typedef struct {
-       union {
-               float v[3];
-               struct {
-                       float x;
-                       float y;
-                       float z;
-               };
-               struct {
-                       float azimuth;
-                       float pitch;
-                       float roll;
-               };
-               int ival;
-               float fval;
-               double dval;
-       };
-} sensor_data_t;
-
-/**
- * @brief Structure of sensor trigger information
- */
-typedef struct {
-       sensor_trigger_type_e type;
-} sensor_trigger_info_t;
-
-/**
- * @brief Definition of sensor_device_t type
- */
-typedef struct sensor_device_t sensor_device_t;
-
-/**
- * @brief Pointer definition to trigger callback function
- */
-typedef int (*sensor_trigger_callback_t)(sensor_device_t *sensor, sensor_data_t *data);
-
-/**
- * @brief Pointer definition to sensor operations
- */
-typedef int (*sensor_init_t)(sensor_device_t *sensor);
-typedef int (*sensor_deinit_t)(sensor_device_t *sensor);
-typedef int (*sensor_activate_t)(sensor_device_t *sensor);
-typedef int (*sensor_deactivate_t)(sensor_device_t *sensor);
-typedef int (*sensor_ioctl_t)(sensor_device_t *sensor, int id, sensor_ioctl_value_t *val);
-typedef int (*sensor_set_trigger_t)(sensor_device_t *sensor, sensor_trigger_info_t info, sensor_trigger_callback_t callback);
-typedef int (*sensor_get_data_t)(sensor_device_t *sensor, sensor_data_t *data);
-
-/**
- * @brief Structure of sensor operations
- */
-typedef struct {
-       sensor_init_t init;             /* initialize sensor device */
-       sensor_deinit_t deinit; /* deinitialize sensor device */
-       sensor_activate_t activate;     /* activate sensor device */
-       sensor_deactivate_t deactivate; /* deactivate sensor device */
-       sensor_ioctl_t ioctl;   /* ioctl on sensor device */
-       sensor_set_trigger_t set_trigger;       /* set trigger information and calback function */
-       sensor_get_data_t get_data;     /* get sensor data from device */
-} sensor_operations_t;
-
-/**
- * @brief Structure of sensor device
- */
-struct sensor_device_t {
-       sensor_device_type_e type;      /* sensor device type */
-       sensor_operations_t *ops;       /* sensor opertaions */
-       void *priv;                             /* private data of a specified device */
-};
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-#define __NAME_STRING(name)    #name
-#define __SENSOR_CREATE_INSTANCE(name, _type, _ops, _priv) \
-       static sensor_device_t g_sensor_##name = { \
-               .type = _type, \
-               .ops = _ops, \
-               .priv = _priv, \
-       }; \
-       \
-       sensor_device_t * name##_get_handle(void) { \
-               return &g_sensor_##name; \
-       }; \
-       \
-       sensor_operations_t * name##_get_ops_handle(void) { \
-               return (&g_sensor_##name)->ops ? (&g_sensor_##name)->ops : NULL; \
-       }
-
-#define __SENSOR_EXTERNAL_FUNCTION_PROTOTYPE(name) \
-       sensor_device_t * name##_get_handle(void); \
-       sensor_operations_t * name##_get_ops_handle(void)
-
-#define __SENSOR_GET_HANDLE(name)                      name##_get_handle()
-#define __SENSOR_GET_OPS_HANDLE(name)          name##_get_ops_handle()
-#define __SENSOR_GET_NAME_STRING(name)         __NAME_STRING(name)
-
-/***************************
-  For Debug
- ***************************/
-#define SENSOR_DEBUG_ON                                1
-#if SENSOR_DEBUG_ON
-#define SENSOR_DEBUG(format, ...)   dbg(format, ##__VA_ARGS__)
-#else
-#define SENSOR_DEBUG(x...)                     (void)0
-#endif
-
-/***************************
-  For Sensor Driver Developers
- ***************************/
-
-/****************************************************************************
- * Name: SENSOR_CREATE_INSTANCE
- *
- * Description:
- *   create a sensor device instance as sensor_device_t.
- *
- * Parameters:
- *   name - sensor device name.
- *          generally, SENSOR_NAME_XXXXX will be a name. it is in the specified sensor driver's header file.
- *   _type - sensor device type as sensor_device_type_e type.
- *   _ops - sensor operations handle as sensor_operations_t type.
- *   _priv - sensor device's private data handle as void type.
- *
- * Returned Value:
- *   none.
- *
- ****************************************************************************/
-#define SENSOR_CREATE_INSTANCE(name, _type, _ops, _priv)       __SENSOR_CREATE_INSTANCE(name, _type, _ops, _priv)
-
-/****************************************************************************
- * Name: SENSOR_GET_NAME_STRING
- *
- * Description:
- *   declare external function prototype.
- *
- * Parameters:
- *   name - sensor device name.
- *          generally, SENSOR_NAME_XXXXX will be a name. it is in the specified sensor driver's header file.
- *
- * Returned Value:
- *   none.
- *
- ****************************************************************************/
-#define SENSOR_EXTERNAL_FUNCTION_PROTOTYPE(name)                       __SENSOR_EXTERNAL_FUNCTION_PROTOTYPE(name)
-
-/***************************
-  For Upper Layer Developers
- ***************************/
-
-/****************************************************************************
- * Name: SENSOR_GET_NAME_STRING
- *
- * Description:
- *   get a name as string type.
- *
- * Parameters:
- *   name - sensor device name.
- *          generally, SENSOR_NAME_XXXXX will be a name. it is in the specified sensor driver's header file.
- *
- * Returned Value:
- *   a name as string type is returned.
- *
- ****************************************************************************/
-#define SENSOR_GET_NAME_STRING(name)    __SENSOR_GET_NAME_STRING(name)
-
-/****************************************************************************
- * Name: SENSOR_GET_HANDLE
- *
- * Description:
- *   get a sensor device handle.
- *
- * Parameters:
- *   name - sensor device name.
- *          generally, SENSOR_NAME_XXXXX will be a name. it is in the specified sensor driver's header file.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_GET_HANDLE(name)                __SENSOR_GET_HANDLE(name)
-
-/****************************************************************************
- * Name: SENSOR_GET_DEVICE_TYPE
- *
- * Description:
- *   get sensor device type as sensor_device_type_e type.
- *
- * Parameters:
- *   handle - sensor device handle.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_GET_DEVICE_TYPE(handle) (handle ? handle->type : -1)
-
-/****************************************************************************
- * Name: SENSOR_INIT
- *
- * Description:
- *   initialize  the specified sensor device.
- *
- * Parameters:
- *   handle - sensor device handle.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_INIT(handle)                    (handle && handle->ops ? handle->ops->init(handle) : -1)
-
-/****************************************************************************
- * Name: SENSOR_DEINIT
- *
- * Description:
- *   deinitialize  the specified sensor device.
- *
- * Parameters:
- *   handle - sensor device handle.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_DEINIT(handle)                  (handle && handle->ops ? handle->ops->deinit(handle) : -1)
-
-/****************************************************************************
- * Name: SENSOR_ACTIVATE
- *
- * Description:
- *   activate  the specified sensor device.
- *
- * Parameters:
- *   handle - sensor device handle.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_ACTIVATE(handle)                (handle && handle->ops ? handle->ops->activate(handle) : -1)
-
-/****************************************************************************
- * Name: SENSOR_DEACTIVATE
- *
- * Description:
- *   deactivate  the specified sensor device.
- *
- * Parameters:
- *   handle - sensor device handle.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_DEACTIVATE(handle)              (handle && handle->ops ? handle->ops->deactivate(handle) : -1)
-
-/****************************************************************************
- * Name: SENSOR_IOCTL
- *
- * Description:
- *   do ioctl on the specified sensor device.
- *
- * Parameters:
- *   handle - sensor device handle.
- *   id - ioctl id as sensor_ioctl_id_e type.
- *   pval -ioctl value as sensor_ioctl_value_t type.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_IOCTL(handle, id, pval)         (handle && handle->ops ? handle->ops->ioctl(handle, id, pval) : -1)
-
-/****************************************************************************
- * Name: SENSOR_SET_TRIGGER
- *
- * Description:
- *   set trigger on the specified sensor device.
- *
- * Parameters:
- *   handle - sensor device handle.
- *   info - trigger information as sensor_trigger_info_t type.
- *   callback - callback function as sensor_trigger_callback_t type.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_SET_TRIGGER(handle, info, callback)     (handle && handle->ops ? handle->ops->set_trigger(handle, info, callback) : -1)
-
-/****************************************************************************
- * Name: SENSOR_GET_DATA
- *
- * Description:
- *   get data from the specified sensor device.
- *
- * Parameters:
- *   handle - sensor device handle.
- *   pdata - data as sensor_data_t type.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_GET_DATA(handle, pdata) (handle && handle->ops ? handle->ops->get_data(handle, pdata) : -1)
-
-/***************************
-  Utilities
- ***************************/
-
-/****************************************************************************
- * Name: SENSOR_TIME_GET
- *
- * Description:
- *   get time information as 'struct timeval' type.
- *
- * Parameters:
- *   time - the pointer of 'struct timeval' type variable.
- *
- * Returned Value:
- *   on success, 0 is returned. on failure, a negative value is returned.
- *
- ****************************************************************************/
-#define SENSOR_TIME_GET(time)          gettimeofday(&time, NULL)
-
-/****************************************************************************
- * Name: SENSOR_TIME_GET
- *
- * Description:
- *   get time differential in usec beween old time and current time.
- *
- * Parameters:
- *   old_time - old time's pointer variable that points 'struct timeval' type.
- *   cur_time - current time's pointer variable that points 'struct timeval' type.
- *
- * Returned Value:
- *   time differentil in usec
- *
- ****************************************************************************/
-#define SENSOR_TIME_DIFF_USEC(old_time, cur_time) \
-        ((cur_time.tv_sec * 1000000 + cur_time.tv_usec) - (old_time.tv_sec * 1000000 + old_time.tv_usec))
-
-#ifdef __cplusplus
-}
-#endif
-#endif                                                 /* __SENSOR_H__ */