drivers: Add apds9960 sensor in polling mode
This patch implements following functionality in polling mode. Ambient light RGB light proximity sensor Following datasheet has been used to develop driver https://docs.broadcom.com/docs/AV02-4191EN Jira: ZEP-1552 Signed-off-by: Punit Vara <punit.vara@intel.com>
This commit is contained in:
parent
1bd9fcc0e3
commit
f60fc94abd
6 changed files with 796 additions and 0 deletions
|
@ -44,6 +44,8 @@ source "drivers/sensor/adxl362/Kconfig"
|
|||
|
||||
source "drivers/sensor/ak8975/Kconfig"
|
||||
|
||||
source "drivers/sensor/apds9960/Kconfig"
|
||||
|
||||
source "drivers/sensor/bma280/Kconfig"
|
||||
|
||||
source "drivers/sensor/bmc150_magn/Kconfig"
|
||||
|
|
|
@ -2,6 +2,7 @@ ccflags-y +=-I$(srctree)/drivers
|
|||
|
||||
obj-$(CONFIG_ADXL362) += adxl362/
|
||||
obj-$(CONFIG_AK8975) += ak8975/
|
||||
obj-$(CONFIG_APDS9960) += apds9960/
|
||||
obj-$(CONFIG_BMA280) += bma280/
|
||||
obj-$(CONFIG_BMC150_MAGN) += bmc150_magn/
|
||||
obj-$(CONFIG_BME280) += bme280/
|
||||
|
|
28
drivers/sensor/apds9960/Kconfig
Normal file
28
drivers/sensor/apds9960/Kconfig
Normal file
|
@ -0,0 +1,28 @@
|
|||
#
|
||||
# Copyright (c) 2017 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
menuconfig APDS9960
|
||||
bool "APDS9960 Sensor"
|
||||
depends on SENSOR && I2C
|
||||
default n
|
||||
help
|
||||
Enable driver for APDS9960 sensors.
|
||||
|
||||
config APDS9960_I2C_DEV_NAME
|
||||
string "I2C Master"
|
||||
depends on APDS9960
|
||||
default I2C_SS_0_NAME
|
||||
help
|
||||
The device name of the I2C master device to which the APDS9960
|
||||
chip is connected.
|
||||
|
||||
config APDS9960_DRV_NAME
|
||||
string
|
||||
prompt "Driver name"
|
||||
default "APDS9960"
|
||||
depends on APDS9960
|
||||
help
|
||||
Device name with which the APDS9960 is identified.
|
3
drivers/sensor/apds9960/Makefile
Normal file
3
drivers/sensor/apds9960/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
ccflags-y +=-I$(srctree)/drivers
|
||||
|
||||
obj-$(CONFIG_APDS9960) += apds9960.o
|
484
drivers/sensor/apds9960/apds9960.c
Normal file
484
drivers/sensor/apds9960/apds9960.c
Normal file
|
@ -0,0 +1,484 @@
|
|||
/*
|
||||
*
|
||||
*Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
*SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
/* @file
|
||||
* @brief driver for APDS9960 ALS/RGB/gesture/proximity sensor
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <sensor.h>
|
||||
#include <i2c.h>
|
||||
#include <misc/__assert.h>
|
||||
#include <init.h>
|
||||
#include <kernel.h>
|
||||
|
||||
#include "apds9960.h"
|
||||
|
||||
static int apds9960_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
u8_t cmsb, clsb, rmsb, rlsb, blsb, bmsb, glsb, gmsb;
|
||||
u8_t pdata;
|
||||
int temp = 0;
|
||||
|
||||
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
|
||||
|
||||
/* Read lower byte following by MSB Ref: Datasheet : RGBC register */
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_CDATAL_REG, &clsb);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_CDATAH_REG, &cmsb);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_RDATAL_REG, &rlsb);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_RDATAH_REG, &rmsb);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_GDATAL_REG, &glsb);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_GDATAH_REG, &gmsb);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_BDATAL_REG, &blsb);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_BDATAH_REG, &bmsb);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_PDATA_REG, &pdata);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
data->sample_c = (cmsb << 8) + clsb;
|
||||
data->sample_r = (rmsb << 8) + rlsb;
|
||||
data->sample_g = (gmsb << 8) + glsb;
|
||||
data->sample_b = (bmsb << 8) + blsb;
|
||||
data->pdata = pdata;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apds9960_channel_get(struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
|
||||
switch (chan) {
|
||||
case SENSOR_CHAN_LIGHT:
|
||||
val->val1 = data->sample_c;
|
||||
val->val2 = 0;
|
||||
break;
|
||||
case SENSOR_CHAN_RED:
|
||||
val->val1 = data->sample_r;
|
||||
val->val2 = 0;
|
||||
break;
|
||||
case SENSOR_CHAN_GREEN:
|
||||
val->val1 = data->sample_g;
|
||||
val->val2 = 0;
|
||||
break;
|
||||
case SENSOR_CHAN_BLUE:
|
||||
val->val1 = data->sample_b;
|
||||
val->val2 = 0;
|
||||
break;
|
||||
case SENSOR_CHAN_PROX:
|
||||
val->val1 = data->pdata;
|
||||
val->val2 = 0;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apds9960_setproxint_lowthresh(struct device *dev, u8_t threshold)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
int temp = 0;
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_PILT_REG, threshold);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR(" Failed");
|
||||
return temp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apds9960_setproxint_highthresh(struct device *dev, u8_t threshold)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
int temp = 0;
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_PIHT_REG, threshold);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR(" Failed");
|
||||
return temp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apds9960_setlightint_lowthresh(struct device *dev, u16_t threshold)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
int temp = 0;
|
||||
u8_t val_low;
|
||||
u8_t val_high;
|
||||
|
||||
/* Break 16-bit threshold into 2 8-bit values */
|
||||
val_low = threshold & 0x00FF;
|
||||
val_high = (threshold & 0xFF00) >> 8;
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_INT_AILTL_REG, val_low);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR(" Failed");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_INT_AILTH_REG, val_high);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR(" Failed");
|
||||
return temp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apds9960_setlightint_highthresh(struct device *dev, u16_t threshold)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
int temp = 0;
|
||||
u8_t val_low;
|
||||
u8_t val_high;
|
||||
|
||||
/* Break 16-bit threshold into 2 8-bit values */
|
||||
val_low = threshold & 0x00FF;
|
||||
val_high = (threshold & 0xFF00) >> 8;
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_INT_AIHTL_REG, val_low);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR(" Failed");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_INT_AIHTH_REG, val_high);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR(" Failed");
|
||||
return temp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apds9960_proxy_setup(struct device *dev, int gain)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
int temp = 0;
|
||||
u8_t mask = APDS9960_ENABLE_PROXY | APDS9960_ENABLE_PIEN;
|
||||
u8_t val = APDS9960_PROXY_ON;
|
||||
|
||||
/* Power ON */
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ENABLE_REG, BIT(0), APDS9960_POWER_ON);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Power on bit not set.");
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* ADC value */
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ATIME_REG, APDS9960_ATIME_WRTIE, APDS9960_ADC_VALUE);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("ADC bits are not written");
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* proxy Gain */
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_CONTROL_REG, APDS9960_CONTROL_PGAIN,
|
||||
(gain & APDS9960_PGAIN_8X));
|
||||
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("proxy Gain is not set");
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Enable proxy */
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ENABLE_REG, mask, val);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Proxy is not enabled");
|
||||
return temp;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
static int apds9960_ambient_setup(struct device *dev, int gain)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
int temp = 0;
|
||||
|
||||
/* Power ON */
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ENABLE_REG, BIT(0), APDS9960_POWER_ON);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Power on bit not set.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* ADC value */
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ATIME_REG, APDS9960_ATIME_WRTIE, APDS9960_ADC_VALUE);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("ADC bits are not written");
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* ALE Gain */
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_CONTROL_REG, APDS9960_CONTROL_AGAIN,
|
||||
(gain & APDS9960_AGAIN_64X));
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Ambient Gain is not set");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ENABLE_REG, BIT(4), 0x00);
|
||||
if (temp < 0) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Enable ALE */
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ENABLE_REG, APDS9960_ENABLE_ALE, APDS9960_RGB_ON);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Proxy is not enabled");
|
||||
return temp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apds9960_sensor_setup(struct device *dev, int gain)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
int temp = 0;
|
||||
u8_t chip_id;
|
||||
|
||||
temp = i2c_reg_read_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ID_REG, &chip_id);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("failed reading chip id");
|
||||
return temp;
|
||||
}
|
||||
|
||||
if (!((chip_id == APDS9960_ID_1) || (chip_id == APDS9960_ID_2))) {
|
||||
SYS_LOG_ERR("invalid chip id 0x%x", chip_id);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ENABLE_REG, APDS9960_ALL_BITS,
|
||||
APDS9960_MODE_OFF);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("ENABLE registered is not cleared");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_ATIME_REG, APDS9960_DEFAULT_ATIME);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Default integration time not set for ADC");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_WTIME_REG, APDS9960_DEFAULT_WTIME);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Default wait time not set ");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_PPULSE_REG, APDS9960_DEFAULT_PROX_PPULSE);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Default proximity ppulse not set ");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_POFFSET_UR_REG, APDS9960_DEFAULT_POFFSET_UR);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Default poffset UR not set ");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_POFFSET_DL_REG, APDS9960_DEFAULT_POFFSET_DL);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Default poffset DL not set ");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_CONFIG1_REG, APDS9960_DEFAULT_CONFIG1);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Default config1 not set ");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_CONTROL_REG, APDS9960_CONTROL_LDRIVE,
|
||||
APDS9960_DEFAULT_LDRIVE);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("LEDdrive not set");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_CONTROL_REG, APDS9960_CONTROL_PGAIN,
|
||||
(gain & APDS9960_DEFAULT_PGAIN));
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("proxy Gain is not set");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_update_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_CONTROL_REG, APDS9960_CONTROL_AGAIN,
|
||||
(gain & APDS9960_DEFAULT_AGAIN));
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Ambient Gain is not set");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = apds9960_setproxint_lowthresh(dev, APDS9960_DEFAULT_PILT);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("prox low threshold not set");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = apds9960_setproxint_highthresh(dev, APDS9960_DEFAULT_PIHT);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("prox high threshold not set");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = apds9960_setlightint_lowthresh(dev, APDS9960_DEFAULT_AILT);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("light low threshold not set");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = apds9960_setlightint_highthresh(dev, APDS9960_DEFAULT_AIHT);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("light high threshold not set");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_PERS_REG, APDS9960_DEFAULT_PERS);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("ALS interrupt persistence not set ");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = i2c_reg_write_byte(data->i2c, APDS9960_I2C_ADDRESS,
|
||||
APDS9960_CONFIG2_REG, APDS9960_DEFAULT_CONFIG2);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("clear diode saturation interrupt is not enabled");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = apds9960_proxy_setup(dev, gain);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Failed to setup proximity functionality");
|
||||
return temp;
|
||||
}
|
||||
|
||||
temp = apds9960_ambient_setup(dev, gain);
|
||||
if (temp < 0) {
|
||||
SYS_LOG_ERR("Failed to setup ambient light functionality");
|
||||
return temp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sensor_driver_api apds9960_driver_api = {
|
||||
.sample_fetch = &apds9960_sample_fetch,
|
||||
.channel_get = &apds9960_channel_get,
|
||||
};
|
||||
|
||||
static int apds9960_init(struct device *dev)
|
||||
{
|
||||
struct apds9960_data *data = dev->driver_data;
|
||||
int als_gain = 0;
|
||||
|
||||
data->i2c = device_get_binding(CONFIG_APDS9960_I2C_DEV_NAME);
|
||||
|
||||
if (data->i2c == NULL) {
|
||||
SYS_LOG_ERR("Failed to get pointer to %s device!",
|
||||
CONFIG_APDS9960_I2C_DEV_NAME);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data->sample_c = 0;
|
||||
data->sample_r = 0;
|
||||
data->sample_g = 0;
|
||||
data->sample_b = 0;
|
||||
data->pdata = 0;
|
||||
|
||||
apds9960_sensor_setup(dev, als_gain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct apds9960_data apds9960_data;
|
||||
|
||||
DEVICE_AND_API_INIT(apds9960, CONFIG_APDS9960_DRV_NAME, &apds9960_init,
|
||||
&apds9960_data, NULL, POST_KERNEL,
|
||||
CONFIG_SENSOR_INIT_PRIORITY, &apds9960_driver_api);
|
278
drivers/sensor/apds9960/apds9960.h
Normal file
278
drivers/sensor/apds9960/apds9960.h
Normal file
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _SENSOR_APDS9960_H_
|
||||
#define _SENSOR_APDS9960_H_
|
||||
|
||||
#define APDS9960_I2C_ADDRESS 0x39
|
||||
|
||||
#define APDS9960_ENABLE_REG 0x80
|
||||
#define APDS9960_RGB_ON 0x03
|
||||
|
||||
#define APDS9960_ENABLE_PIEN BIT(5)
|
||||
#define APDS9960_ENABLE_PON BIT(0)
|
||||
#define APDS9960_ENABLE_AEN BIT(1)
|
||||
#define APDS9960_ENABLE_AIEN BIT(4)
|
||||
#define APDS9960_ENABLE_WEN BIT(3)
|
||||
#define APDS9960_ENABLE_ALE (BIT(0) | BIT(1))
|
||||
|
||||
#define APDS9960_ENABLE_PROXY (BIT(0) | BIT(2))
|
||||
#define APDS9960_CONTROL_AGAIN (BIT(0) | BIT(1))
|
||||
#define APDS9960_CONTROL_PGAIN (BIT(3) | BIT(2))
|
||||
#define APDS9960_CONTROL_LDRIVE (BIT(6) | BIT(7))
|
||||
#define APDS9960_POWER_ON 1
|
||||
#define APDS9960_ALL_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3) |\
|
||||
BIT(4) | BIT(5) | BIT(6) | BIT(7))
|
||||
#define APDS9960_ATIME_REG 0x81
|
||||
#define APDS9960_ADC_VALUE 0xB6
|
||||
#define APDS9960_ATIME_WRTIE (BIT(0) | BIT(1) | BIT(2) | BIT(3) |\
|
||||
BIT(4) | BIT(5) | BIT(6) | BIT(7))
|
||||
#define APDS9960_WTIME_REG 0x83
|
||||
|
||||
#define APDS9960_INT_AILTL_REG 0x84
|
||||
#define APDS9960_INT_AILTH_REG 0x85
|
||||
#define APDS9960_INT_AIHTL_REG 0x86
|
||||
#define APDS9960_INT_AIHTH_REG 0x87
|
||||
|
||||
#define APDS9960_INT_PILT_REG 0x89
|
||||
#define APDS9960_INT_PIHT_REG 0x8B
|
||||
|
||||
#define APDS9960_ID_REG 0x92
|
||||
|
||||
/* Acceptable device IDs */
|
||||
#define APDS9960_ID_1 0xAB
|
||||
#define APDS9960_ID_2 0x9C
|
||||
|
||||
#define APDS9960_STATUS_REG 0x93
|
||||
#define APDS9960_STATUS_CPSAT BIT(7)
|
||||
#define APDS9960_STATUS_AINT BIT(4)
|
||||
#define APDS9960_STATUS_AVALID BIT(0)
|
||||
|
||||
#define APDS9960_CDATAL_REG 0x94
|
||||
#define APDS9960_CDATAH_REG 0x95
|
||||
|
||||
#define APDS9960_RDATAL_REG 0x96
|
||||
#define APDS9960_RDATAH_REG 0x97
|
||||
|
||||
#define APDS9960_GDATAL_REG 0x98
|
||||
#define APDS9960_GDATAH_REG 0x99
|
||||
|
||||
#define APDS9960_BDATAL_REG 0x9A
|
||||
#define APDS9960_BDATAH_REG 0x9B
|
||||
|
||||
#define APDS9960_IFORCE_REG 0xE4
|
||||
#define APDS9960_CICLEAR_REG 0xE6
|
||||
#define APDS9960_AICLEAR_REG 0xE7
|
||||
|
||||
#define APDS9960_CONFIG1_REG 0x8D
|
||||
#define APDS9960_CONFIG1_WLONG BIT(1)
|
||||
|
||||
#define APDS9960_CONFIG2_REG 0x90
|
||||
#define APDS9960_CONFIG2_CPSIEN BIT(6)
|
||||
|
||||
#define APDS9960_CONFIG3_REG 0x9F
|
||||
|
||||
#define APDS9960_PERS_REG 0x8C
|
||||
#define APDS9960_APERS_SHIFT 0
|
||||
#define APDS9960_APERS_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
|
||||
|
||||
#define APDS9960_CONTROL_REG 0x8F
|
||||
|
||||
/* On/Off definitions */
|
||||
#define APDS9960_MODE_OFF 0
|
||||
#define APDS9960_MODE_ON 1
|
||||
|
||||
/* Acceptable parameters for apds9960_setmode */
|
||||
#define APDS9960_POWER 0
|
||||
#define APDS9960_MBIENT_LIGHT 1
|
||||
#define APDS9960_PROXIMITY 2
|
||||
#define APDS9960_WAIT 3
|
||||
#define APDS9960_AMBIENT_LIGHT_INT 4
|
||||
#define APDS9960_PROXIMITY_INT 5
|
||||
#define APDS9960_GESTURE 6
|
||||
#define APDS9960_ALL 7
|
||||
|
||||
/* ALS Gain (AGAIN) values */
|
||||
#define APDS9960_AGAIN_1X 0
|
||||
#define APDS9960_AGAIN_4X 1
|
||||
#define APDS9960_AGAIN_16X 2
|
||||
#define APDS9960_AGAIN_64X 3
|
||||
|
||||
/* LED Drive values */
|
||||
#define APDS9960_LED_DRIVE_100MA 0
|
||||
#define APDS9960_LED_DRIVE_50MA 1
|
||||
#define APDS9960_LED_DRIVE_25MA 2
|
||||
#define APDS9960_LED_DRIVE_12_5MA 3
|
||||
|
||||
/* Proximity Gain (PGAIN) values */
|
||||
#define APDS9960_PGAIN_1X 0
|
||||
#define APDS9960_PGAIN_2X 1
|
||||
#define APDS9960_PGAIN_4X 2
|
||||
#define APDS9960_PGAIN_8X 3
|
||||
|
||||
/* Gesture Gain (GGAIN) values */
|
||||
#define APDS9960_GGAIN_1X 0
|
||||
#define APDS9960_GGAIN_2X 1
|
||||
#define APDS9960_GGAIN_4X 2
|
||||
#define APDS9960_GGAIN_8X 3
|
||||
|
||||
/* LED Boost values */
|
||||
#define APDS9960_GLED_BOOST_100 0
|
||||
#define APDS9960_GLED_BOOST_150 1
|
||||
#define APDS9960_GLED_BOOST_200 2
|
||||
#define APDS9960_GLED_BOOST_300 3
|
||||
|
||||
/* Gesture wait time values */
|
||||
#define APDS9960_GWTIME_0MS 0
|
||||
#define APDS9960_GWTIME_2_8MS 1
|
||||
#define APDS9960_GWTIME_5_6MS 2
|
||||
#define APDS9960_GWTIME_8_4MS 3
|
||||
#define APDS9960_GWTIME_14_0MS 4
|
||||
#define APDS9960_GWTIME_22_4MS 5
|
||||
#define APDS9960_GWTIME_30_8MS 6
|
||||
#define APDS9960_GWTIME_39_2MS 7
|
||||
|
||||
/* Default values */
|
||||
#define APDS9960_DEFAULT_ATIME 219
|
||||
#define APDS9960_DEFAULT_WTIME 246
|
||||
#define APDS9960_DEFAULT_CONFIG1 0x60
|
||||
#define APDS9960_DEFAULT_AGAIN APDS9960_AGAIN_4X
|
||||
#define APDS9960_DEFAULT_AILT 0xFFFF
|
||||
#define APDS9960_DEFAULT_AIHT 0
|
||||
#define APDS9960_DEFAULT_PERS 0x11
|
||||
#define APDS9960_DEFAULT_CONFIG2 0x01
|
||||
|
||||
#define APDS9960_DEFAULT_PROX_PPULSE 0x87
|
||||
#define APDS9960_DEFAULT_GESTURE_PPULSE 0x89
|
||||
#define APDS9960_DEFAULT_POFFSET_UR 0
|
||||
#define APDS9960_DEFAULT_POFFSET_DL 0
|
||||
|
||||
#define APDS9960_DEFAULT_LDRIVE APDS9960_LED_DRIVE_100MA
|
||||
#define APDS9960_DEFAULT_PGAIN APDS9960_PGAIN_4X
|
||||
|
||||
#define APDS9960_DEFAULT_PILT 0
|
||||
#define APDS9960_DEFAULT_PIHT 50
|
||||
|
||||
#define APDS9960_DEFAULT_CONFIG2 0x01
|
||||
#define APDS9960_DEFAULT_CONFIG3 0
|
||||
#define APDS9960_DEFAULT_GPENTH 40
|
||||
#define APDS9960_DEFAULT_GEXTH 30
|
||||
#define APDS9960_DEFAULT_GCONF1 0x40
|
||||
#define APDS9960_DEFAULT_GGAIN APDS9960_GGAIN_4X
|
||||
#define APDS9960_DEFAULT_GLDRIVE APDS9960_LED_DRIVE_100MA
|
||||
|
||||
#define APDS9960_DEFAULT_GWTIME APDS9960_GWTIME_2_8MS
|
||||
#define APDS9960_DEFAULT_GOFFSET 0
|
||||
#define APDS9960_DEFAULT_GPULSE 0xC9
|
||||
#define APDS9960_DEFAULT_GCONF3 0
|
||||
#define APDS9960_DEFAULT_GIEN 0
|
||||
|
||||
/* proxy Registers */
|
||||
#define APDS9960_ENABLE_PEN BIT(0)
|
||||
#define APDS9960_ENABLE_PIEN BIT(5)
|
||||
|
||||
#define APDS9960_PILT_REG 0x89
|
||||
#define APDS9960_PIHT_REG 0x8B
|
||||
|
||||
#define APDS9960_PERS_REG 0x8C
|
||||
#define APDS9960_PERS_PPERS (BIT(4) | BIT(5) | BIT(6) | BIT(7))
|
||||
|
||||
#define APDS9960_PPULSE_REG 0x8E
|
||||
#define APDS9960_PPULSE_PLEN (BIT(7) | BIT(6))
|
||||
#define APDS9960_PPULSE_PULSE (BIT(5) | BIT(4) | BIT(3) |\
|
||||
BIT(2) | BIT(1) | BIT(0))
|
||||
|
||||
#define APDS9960_CONTROL_PGAIN (BIT(3) | BIT(2))
|
||||
|
||||
#define APDS9960_CONFIG2_PSIEN BIT(7)
|
||||
#define APDS9960_CONFIG2_LEDBOOST (BIT(5) | BIT(4))
|
||||
|
||||
#define APDS9960_STATUS_PGSAT BIT(6)
|
||||
#define APDS9960_STATUS_PINT BIT(5)
|
||||
#define APDS9960_STATUS_PVALID BIT(1)
|
||||
|
||||
#define APDS9960_PDATA_REG 0x9C
|
||||
#define APDS9960_POFFSET_UR_REG 0x9D
|
||||
#define APDS9960_POFFSET_DL_REG 0x9E
|
||||
|
||||
#define APDS9960_CONFIG3_REG 0x9F
|
||||
#define APDS9960_CONFIG3_PCMP BIT(5)
|
||||
#define APDS9960_CONFIG3_PMSK_U BIT(3)
|
||||
#define APDS9960_CONFIG3_PMSK_D BIT(2)
|
||||
#define APDS9960_CONFIG3_PMSK_L BIT(4)
|
||||
#define APDS9960_CONFIG3_PMSK_R BIT(0)
|
||||
|
||||
#define APDS9960_PICLEAR_REG 0xE5
|
||||
#define APDS9960_PROXY_ON 0x05
|
||||
|
||||
/* Gesture Registers */
|
||||
#define APDS9960_ENABLE_GEN BIT(6)
|
||||
|
||||
#define APDS9960_GCONFIG4_REG 0xAB
|
||||
#define APDS9960_GCONFIG4_GIEN BIT(1)
|
||||
|
||||
#define APDS9960_GPENTH_REG 0xA0
|
||||
#define APDS9960_GEXTH_REG 0xA1
|
||||
|
||||
#define APDS9960_GCONFIG1_REG 0xA2
|
||||
|
||||
#define APDS9960_GCONFIG1_GFIFOTH (BIT(7) | BIT(6))
|
||||
#define APDS9960_GCONFIG1_GEXMSK (BIT(5) | BIT(4) | BIT(3) | BIT(2))
|
||||
#define APDS9960_GCONFIG1_GEXPERS (BIT(1) | BIT(0))
|
||||
|
||||
#define APDS9960_GCONFIG2_REG 0xA3
|
||||
#define APDS9960_GCONFIG2_GGAIN (BIT(6) | BIT(5))
|
||||
#define APDS9960_GCONFIG2_GLDRIVE (BIT(4) | BIT(3))
|
||||
#define APDS9960_GCONFIG2_WTIME (BIT(2) | BIT(1) | BIT(0))
|
||||
|
||||
#define APDS9960_STATUS_PGSAT BIT(6)
|
||||
#define APDS9960_CONFIG2_LEDBOOST (BIT(5) | BIT(4))
|
||||
|
||||
#define APDS9960_GOFFSET_U_REG 0xA4
|
||||
#define APDS9960_GOFFSET_D_REG 0xA5
|
||||
#define APDS9960_GOFFSET_L_REG 0xA7
|
||||
#define APDS9960_GOFFSET_R_REG 0xA9
|
||||
|
||||
#define APDS9960_GPULSE_REG 0xA6
|
||||
#define APDS9960_GPULSE_GPULSE (BIT(5) | BIT(4) | BIT(3) |\
|
||||
BIT(2) | BIT(1) | BIT(0))
|
||||
#define APDS9960_GPULSE_GPLEN (BIT(7) | BIT(6))
|
||||
|
||||
#define APDS9960_GCONFIG3_REG 0xAA
|
||||
|
||||
#define APDS9960_GCONFIG3_GDIMS (BIT(1) | BIT(0))
|
||||
|
||||
#define APDS9960_GCONFIG4_GIEN BIT(1)
|
||||
#define APDS9960_GCONFIG4_GMODE BIT(0)
|
||||
|
||||
#define APDS9960_GFLVL_REG 0xAE
|
||||
|
||||
#define APDS9960_GSTATUS_REG 0xAF
|
||||
#define APDS9960_GSTATUS_GFOV BIT(1)
|
||||
#define APDS9960_GSTATUS_GVALID BIT(0)
|
||||
|
||||
#define APDS9960_GFIFO_U_REG 0xFC
|
||||
#define APDS9960_GFIFO_D_REG 0xFD
|
||||
#define APDS9960_GFIFO_L_REG 0xFE
|
||||
#define APDS9960_GFIFO_R_REG 0xFF
|
||||
|
||||
#define APDS9960_CONFIG1_LOWPOW 0x8D
|
||||
|
||||
struct apds9960_data {
|
||||
struct device *i2c;
|
||||
s16_t sample_c;
|
||||
s16_t sample_r;
|
||||
s16_t sample_g;
|
||||
s16_t sample_b;
|
||||
s8_t pdata;
|
||||
s8_t gdata;
|
||||
};
|
||||
|
||||
#define SYS_LOG_DOMAIN "APDS9960"
|
||||
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_SENSOR_LEVEL
|
||||
#include <logging/sys_log.h>
|
||||
|
||||
#endif /* _SENSOR_APDS9960_H_*/
|
Loading…
Add table
Add a link
Reference in a new issue