diff options
Diffstat (limited to 'driver/als_bh1730.c')
-rw-r--r-- | driver/als_bh1730.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/driver/als_bh1730.c b/driver/als_bh1730.c new file mode 100644 index 0000000000..57db6fdba7 --- /dev/null +++ b/driver/als_bh1730.c @@ -0,0 +1,175 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Rohm BH1730 Ambient light sensor driver + */ + +#include "accelgyro.h" +#include "config.h" +#include "console.h" +#include "driver/als_bh1730.h" +#include "i2c.h" + +#define CPRINTS(format, args...) cprints(CC_MOTION_SENSE, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_MOTION_SENSE, format, ## args) + +/** + * Convert BH1730 data0, data1 to lux + */ +static int bh1730_convert_to_lux(uint32_t data0_1) +{ + int lux; + uint16_t data0 = 0x0000ffff & data0_1; + uint16_t data1 = data0_1 >> 16; + uint32_t d0_1k = data0 * 1000; + uint32_t d1_1k = data1 * 1000; + uint32_t d_temp = d1_1k / d0_1k; + uint32_t d_lux; + + if (data0 == 0) + return 0; + + if(d_temp < BH1730_LUXTH1_1K) { + d0_1k = BH1730_LUXTH1_D0_1K * data0; + d1_1k = BH1730_LUXTH1_D1_1K * data1; + } else if(d_temp < BH1730_LUXTH2_1K) { + d0_1k = BH1730_LUXTH2_D0_1K * data0; + d1_1k = BH1730_LUXTH2_D1_1K * data1; + } else if(d_temp < BH1730_LUXTH3_1K) { + d0_1k = BH1730_LUXTH3_D0_1K * data0; + d1_1k = BH1730_LUXTH3_D1_1K * data1; + } else if(d_temp < BH1730_LUXTH4_1K) { + d0_1k = BH1730_LUXTH4_D0_1K * data0; + d1_1k = BH1730_LUXTH4_D1_1K * data1; + } else + return 0; + + d_lux = (d0_1k - d1_1k) / BH1730_GAIN_DIV; + d_lux *= 100; + lux = d_lux / ITIME_MS_X_1K; + + return lux; +} + +/** + * Read BH1730 light sensor data. + */ +static int bh1730_read_lux(const struct motion_sensor_t *s, vector_3_t v) +{ + struct bh1730_drv_data_t *drv_data = BH1730_GET_DATA(s); + int ret; + int data0_1; + + /* read data0 and data1 from sensor */ + ret = i2c_read32(s->port, s->addr, BH1730_DATA0LOW, &data0_1); + if (ret != EC_SUCCESS) { + CPRINTF("bh1730_read_lux - fail %d\n", ret); + return ret; + } + + /* convert sensor data0 and data1 to lux */ + v[0] = bh1730_convert_to_lux(data0_1); + v[1] = 0; + v[2] = 0; + + /* + * Return an error when nothing change to prevent filling the + * fifo with useless data. + */ + if (v[0] == drv_data->last_value) + return EC_ERROR_UNCHANGED; + else + return EC_SUCCESS; +} + +static int bh1730_set_range(const struct motion_sensor_t *s, int range, + int rnd) +{ + return EC_SUCCESS; +} + +static int bh1730_get_range(const struct motion_sensor_t *s) +{ + return 1; +} + +static int bh1730_set_data_rate(const struct motion_sensor_t *s, + int rate, int roundup) +{ + struct bh1730_drv_data_t *drv_data = BH1730_GET_DATA(s); + + /* now only one rate supported */ + drv_data->rate = BH1730_10000_MHZ; + + return EC_SUCCESS; +} + +static int bh1730_get_data_rate(const struct motion_sensor_t *s) +{ + struct bh1730_drv_data_t *drv_data = BH1730_GET_DATA(s); + + return drv_data->rate; +} + +static int bh1730_set_offset(const struct motion_sensor_t *s, + const int16_t *offset, + int16_t temp) +{ + return EC_SUCCESS; +} + +static int bh1730_get_offset(const struct motion_sensor_t *s, + int16_t *offset, + int16_t *temp) +{ + *offset = 0; + + return EC_SUCCESS; +} + +/** + * Initialise BH1730 Ambient light sensor. + */ +static int bh1730_init(const struct motion_sensor_t *s) +{ + int ret; + + /* power and measurement bit high */ + ret = i2c_write8(s->port, s->addr, + BH1730_CONTROL, + BH1730_CONTROL_POWER_ENABLE|BH1730_CONTROL_ADC_EN_ENABLE); + + if (ret != EC_SUCCESS) { + CPRINTF("bh1730_init_sensor - enable fail %d\n", ret); + return ret; + } + + /* set timing */ + ret = i2c_write8(s->port, s->addr, BH1730_TIMING, BH1730_CONF_ITIME); + if (ret != EC_SUCCESS) { + CPRINTF("bh1730_init_sensor - time fail %d\n", ret); + return ret; + } + /* set ADC gain */ + ret = i2c_write8(s->port, s->addr, BH1730_GAIN, BH1730_CONF_GAIN); + + if (ret != EC_SUCCESS) { + CPRINTF("bh1730_init_sensor - gain fail %d\n", ret); + return ret; + } + + return sensor_init_done(s); +} + +const struct accelgyro_drv bh1730_drv = { + .init = bh1730_init, + .read = bh1730_read_lux, + .set_range = bh1730_set_range, + .get_range = bh1730_get_range, + .set_offset = bh1730_set_offset, + .get_offset = bh1730_get_offset, + .set_data_rate = bh1730_set_data_rate, + .get_data_rate = bh1730_get_data_rate, +}; + |