summaryrefslogtreecommitdiff
path: root/drivers/grove
diff options
context:
space:
mode:
authorBogdan Davidoaia <bogdan.m.davidoaia@intel.com>2016-05-06 16:33:21 +0300
committerAnas Nashif <nashif@linux.intel.com>2016-05-12 12:11:04 +0000
commit62c7a1338a042e757c57b44a7c9162a30c7772b0 (patch)
tree740f319b62b161c576ff137952fe8ae8ddd6ee59 /drivers/grove
parent059d97839e033b1541e8c961e3527f92fc3ee203 (diff)
grove: add light sensor
Add driver for the Grove Light Sensor which detects changes in ambient light. Sensor reference page: http://www.seeedstudio.com/wiki/Grove_-_Light_Sensor Origin: Original Change-Id: I88ae20cc9faa8ab8f274b0bd7a114db5c1a87a91 Signed-off-by: Bogdan Davidoaia <bogdan.m.davidoaia@intel.com>
Diffstat (limited to 'drivers/grove')
-rw-r--r--drivers/grove/Kconfig45
-rw-r--r--drivers/grove/Makefile1
-rw-r--r--drivers/grove/light_sensor.c100
3 files changed, 146 insertions, 0 deletions
diff --git a/drivers/grove/Kconfig b/drivers/grove/Kconfig
index a544b2aa4..3a99865c1 100644
--- a/drivers/grove/Kconfig
+++ b/drivers/grove/Kconfig
@@ -66,3 +66,48 @@ config GROVE_LCD_RGB_INIT_PRIORITY
Device driver initialization priority.
As the device is connected to I2C bus, its driver has
to be initialized after the I2C one.
+
+config GROVE_LIGHT_SENSOR
+ bool
+ prompt "Enable the Seeed Grove Light Sensor"
+ depends on GROVE && ADC && NEWLIB_LIBC
+ default n
+ help
+ Setting this value will enable dirver support for the Grove Light
+ Sensor.
+
+config GROVE_LIGHT_SENSOR_NAME
+ string
+ prompt "Driver name"
+ depends on GROVE_LIGHT_SENSOR
+ default "GROVE_LIGHT_SENSOR"
+ help
+ Specify the device name with which the sensor is identified.
+
+config GROVE_LIGHT_SENSOR_ADC_DEV_NAME
+ string
+ prompt "ADC where Grove Light Sensor is connected"
+ depends on GROVE_LIGHT_SENSOR
+ default "ADC_0"
+ help
+ Specify the device name of the ADC to which the Grove Light Sensor
+ is connected.
+
+config GROVE_LIGHT_SENSOR_ADC_CHANNEL
+ int
+ prompt "ADC channel used by Grove Light Sensor"
+ depends on GROVE_LIGHT_SENSOR
+ default 10
+ help
+ Specify the channel of the ADC to which the Grove Light Sensor is
+ connected.
+
+config GROVE_LIGHT_SENSOR_INIT_PRIORITY
+ int
+ prompt "Init priority"
+ default 70
+ depends on GROVE_LIGHT_SENSOR
+ help
+ Device driver initialization priority.
+ As the device is connected to an ADC device, its driver has to be
+ initialized after the ADC device.
diff --git a/drivers/grove/Makefile b/drivers/grove/Makefile
index 499e25753..cafde1859 100644
--- a/drivers/grove/Makefile
+++ b/drivers/grove/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_GROVE_LCD_RGB) += lcd_rgb.o
+obj-$(CONFIG_GROVE_LIGHT_SENSOR) += light_sensor.o
diff --git a/drivers/grove/light_sensor.c b/drivers/grove/light_sensor.c
new file mode 100644
index 000000000..92ba181a5
--- /dev/null
+++ b/drivers/grove/light_sensor.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * 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.
+ */
+
+#include <adc.h>
+#include <device.h>
+#include <math.h>
+#include <sensor.h>
+#include <zephyr.h>
+
+#define SYS_LOG_DOMAIN "GROVE_LIGHT_SENSOR"
+#define SYS_LOG_LEVEL CONFIG_GROVE_SYS_LOG_LEVEL
+#include <misc/sys_log.h>
+
+struct gls_data {
+ struct device *adc;
+ struct adc_seq_entry sample;
+ struct adc_seq_table adc_table;
+ uint8_t adc_buffer[4];
+};
+
+static int gls_sample_fetch(struct device *dev, enum sensor_channel chan)
+{
+ struct gls_data *drv_data = dev->driver_data;
+
+ return adc_read(drv_data->adc, &drv_data->adc_table);
+}
+
+static int gls_channel_get(struct device *dev,
+ enum sensor_channel chan,
+ struct sensor_value *val)
+{
+ struct gls_data *drv_data = dev->driver_data;
+ uint16_t analog_val;
+ double ldr_val;
+
+ /* rescale sample from 12bit (Zephyr) to 10bit (Grove) */
+ analog_val = ((uint16_t)drv_data->adc_buffer[1] << 8) |
+ drv_data->adc_buffer[0];
+ analog_val = analog_val >> 2;
+
+ /*
+ * The formula for converting the analog value to lux is taken from
+ * the UPM project:
+ * https://github.com/intel-iot-devkit/upm/blob/master/src/grove/grove.cxx#L161
+ */
+ ldr_val = (1023.0 - analog_val) * 10.0 / analog_val;
+ val->type = SENSOR_VALUE_TYPE_DOUBLE;
+ val->dval = 10000.0 / pow(ldr_val * 15.0, 4.0/3.0);
+
+ return 0;
+}
+
+static struct sensor_driver_api gls_api = {
+ .sample_fetch = &gls_sample_fetch,
+ .channel_get = &gls_channel_get,
+};
+
+static int gls_init(struct device *dev)
+{
+ struct gls_data *drv_data = dev->driver_data;
+
+ drv_data->adc =
+ device_get_binding(CONFIG_GROVE_LIGHT_SENSOR_ADC_DEV_NAME);
+ if (drv_data->adc == NULL) {
+ SYS_LOG_ERR("Failed to get ADC device.");
+ return -EINVAL;
+ }
+
+ drv_data->sample.sampling_delay = 12;
+ drv_data->sample.channel_id = CONFIG_GROVE_LIGHT_SENSOR_ADC_CHANNEL;
+ drv_data->sample.buffer = drv_data->adc_buffer;
+ drv_data->sample.buffer_length = 4;
+
+ drv_data->adc_table.entries = &drv_data->sample;
+ drv_data->adc_table.num_entries = 1;
+
+ adc_enable(drv_data->adc);
+
+ dev->driver_api = &gls_api;
+
+ return 0;
+}
+
+struct gls_data gls_data;
+
+DEVICE_INIT(gls_dev, CONFIG_GROVE_LIGHT_SENSOR_NAME, &gls_init, &gls_data,
+ NULL, SECONDARY, CONFIG_GROVE_LIGHT_SENSOR_INIT_PRIORITY);