summaryrefslogtreecommitdiff
path: root/driver/als_tcs3400.h
diff options
context:
space:
mode:
authorNick Vaccaro <nvaccaro@google.com>2019-05-07 15:23:03 -0700
committerCommit Bot <commit-bot@chromium.org>2019-08-20 16:31:46 +0000
commit72c142d8a751089baac1f042d6a199e49daa32d0 (patch)
treee5ebf12bb8e3edb4e1b3ecb8352888028e8d9ca8 /driver/als_tcs3400.h
parent6d8a5d3f207af7481e2aa114d306f8448d21b74f (diff)
downloadchrome-ec-72c142d8a751089baac1f042d6a199e49daa32d0.tar.gz
driver/tcs3400: add auto-compensation for saturation
Making settings more sensitive makes the SNR better, so this algorithm strives to keep the output level as close to 90% saturation as possible. Adds calibration mode and lux calculation. Removes unused last_value field from the tcs3400_rgb_drv_data_t structure, we use raw_xyz field in motion_sensor_t struct instead. BUG=b:124512628 BRANCH=master TEST=Flash and boot flapjack, verify that ALS and RGB sensors are still generating data. I used alslog patch and enabled ALS logging in EC console via "alslog 1023". Verify that under a constant light source, the adjustment mechanism correctly drives the ALS values such that they land in the sweet spot between 90 to <100% of saturation. Cq-Depend: chromium:1711958,chromium:1702543 Change-Id: Ibf260a990fe285cb54ee94c1ebe8aa85ea10affc Signed-off-by: Nick Vaccaro <nvaccaro@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1633269 Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
Diffstat (limited to 'driver/als_tcs3400.h')
-rw-r--r--driver/als_tcs3400.h81
1 files changed, 66 insertions, 15 deletions
diff --git a/driver/als_tcs3400.h b/driver/als_tcs3400.h
index bad2ec5857..eace416c94 100644
--- a/driver/als_tcs3400.h
+++ b/driver/als_tcs3400.h
@@ -68,7 +68,7 @@ enum tcs3400_mode {
#define TCS_I2C_CONTROL_MASK 0x03
#define TCS_I2C_STATUS_RGBC_VALID BIT(0)
#define TCS_I2C_STATUS_ALS_IRQ BIT(4)
-#define TCS_I2C_STATUS_ALS_VALID BIT(7)
+#define TCS_I2C_STATUS_ALS_SATURATED BIT(7)
#define TCS_I2C_AUX_ASL_INT_ENABLE BIT(5)
@@ -79,7 +79,7 @@ enum tcs3400_mode {
/* Min and Max sampling frequency in mHz */
#define TCS3400_LIGHT_MIN_FREQ 149
-#define TCS3400_LIGHT_MAX_FREQ 10000
+#define TCS3400_LIGHT_MAX_FREQ 1000
#if (CONFIG_EC_MAX_SENSOR_FREQ_MILLIHZ <= TCS3400_LIGHT_MAX_FREQ)
#error "EC too slow for light sensor"
#endif
@@ -91,27 +91,78 @@ enum tcs3400_mode {
/* NOTE: The higher the ATIME value in reg, the shorter the accumulation time */
#define TCS_MIN_ATIME 0x00 /* 712 ms */
#define TCS_MAX_ATIME 0x70 /* 400 ms */
+#define TCS_ATIME_GRANULARITY 256 /* 256 atime settings */
+#define TCS_SATURATION_LEVEL 0xffff /* for 0 < atime < 0x70 */
#define TCS_DEFAULT_ATIME TCS_MIN_ATIME /* 712 ms */
+#define TCS_CALIBRATION_ATIME TCS_MIN_ATIME
+#define TCS_GAIN_UPSHIFT_ATIME TCS_MAX_ATIME
#define TCS_MIN_AGAIN 0x00 /* 1x gain */
#define TCS_MAX_AGAIN 0x03 /* 64x gain */
-#define TCS_DEFAULT_AGAIN 0x02 /* 16x gain */
+#define TCS_CALIBRATION_AGAIN 0x02 /* 16x gain */
+#define TCS_DEFAULT_AGAIN TCS_CALIBRATION_AGAIN
-/* tcs3400 rgb als driver data */
-struct tcs3400_rgb_drv_data_t {
+#define TCS_ATIME_DEC_STEP 5
+#define TCS_ATIME_INC_STEP TCS_GAIN_UPSHIFT_ATIME
+
+/*
+ * Factor to multiply light value by to determine if an increase in gain
+ * would cause the next value to saturate.
+ *
+ * On the TCS3400, gain increases 4x each time again register setting is
+ * incremented. However, I see cases where values that are 24% of saturation
+ * go into saturation after increasing gain, causing a back-and-forth cycle to
+ * occur :
+ *
+ * [134.654994 tcs3400_adjust_sensor_for_saturation value=65535 100% Gain=2 ]
+ * [135.655064 tcs3400_adjust_sensor_for_saturation value=15750 24% Gain=1 ]
+ * [136.655107 tcs3400_adjust_sensor_for_saturation value=65535 100% Gain=2 ]
+ *
+ * To avoid this, we require value to be <= 20% of saturation level
+ * (TCS_GAIN_SAT_LEVEL) before allowing gain to be increased.
+ */
+#define TCS_GAIN_ADJUST_FACTOR 5
+#define TCS_GAIN_SAT_LEVEL (TCS_SATURATION_LEVEL / TCS_GAIN_ADJUST_FACTOR)
+#define TCS_UPSHIFT_FACTOR 3
+#define TCS_GAIN_SAT_UPSHIFT_LEVEL (TCS_SATURATION_LEVEL / TCS_UPSHIFT_FACTOR)
+
+/*
+ * Percentage of saturation level that the auto-adjusting anti-saturation
+ * method will drive towards.
+ */
+#define TSC_SATURATION_LOW_BAND_PERCENT 90
+#define TSC_SATURATION_LOW_BAND_LEVEL (TCS_SATURATION_LEVEL * \
+ TSC_SATURATION_LOW_BAND_PERCENT / 100)
+
+enum crbg_index {
+ CLEAR_CRGB_IDX = 0,
+ RED_CRGB_IDX,
+ GREEN_CRGB_IDX,
+ BLUE_CRGB_IDX,
+ CRGB_COUNT,
+};
+
+/* saturation auto-adjustment */
+struct tcs_saturation_t {
/*
- * device_scale and device_uscale are used to adjust raw rgb channel
- * values prior to applying any channel-specific scaling required.
- * raw_value += rgb_cal.offset;
- * adjusted_value = raw_value * device_scale +
- * raw_value * device_uscale / 10000;
+ * Gain Scaling; must be value between 0 and 3
+ * 0 - 1x scaling
+ * 1 - 4x scaling
+ * 2 - 16x scaling
+ * 3 - 64x scaling
*/
- uint16_t device_scale;
- uint16_t device_uscale;
+ uint8_t again;
+
+ /* Acquisition Time, controlled by the ATIME register */
+ uint8_t atime; /* ATIME register setting */
+};
+
+/* tcs3400 rgb als driver data */
+struct tcs3400_rgb_drv_data_t {
+ uint8_t calibration_mode;/* 0 = normal run mode, 1 = calibration mode */
- int rate; /* holds current sensor rate */
- int last_value[3]; /* holds last RGB values */
- struct rgb_calibration_t rgb_cal[3]; /* calibration data */
+ struct rgb_calibration_t rgb_cal[RGB_CHANNEL_COUNT];
+ struct tcs_saturation_t saturation; /* saturation adjustment */
};
extern const struct accelgyro_drv tcs3400_drv;