blob: 7bf710920acc1eb04a4275c0cf8c643553fcd17a [file] [log] [blame]
Mike Frysinger71b2ef72022-09-12 18:54:361/* Copyright 2021 The ChromiumOS Authors
Wisley Chen2ef205a2021-06-25 08:37:562 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
Wisley Chen2ef205a2021-06-25 08:37:566#include "accelgyro.h"
7#include "adc_chip.h"
Devin Lueedacab2022-02-14 09:23:278#include "cbi_ssfc.h"
Jeremy Bettisc50046a2022-11-28 17:00:459#include "common.h"
Devin Luedc228b2021-07-19 03:03:0510#include "driver/accel_bma2x2.h"
Devin Lueedacab2022-02-14 09:23:2711#include "driver/accel_bma422.h"
Devin Luedc228b2021-07-19 03:03:0512#include "driver/accelgyro_lsm6dsm.h"
Wisley Chen2ef205a2021-06-25 08:37:5613#include "driver/als_tcs3400_public.h"
Keith Short9877be72022-02-11 22:46:2414#include "gpio.h"
Wisley Chen2ef205a2021-06-25 08:37:5615#include "hooks.h"
16#include "motion_sense.h"
17#include "temp_sensor.h"
Wisley Chen2ef205a2021-06-25 08:37:5618#include "temp_sensor/thermistor.h"
Jeremy Bettisc50046a2022-11-28 17:00:4519#include "thermal.h"
Wisley Chen2ef205a2021-06-25 08:37:5620
21/* ADC configuration */
22const struct adc_t adc_channels[] = {
Devin Lu6e9c1b32021-08-06 01:30:4723 [ADC_TEMP_SENSOR_1_DDR] = {
24 .name = "TEMP_DDR",
Wisley Chen2ef205a2021-06-25 08:37:5625 .input_ch = NPCX_ADC_CH0,
26 .factor_mul = ADC_MAX_VOLT,
27 .factor_div = ADC_READ_MAX + 1,
28 .shift = 0,
29 },
Devin Lu6e9c1b32021-08-06 01:30:4730 [ADC_TEMP_SENSOR_2_SOC] = {
31 .name = "TEMP_SOC",
Wisley Chen2ef205a2021-06-25 08:37:5632 .input_ch = NPCX_ADC_CH1,
33 .factor_mul = ADC_MAX_VOLT,
34 .factor_div = ADC_READ_MAX + 1,
35 .shift = 0,
36 },
37 [ADC_TEMP_SENSOR_3_CHARGER] = {
38 .name = "TEMP_CHARGER",
39 .input_ch = NPCX_ADC_CH6,
40 .factor_mul = ADC_MAX_VOLT,
41 .factor_div = ADC_READ_MAX + 1,
42 .shift = 0,
43 },
Devin Lu6e9c1b32021-08-06 01:30:4744 [ADC_TEMP_SENSOR_4_REGULATOR] = {
45 .name = "TEMP_REGULATOR",
Wisley Chen2ef205a2021-06-25 08:37:5646 .input_ch = NPCX_ADC_CH7,
47 .factor_mul = ADC_MAX_VOLT,
48 .factor_div = ADC_READ_MAX + 1,
49 .shift = 0,
50 },
51};
52BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
53
54K_MUTEX_DEFINE(g_lid_accel_mutex);
55K_MUTEX_DEFINE(g_base_accel_mutex);
Devin Luedc228b2021-07-19 03:03:0556static struct accelgyro_saved_data_t g_bma253_data;
Devin Lueedacab2022-02-14 09:23:2757static struct accelgyro_saved_data_t g_bma422_data;
Devin Lu856b4e12021-08-05 08:23:1158static struct lsm6dsm_data lsm6dsm_data = LSM6DSM_DATA;
Wisley Chen2ef205a2021-06-25 08:37:5659
Jack Rosenthal5d575a52022-06-27 20:02:1260static const mat33_fp_t lid_standard_ref = { { FLOAT_TO_FP(-1), 0, 0 },
61 { 0, FLOAT_TO_FP(1), 0 },
62 { 0, 0, FLOAT_TO_FP(-1) } };
Wisley Chen2ef205a2021-06-25 08:37:5663
Jack Rosenthal5d575a52022-06-27 20:02:1264static const mat33_fp_t base_standard_ref = { { FLOAT_TO_FP(-1), 0, 0 },
65 { 0, FLOAT_TO_FP(1), 0 },
66 { 0, 0, FLOAT_TO_FP(-1) } };
Wisley Chen2ef205a2021-06-25 08:37:5667
68/* TCS3400 private data */
69static struct als_drv_data_t g_tcs3400_data = {
70 .als_cal.scale = 1,
71 .als_cal.uscale = 0,
72 .als_cal.offset = 0,
73 .als_cal.channel_scale = {
74 .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kc from VPD */
Isaac Leeed191892021-11-09 06:34:1175 .cover_scale = ALS_CHANNEL_SCALE(0.98), /* CT */
Wisley Chen2ef205a2021-06-25 08:37:5676 },
77};
78
79/*
80 * TODO: b/184702900 need to calibrate ALS/RGB sensor. At default settings,
81 * shining phone flashlight on sensor pegs all readings at 0xFFFF.
82 */
83static struct tcs3400_rgb_drv_data_t g_tcs3400_rgb_data = {
84 .calibration.rgb_cal[X] = {
Isaac Leeed191892021-11-09 06:34:1185 .offset = 66, /* 66.47729532 */
86 .coeff[TCS_RED_COEFF_IDX] = FLOAT_TO_FP(0.00222243),
87 .coeff[TCS_GREEN_COEFF_IDX] = FLOAT_TO_FP(0.51877192),
88 .coeff[TCS_BLUE_COEFF_IDX] = FLOAT_TO_FP(-0.28664117),
89 .coeff[TCS_CLEAR_COEFF_IDX] = FLOAT_TO_FP(0.0586877),
Wisley Chen2ef205a2021-06-25 08:37:5690 .scale = {
91 .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kr */
Isaac Leeed191892021-11-09 06:34:1192 .cover_scale = ALS_CHANNEL_SCALE(0.61)
Wisley Chen2ef205a2021-06-25 08:37:5693 }
94 },
95 .calibration.rgb_cal[Y] = {
Isaac Leeed191892021-11-09 06:34:1196 .offset = 41, /* 40.95355984 */
97 .coeff[TCS_RED_COEFF_IDX] = FLOAT_TO_FP(-0.15384715),
98 .coeff[TCS_GREEN_COEFF_IDX] = FLOAT_TO_FP(0.40454969),
99 .coeff[TCS_BLUE_COEFF_IDX] = FLOAT_TO_FP(-0.237452),
100 .coeff[TCS_CLEAR_COEFF_IDX] = FLOAT_TO_FP(0.13102168),
Wisley Chen2ef205a2021-06-25 08:37:56101 .scale = {
102 .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kg */
103 .cover_scale = ALS_CHANNEL_SCALE(1.0)
104 },
105 },
106 .calibration.rgb_cal[Z] = {
Isaac Leeed191892021-11-09 06:34:11107 .offset = 5, /* 5.08596128 */
108 .coeff[TCS_RED_COEFF_IDX] = FLOAT_TO_FP(-0.79005309),
109 .coeff[TCS_GREEN_COEFF_IDX] = FLOAT_TO_FP(-0.35553576),
110 .coeff[TCS_BLUE_COEFF_IDX] = FLOAT_TO_FP(0.13997097),
111 .coeff[TCS_CLEAR_COEFF_IDX] = FLOAT_TO_FP(0.40223911),
Wisley Chen2ef205a2021-06-25 08:37:56112 .scale = {
113 .k_channel_scale = ALS_CHANNEL_SCALE(1.0), /* kb */
Isaac Leeed191892021-11-09 06:34:11114 .cover_scale = ALS_CHANNEL_SCALE(1.6)
Wisley Chen2ef205a2021-06-25 08:37:56115 }
116 },
Boris Mittelbergc8bc2742022-08-11 22:03:42117 .calibration.irt = FLOAT_TO_FP(0.41),
Wisley Chen2ef205a2021-06-25 08:37:56118 .saturation.again = TCS_DEFAULT_AGAIN,
119 .saturation.atime = TCS_DEFAULT_ATIME,
120};
121
122struct motion_sensor_t motion_sensors[] = {
123 [LID_ACCEL] = {
124 .name = "Lid Accel",
125 .active_mask = SENSOR_ACTIVE_S0_S3,
Devin Luedc228b2021-07-19 03:03:05126 .chip = MOTIONSENSE_CHIP_BMA255,
Wisley Chen2ef205a2021-06-25 08:37:56127 .type = MOTIONSENSE_TYPE_ACCEL,
128 .location = MOTIONSENSE_LOC_LID,
Devin Luedc228b2021-07-19 03:03:05129 .drv = &bma2x2_accel_drv,
Wisley Chen2ef205a2021-06-25 08:37:56130 .mutex = &g_lid_accel_mutex,
Devin Luedc228b2021-07-19 03:03:05131 .drv_data = &g_bma253_data,
Wisley Chen2ef205a2021-06-25 08:37:56132 .port = I2C_PORT_SENSOR,
Devin Luedc228b2021-07-19 03:03:05133 .i2c_spi_addr_flags = BMA2x2_I2C_ADDR1_FLAGS,
Wisley Chen2ef205a2021-06-25 08:37:56134 .rot_standard_ref = &lid_standard_ref, /* identity matrix */
135 .default_range = 2, /* g */
Devin Luedc228b2021-07-19 03:03:05136 .min_frequency = BMA255_ACCEL_MIN_FREQ,
137 .max_frequency = BMA255_ACCEL_MAX_FREQ,
Wisley Chen2ef205a2021-06-25 08:37:56138 .config = {
139 /* EC use accel for angle detection */
140 [SENSOR_CONFIG_EC_S0] = {
Devin Luedc228b2021-07-19 03:03:05141 .odr = 10000 | ROUND_UP_FLAG,
Wisley Chen2ef205a2021-06-25 08:37:56142 },
143 /* Sensor on for lid angle detection */
144 [SENSOR_CONFIG_EC_S3] = {
145 .odr = 10000 | ROUND_UP_FLAG,
146 },
147 },
148 },
149
150 [BASE_ACCEL] = {
151 .name = "Base Accel",
152 .active_mask = SENSOR_ACTIVE_S0_S3,
Devin Luedc228b2021-07-19 03:03:05153 .chip = MOTIONSENSE_CHIP_LSM6DSM,
Wisley Chen2ef205a2021-06-25 08:37:56154 .type = MOTIONSENSE_TYPE_ACCEL,
155 .location = MOTIONSENSE_LOC_BASE,
Devin Luedc228b2021-07-19 03:03:05156 .drv = &lsm6dsm_drv,
Wisley Chen2ef205a2021-06-25 08:37:56157 .mutex = &g_base_accel_mutex,
Devin Luedc228b2021-07-19 03:03:05158 .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data,
elmo_lan1d0e31a2021-07-13 11:52:48159 MOTIONSENSE_TYPE_ACCEL),
Wisley Chen2ef205a2021-06-25 08:37:56160 .port = I2C_PORT_SENSOR,
Devin Luedc228b2021-07-19 03:03:05161 .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS,
Wisley Chen2ef205a2021-06-25 08:37:56162 .rot_standard_ref = &base_standard_ref,
163 .default_range = 4, /* g */
Devin Luedc228b2021-07-19 03:03:05164 .min_frequency = LSM6DSM_ODR_MIN_VAL,
165 .max_frequency = LSM6DSM_ODR_MAX_VAL,
Wisley Chen2ef205a2021-06-25 08:37:56166 .config = {
167 [SENSOR_CONFIG_EC_S0] = {
168 .odr = 13000 | ROUND_UP_FLAG,
169 .ec_rate = 100 * MSEC,
170 },
171 [SENSOR_CONFIG_EC_S3] = {
172 .odr = 10000 | ROUND_UP_FLAG,
173 .ec_rate = 100 * MSEC,
174 },
175 },
176 },
177
178 [BASE_GYRO] = {
179 .name = "Base Gyro",
180 .active_mask = SENSOR_ACTIVE_S0_S3,
Devin Luedc228b2021-07-19 03:03:05181 .chip = MOTIONSENSE_CHIP_LSM6DSM,
Wisley Chen2ef205a2021-06-25 08:37:56182 .type = MOTIONSENSE_TYPE_GYRO,
183 .location = MOTIONSENSE_LOC_BASE,
Devin Luedc228b2021-07-19 03:03:05184 .drv = &lsm6dsm_drv,
Wisley Chen2ef205a2021-06-25 08:37:56185 .mutex = &g_base_accel_mutex,
Devin Luedc228b2021-07-19 03:03:05186 .drv_data = LSM6DSM_ST_DATA(lsm6dsm_data,
elmo_lan1d0e31a2021-07-13 11:52:48187 MOTIONSENSE_TYPE_GYRO),
Wisley Chen2ef205a2021-06-25 08:37:56188 .port = I2C_PORT_SENSOR,
Devin Luedc228b2021-07-19 03:03:05189 .i2c_spi_addr_flags = LSM6DSM_ADDR0_FLAGS,
Wisley Chen2ef205a2021-06-25 08:37:56190 .default_range = 1000 | ROUND_UP_FLAG, /* dps */
191 .rot_standard_ref = &base_standard_ref,
Devin Luedc228b2021-07-19 03:03:05192 .min_frequency = LSM6DSM_ODR_MIN_VAL,
193 .max_frequency = LSM6DSM_ODR_MAX_VAL,
Wisley Chen2ef205a2021-06-25 08:37:56194 },
195
196 [CLEAR_ALS] = {
197 .name = "Clear Light",
198 .active_mask = SENSOR_ACTIVE_S0_S3,
199 .chip = MOTIONSENSE_CHIP_TCS3400,
200 .type = MOTIONSENSE_TYPE_LIGHT,
201 .location = MOTIONSENSE_LOC_CAMERA,
202 .drv = &tcs3400_drv,
203 .drv_data = &g_tcs3400_data,
204 .port = I2C_PORT_SENSOR,
205 .i2c_spi_addr_flags = TCS3400_I2C_ADDR_FLAGS,
206 .rot_standard_ref = NULL,
207 .default_range = 0x10000, /* scale = 1x, uscale = 0 */
208 .min_frequency = TCS3400_LIGHT_MIN_FREQ,
209 .max_frequency = TCS3400_LIGHT_MAX_FREQ,
210 .config = {
211 /* Run ALS sensor in S0 */
212 [SENSOR_CONFIG_EC_S0] = {
213 .odr = 1000,
214 },
215 },
216 },
217
218 [RGB_ALS] = {
219 /*
220 * RGB channels read by CLEAR_ALS and so the i2c port and
221 * address do not need to be defined for RGB_ALS.
222 */
223 .name = "RGB Light",
224 .active_mask = SENSOR_ACTIVE_S0_S3,
225 .chip = MOTIONSENSE_CHIP_TCS3400,
226 .type = MOTIONSENSE_TYPE_LIGHT_RGB,
227 .location = MOTIONSENSE_LOC_CAMERA,
228 .drv = &tcs3400_rgb_drv,
229 .drv_data = &g_tcs3400_rgb_data,
230 .rot_standard_ref = NULL,
231 .default_range = 0x10000, /* scale = 1x, uscale = 0 */
232 },
233};
234const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors);
235
Devin Lueedacab2022-02-14 09:23:27236struct motion_sensor_t bma422_lid_accel = {
237 .name = "Lid Accel",
238 .active_mask = SENSOR_ACTIVE_S0_S3,
239 .chip = MOTIONSENSE_CHIP_BMA422,
240 .type = MOTIONSENSE_TYPE_ACCEL,
241 .location = MOTIONSENSE_LOC_LID,
242 .drv = &bma4_accel_drv,
243 .mutex = &g_lid_accel_mutex,
244 .drv_data = &g_bma422_data,
245 .port = I2C_PORT_SENSOR,
246 .i2c_spi_addr_flags = BMA4_I2C_ADDR_PRIMARY,
247 .rot_standard_ref = &lid_standard_ref,
248 .default_range = 2, /* g, enough for laptop. */
249 .min_frequency = BMA4_ACCEL_MIN_FREQ,
250 .max_frequency = BMA4_ACCEL_MAX_FREQ,
251 .config = {
252 /* EC use accel for angle detection */
253 [SENSOR_CONFIG_EC_S0] = {
254 .odr = 12500 | ROUND_UP_FLAG,
255 .ec_rate = 100 * MSEC,
256 },
257 /* Sensor on in S3 */
258 [SENSOR_CONFIG_EC_S3] = {
259 .odr = 12500 | ROUND_UP_FLAG,
260 .ec_rate = 0,
261 },
262 },
263};
264
265static void board_update_motion_sensor_config(void)
266{
267 if (get_cbi_ssfc_lid_sensor() == SSFC_SENSOR_LID_BMA422)
268 motion_sensors[LID_ACCEL] = bma422_lid_accel;
269}
270
Wisley Chen2ef205a2021-06-25 08:37:56271/* ALS instances when LPC mapping is needed. Each entry directs to a sensor. */
272const struct motion_sensor_t *motion_als_sensors[] = {
273 &motion_sensors[CLEAR_ALS],
274};
275BUILD_ASSERT(ARRAY_SIZE(motion_als_sensors) == ALS_COUNT);
276
Devin Luedc228b2021-07-19 03:03:05277static void board_sensors_init(void)
Wisley Chen2ef205a2021-06-25 08:37:56278{
Wisley Chen2ef205a2021-06-25 08:37:56279 /* Enable interrupt for the TCS3400 color light sensor */
280 gpio_enable_interrupt(GPIO_EC_ALS_RGB_INT_R_L);
281 /* Enable gpio interrupt for base accelgyro sensor */
282 gpio_enable_interrupt(GPIO_EC_IMU_INT_R_L);
Devin Lueedacab2022-02-14 09:23:27283
284 board_update_motion_sensor_config();
Wisley Chen2ef205a2021-06-25 08:37:56285}
Devin Luedc228b2021-07-19 03:03:05286DECLARE_HOOK(HOOK_INIT, board_sensors_init, HOOK_PRIO_INIT_I2C + 1);
Wisley Chen2ef205a2021-06-25 08:37:56287
288/* Temperature sensor configuration */
289const struct temp_sensor_t temp_sensors[] = {
Jack Rosenthal5d575a52022-06-27 20:02:12290 [TEMP_SENSOR_1_DDR] = { .name = "DDR",
291 .type = TEMP_SENSOR_TYPE_BOARD,
292 .read = get_temp_3v3_30k9_47k_4050b,
293 .idx = ADC_TEMP_SENSOR_1_DDR },
294 [TEMP_SENSOR_2_SOC] = { .name = "SOC",
295 .type = TEMP_SENSOR_TYPE_BOARD,
296 .read = get_temp_3v3_30k9_47k_4050b,
297 .idx = ADC_TEMP_SENSOR_2_SOC },
298 [TEMP_SENSOR_3_CHARGER] = { .name = "Charger",
299 .type = TEMP_SENSOR_TYPE_BOARD,
300 .read = get_temp_3v3_30k9_47k_4050b,
301 .idx = ADC_TEMP_SENSOR_3_CHARGER },
302 [TEMP_SENSOR_4_REGULATOR] = { .name = "Regulator",
303 .type = TEMP_SENSOR_TYPE_BOARD,
304 .read = get_temp_3v3_30k9_47k_4050b,
305 .idx = ADC_TEMP_SENSOR_4_REGULATOR },
Wisley Chen2ef205a2021-06-25 08:37:56306};
307BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT);
308
Tom Hughes04d24d12023-12-01 18:08:13309static const struct ec_thermal_config thermal_ddr = {
310 .temp_host = {
311 [EC_TEMP_THRESH_HIGH] = C_TO_K(75),
312 [EC_TEMP_THRESH_HALT] = C_TO_K(80),
313 },
314 .temp_host_release = {
315 [EC_TEMP_THRESH_HIGH] = C_TO_K(70),
316 },
317};
Devin Lu6e9c1b32021-08-06 01:30:47318
319/*
Wisley Chen2ef205a2021-06-25 08:37:56320 * Tiger Lake specifies 100 C as maximum TDP temperature. THRMTRIP# occurs at
Devin Lu6e9c1b32021-08-06 01:30:47321 * 130 C. However, sensor is located next to SOC, so we need to use the lower
322 * SOC temperature limit (85 C)
Wisley Chen2ef205a2021-06-25 08:37:56323 */
Tom Hughes04d24d12023-12-01 18:08:13324static const struct ec_thermal_config thermal_cpu = {
325 .temp_host = {
326 [EC_TEMP_THRESH_HIGH] = C_TO_K(75),
327 [EC_TEMP_THRESH_HALT] = C_TO_K(80),
328 },
329 .temp_host_release = {
330 [EC_TEMP_THRESH_HIGH] = C_TO_K(70),
331 },
332};
Wisley Chen2ef205a2021-06-25 08:37:56333
Tom Hughes04d24d12023-12-01 18:08:13334static const struct ec_thermal_config thermal_charger = {
335 .temp_host = {
336 [EC_TEMP_THRESH_HIGH] = C_TO_K(80),
337 [EC_TEMP_THRESH_HALT] = C_TO_K(85),
338 },
339 .temp_host_release = {
340 [EC_TEMP_THRESH_HIGH] = C_TO_K(75),
341 },
342};
Devin Lu6e9c1b32021-08-06 01:30:47343
Tom Hughes04d24d12023-12-01 18:08:13344static const struct ec_thermal_config thermal_regulator = {
345 .temp_host = {
346 [EC_TEMP_THRESH_HIGH] = C_TO_K(80),
347 [EC_TEMP_THRESH_HALT] = C_TO_K(85),
348 },
349 .temp_host_release = {
350 [EC_TEMP_THRESH_HIGH] = C_TO_K(75),
351 },
352};
Wisley Chen2ef205a2021-06-25 08:37:56353
354/* this should really be "const" */
355struct ec_thermal_config thermal_params[] = {
Tom Hughes04d24d12023-12-01 18:08:13356 [TEMP_SENSOR_1_DDR] = thermal_ddr,
357 [TEMP_SENSOR_2_SOC] = thermal_cpu,
358 [TEMP_SENSOR_3_CHARGER] = thermal_charger,
359 [TEMP_SENSOR_4_REGULATOR] = thermal_regulator,
Wisley Chen2ef205a2021-06-25 08:37:56360};
361BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT);