diff options
Diffstat (limited to 'zephyr/projects/nissa/craask')
-rw-r--r-- | zephyr/projects/nissa/craask/cbi.dtsi | 107 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/generated.dtsi | 288 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/keyboard.dtsi | 32 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/motionsense.dtsi | 257 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/overlay.dtsi | 360 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/power_signals.dtsi | 220 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/project.conf | 15 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/project.overlay | 14 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/pwm_leds.dtsi | 62 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/src/charger.c | 56 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/src/form_factor.c | 121 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/src/keyboard.c | 29 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/src/led.c | 56 | ||||
-rw-r--r-- | zephyr/projects/nissa/craask/src/usbc.c | 277 |
14 files changed, 1894 insertions, 0 deletions
diff --git a/zephyr/projects/nissa/craask/cbi.dtsi b/zephyr/projects/nissa/craask/cbi.dtsi new file mode 100644 index 0000000000..4c2e052f4d --- /dev/null +++ b/zephyr/projects/nissa/craask/cbi.dtsi @@ -0,0 +1,107 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + /* Craask-specific fw_config fields. */ + nissa-fw-config { + /* + * FW_CONFIG field to describe Lid sensor orientation. + */ + lid-inversion { + enum-name = "FW_LID_INVERSION"; + start = <8>; + size = <1>; + + /* + * 0: regular placement of the lid sensor + * 1: rotate 180' of xy plane. + */ + regular { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_LID_REGULAR"; + value = <0>; + default; + }; + xy_rotate_180 { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "FW_LID_XY_ROT_180"; + value = <1>; + }; + }; + /* + * FW_CONFIG field to describe Clamshell/Convertible. + */ + form_factor { + enum-name = "FORM_FACTOR"; + start = <9>; + size = <1>; + + /* + * 0: convertible, 1: clamshell + */ + convertible { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "CONVERTIBLE"; + value = <0>; + }; + clamshell { + compatible = "cros-ec,cbi-fw-config-value"; + enum-name = "CLAMSHELL"; + value = <1>; + }; + }; + }; + /* Craask-specific ssfc fields. */ + cbi-ssfc { + compatible = "named-cbi-ssfc"; + /* + * SSFC bit0-1 was defined for AUDIO CODEC. + * 0: ALC5682I_VS + * 1: NAU8825 + */ + audio_codec { + enum-name = "AUDIO_CODEC"; + size = <2>; + }; + /* + * SSFC field to identify LID motion sensor. + */ + lid-sensor { + enum-name = "LID_SENSOR"; + size = <2>; + + lid_sensor_0: lis2dw12 { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <0>; + default; + }; + lid_sensor_1: bma422 { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <1>; + }; + }; + /* + * SSFC field to identify BASE motion sensor. + */ + base-sensor { + enum-name = "BASE_SENSOR"; + size = <2>; + + base_sensor_0: lsm6dso { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <0>; + default; + }; + base_sensor_1: bmi323 { + compatible = "named-cbi-ssfc-value"; + status = "okay"; + value = <1>; + }; + }; + }; +}; diff --git a/zephyr/projects/nissa/craask/generated.dtsi b/zephyr/projects/nissa/craask/generated.dtsi new file mode 100644 index 0000000000..4303bbd4c5 --- /dev/null +++ b/zephyr/projects/nissa/craask/generated.dtsi @@ -0,0 +1,288 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + + named-adc-channels { + compatible = "named-adc-channels"; + + adc_ec_vsense_pp1050_proc: ec_vsense_pp1050_proc { + enum-name = "ADC_PP1050_PROC"; + io-channels = <&adc0 4>; + }; + adc_ec_vsense_pp3300_s5: ec_vsense_pp3300_s5 { + enum-name = "ADC_PP3300_S5"; + io-channels = <&adc0 6>; + }; + adc_temp_sensor_1: temp_sensor_1 { + enum-name = "ADC_TEMP_SENSOR_1"; + io-channels = <&adc0 0>; + }; + adc_temp_sensor_2: temp_sensor_2 { + enum-name = "ADC_TEMP_SENSOR_2"; + io-channels = <&adc0 1>; + }; + adc_temp_sensor_3: temp_sensor_3 { + enum-name = "ADC_TEMP_SENSOR_3"; + io-channels = <&adc0 10>; + }; + }; + + named-gpios { + compatible = "named-gpios"; + + gpio_acc_int_l: acc_int_l { + gpios = <&gpio5 0 GPIO_INPUT>; + }; + gpio_all_sys_pwrgd: all_sys_pwrgd { + gpios = <&gpioa 7 GPIO_INPUT>; + }; + gpio_ccd_mode_odl: ccd_mode_odl { + gpios = <&gpioe 5 GPIO_INPUT>; + enum-name = "GPIO_CCD_MODE_ODL"; + }; + gpio_cpu_c10_gate_l: cpu_c10_gate_l { + gpios = <&gpio6 7 GPIO_INPUT>; + }; + gpio_ec_battery_pres_odl: ec_battery_pres_odl { + gpios = <&gpioa 3 GPIO_INPUT>; + enum-name = "GPIO_BATT_PRES_ODL"; + }; + gpio_ec_cbi_wp: ec_cbi_wp { + gpios = <&gpio7 4 GPIO_OUTPUT>; + }; + gpio_ec_edp_bl_en_od: ec_edp_bl_en_od { + gpios = <&gpiod 3 GPIO_ODR_HIGH>; + enum-name = "GPIO_ENABLE_BACKLIGHT"; + }; + gpio_ec_entering_rw: ec_entering_rw { + gpios = <&gpio0 3 GPIO_OUTPUT>; + enum-name = "GPIO_ENTERING_RW"; + }; + gpio_ec_gsc_packet_mode: ec_gsc_packet_mode { + gpios = <&gpio7 5 GPIO_OUTPUT>; + enum-name = "GPIO_PACKET_MODE_EN"; + }; + gpio_ec_kso_02_inv: ec_kso_02_inv { + gpios = <&gpio1 7 (GPIO_OUTPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_ec_pch_wake_odl: ec_pch_wake_odl { + gpios = <&gpiob 0 GPIO_ODR_LOW>; + }; + gpio_ec_prochot_odl: ec_prochot_odl { + gpios = <&gpiof 1 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_dsw_pwrok: ec_soc_dsw_pwrok { + gpios = <&gpio6 1 GPIO_OUTPUT>; + }; + gpio_ec_soc_hdmi_hpd: ec_soc_hdmi_hpd { + gpios = <&gpioe 4 GPIO_OUTPUT>; + }; + gpio_ec_soc_int_odl: ec_soc_int_odl { + gpios = <&gpio8 0 GPIO_ODR_HIGH>; + enum-name = "GPIO_EC_INT_L"; + }; + gpio_ec_soc_pch_pwrok_od: ec_soc_pch_pwrok_od { + gpios = <&gpio7 2 GPIO_ODR_HIGH>; + }; + gpio_ec_soc_pwr_btn_odl: ec_soc_pwr_btn_odl { + gpios = <&gpioc 1 GPIO_ODR_HIGH>; + enum-name = "GPIO_PCH_PWRBTN_L"; + }; + gpio_ec_soc_rsmrst_l: ec_soc_rsmrst_l { + gpios = <&gpioa 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_rtcrst: ec_soc_rtcrst { + gpios = <&gpio7 6 GPIO_OUTPUT>; + }; + gpio_ec_soc_sys_pwrok: ec_soc_sys_pwrok { + gpios = <&gpio3 7 GPIO_OUTPUT>; + }; + gpio_ec_soc_vccst_pwrgd_od: ec_soc_vccst_pwrgd_od { + gpios = <&gpioa 4 GPIO_ODR_HIGH>; + }; + gpio_ec_wp_odl: ec_wp_odl { + gpios = <&gpioa 1 (GPIO_INPUT | GPIO_ACTIVE_LOW)>; + }; + gpio_en_kb_bl: en_kb_bl { + gpios = <&gpioa 0 GPIO_OUTPUT>; + enum-name = "GPIO_EN_KEYBOARD_BACKLIGHT"; + }; + gpio_en_pp3300_s5: en_pp3300_s5 { + gpios = <&gpiob 6 GPIO_OUTPUT>; + enum-name = "GPIO_TEMP_SENSOR_POWER"; + }; + gpio_en_pp5000_pen_x: en_pp5000_pen_x { + gpios = <&gpioe 2 GPIO_OUTPUT>; + }; + gpio_en_pp5000_s5: en_pp5000_s5 { + gpios = <&gpio4 0 GPIO_OUTPUT>; + }; + gpio_en_slp_z: en_slp_z { + gpios = <&gpioe 1 GPIO_OUTPUT>; + }; + gpio_en_usb_a0_vbus: en_usb_a0_vbus { + gpios = <&gpio9 1 GPIO_OUTPUT>; + }; + gpio_gsc_ec_pwr_btn_odl: gsc_ec_pwr_btn_odl { + gpios = <&gpio0 0 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_POWER_BUTTON_L"; + }; + gpio_hdmi_sel: hdmi_sel { + gpios = <&gpioc 6 GPIO_OUTPUT>; + }; + gpio_imu_int_l: imu_int_l { + gpios = <&gpio5 6 GPIO_INPUT>; + }; + gpio_imvp91_vrrdy_od: imvp91_vrrdy_od { + gpios = <&gpio4 3 GPIO_INPUT>; + }; + gpio_lid_open: lid_open { + gpios = <&gpiod 2 GPIO_INPUT>; + enum-name = "GPIO_LID_OPEN"; + }; + gpio_pen_detect_odl: pen_detect_odl { + gpios = <&gpio9 6 GPIO_INPUT_PULL_UP>; + }; + gpio_pg_pp1050_mem_s3_od: pg_pp1050_mem_s3_od { + gpios = <&gpiof 0 GPIO_INPUT>; + }; + gpio_pg_pp5000_s5_od: pg_pp5000_s5_od { + gpios = <&gpio4 2 GPIO_INPUT>; + }; + gpio_rsmrst_pwrgd_l: rsmrst_pwrgd_l { + gpios = <&gpio9 4 GPIO_INPUT_PULL_UP>; + }; + gpio_slp_s0_l: slp_s0_l { + gpios = <&gpio9 7 GPIO_INPUT>; + }; + gpio_slp_s3_l: slp_s3_l { + gpios = <&gpioa 5 GPIO_INPUT>; + }; + gpio_slp_s4_l: slp_s4_l { + gpios = <&gpio7 0 GPIO_INPUT>; + }; + gpio_slp_sus_l: slp_sus_l { + gpios = <&gpio6 2 GPIO_INPUT>; + }; + gpio_sub_usb_a1_ilimit_sdp: sub_usb_a1_ilimit_sdp { + gpios = <&gpiod 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB2_ILIM_SEL"; + }; + gpio_sys_rst_odl: sys_rst_odl { + gpios = <&gpioc 5 GPIO_ODR_HIGH>; + }; + gpio_tablet_mode_l: tablet_mode_l { + gpios = <&gpio9 5 GPIO_INPUT>; + enum-name = "GPIO_TABLET_MODE_L"; + }; + gpio_usb_a0_ilimit_sdp: usb_a0_ilimit_sdp { + gpios = <&gpio8 5 GPIO_OUTPUT>; + enum-name = "GPIO_USB1_ILIM_SEL"; + }; + gpio_usb_c0_int_odl: usb_c0_int_odl { + gpios = <&gpio0 1 GPIO_INPUT_PULL_UP>; + }; + gpio_vccin_aux_vid0: vccin_aux_vid0 { + gpios = <&gpio9 2 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + gpio_vccin_aux_vid1: vccin_aux_vid1 { + gpios = <&gpioe 3 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + gpio_voldn_btn_odl: voldn_btn_odl { + gpios = <&gpio9 3 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_DOWN_L"; + }; + gpio_volup_btn_odl: volup_btn_odl { + gpios = <&gpioa 2 GPIO_INPUT_PULL_UP>; + enum-name = "GPIO_VOLUME_UP_L"; + }; + }; + + named-i2c-ports { + compatible = "named-i2c-ports"; + + i2c_ec_i2c_eeprom: ec_i2c_eeprom { + i2c-port = <&i2c0_0>; + enum-names = "I2C_PORT_EEPROM"; + }; + i2c_ec_i2c_sensor: ec_i2c_sensor { + i2c-port = <&i2c1_0>; + enum-names = "I2C_PORT_SENSOR"; + }; + i2c_ec_i2c_usb_c0: ec_i2c_usb_c0 { + i2c-port = <&i2c3_0>; + enum-names = "I2C_PORT_USB_C0_TCPC"; + }; + i2c_ec_i2c_sub_usb_c1: ec_i2c_sub_usb_c1 { + i2c-port = <&i2c5_1>; + enum-names = "I2C_PORT_USB_C1_TCPC"; + }; + i2c_ec_i2c_batt: ec_i2c_batt { + i2c-port = <&i2c7_0>; + enum-names = "I2C_PORT_BATTERY"; + }; + }; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_chan0_gp45 + &adc0_chan1_gp44 + &adc0_chan4_gp41 + &adc0_chan6_gp34 + &adc0_chan10_gpe0>; + pinctrl-names = "default"; +}; + +&i2c0_0 { + status = "okay"; + pinctrl-0 = <&i2c0_0_sda_scl_gpb4_b5>; + pinctrl-names = "default"; +}; + +&i2c1_0 { + status = "okay"; + pinctrl-0 = <&i2c1_0_sda_scl_gp87_90>; + pinctrl-names = "default"; +}; + +&i2c3_0 { + status = "okay"; + pinctrl-0 = <&i2c3_0_sda_scl_gpd0_d1>; + pinctrl-names = "default"; +}; + +&i2c5_1 { + status = "okay"; + pinctrl-0 = <&i2c5_1_sda_scl_gpf4_f5>; + pinctrl-names = "default"; +}; + +&i2c7_0 { + status = "okay"; + pinctrl-0 = <&i2c7_0_sda_scl_gpb2_b3>; + pinctrl-names = "default"; +}; + +&i2c_ctrl0 { + status = "okay"; +}; + +&i2c_ctrl1 { + status = "okay"; +}; + +&i2c_ctrl3 { + status = "okay"; +}; + +&i2c_ctrl5 { + status = "okay"; +}; + +&i2c_ctrl7 { + status = "okay"; +}; diff --git a/zephyr/projects/nissa/craask/keyboard.dtsi b/zephyr/projects/nissa/craask/keyboard.dtsi new file mode 100644 index 0000000000..f9e46de1f2 --- /dev/null +++ b/zephyr/projects/nissa/craask/keyboard.dtsi @@ -0,0 +1,32 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +&cros_kb_raw { + status = "okay"; + /* No KSO2 (it's inverted and implemented by GPIO) */ + pinctrl-0 = < + &ksi0_gp31 + &ksi1_gp30 + &ksi2_gp27 + &ksi3_gp26 + &ksi4_gp25 + &ksi5_gp24 + &ksi6_gp23 + &ksi7_gp22 + &kso00_gp21 + &kso01_gp20 + &kso03_gp16 + &kso04_gp15 + &kso05_gp14 + &kso06_gp13 + &kso07_gp12 + &kso08_gp11 + &kso09_gp10 + &kso10_gp07 + &kso11_gp06 + &kso12_gp05 + >; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/craask/motionsense.dtsi b/zephyr/projects/nissa/craask/motionsense.dtsi new file mode 100644 index 0000000000..448aed6991 --- /dev/null +++ b/zephyr/projects/nissa/craask/motionsense.dtsi @@ -0,0 +1,257 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <dt-bindings/motionsense/utils.h> + + +/ { + aliases { + /* + * Interrupt bindings for sensor devices. + */ + lsm6dso-int = &base_accel; + lis2dw12-int = &lid_accel; + bmi3xx-int = &base_accel; + }; + + /* + * Declare mutexes used by sensor drivers. + * A mutex node is used to create an instance of mutex_t. + * A mutex node is referenced by a sensor node if the + * corresponding sensor driver needs to use the + * instance of the mutex. + */ + motionsense-mutex { + compatible = "cros-ec,motionsense-mutex"; + lid_mutex: lis2dw12-mutex { + }; + + lid_mutex_bma422: bma422-mutex { + }; + + base_mutex: base-mutex { + }; + + base_mutex_bmi323: bmi323-mutex { + }; + }; + + /* Rotation matrix used by drivers. */ + motionsense-rotation-ref { + compatible = "cros-ec,motionsense-rotation-ref"; + lid_rot_ref: lid-rotation-ref { + mat33 = <(-1) 0 0 + 0 1 0 + 0 0 (-1)>; + }; + + base_rot_ref: base-rotation-ref { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + + base_rot_ver1: base-rotation-ver1 { + mat33 = <(-1) 0 0 + 0 (-1) 0 + 0 0 1>; + }; + + lid_rot_bma422: lid-rotation-bma { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + + base_rot_bmi323: base-rotation-bmi323 { + mat33 = <1 0 0 + 0 (-1) 0 + 0 0 (-1)>; + }; + }; + + /* + * Driver specific data. A driver-specific data can be shared with + * different motion sensors while they are using the same driver. + * + * If a node's compatible starts with "cros-ec,accelgyro-", it is for + * a common structure defined in accelgyro.h. + * e.g) compatible = "cros-ec,accelgyro-als-drv-data" is for + * "struct als_drv_data_t" in accelgyro.h + */ + motionsense-sensor-data { + lsm6dso_accel_data: lsm6dso-accel-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lsm6dso_gyro_data: lsm6dso-gyro-drv-data { + compatible = "cros-ec,drvdata-lsm6dso"; + status = "okay"; + }; + + lis2dw12_data: lis2dw12-drv-data { + compatible = "cros-ec,drvdata-lis2dw12"; + status = "okay"; + }; + + bma422_data: bma4xx-drv-data { + compatible = "cros-ec,drvdata-bma4xx"; + status = "okay"; + }; + + bmi323_data: bmi323-drv-data { + compatible = "cros-ec,drvdata-bmi3xx"; + status = "okay"; + }; + }; + + /* + * List of motion sensors that creates motion_sensors array. + * The nodelabel "lid_accel" and "base_accel" are used to indicate + * motion sensor IDs for lid angle calculation. + * TODO(b/238139272): The first entries of the array must be + * accelerometers,then gyroscope. Fix this dependency in the DTS + * processing which makes the devicetree entries independent. + */ + motionsense-sensor { + lid_accel: lid-accel { + compatible = "cros-ec,lis2dw12"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_ref>; + default-range = <2>; + drv-data = <&lis2dw12_data>; + i2c-spi-addr-flags = "LIS2DWL_ADDR0_FLAGS"; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_accel: base-accel { + compatible = "cros-ec,lsm6dso-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + drv-data = <&lsm6dso_accel_data>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + base_gyro: base-gyro { + compatible = "cros-ec,lsm6dso-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_ref>; + default-range = <(1000 | ROUND_UP_FLAG)>; /* dps */ + drv-data = <&lsm6dso_gyro_data>; + }; + }; + + motionsense-sensor-alt { + alt_lid_accel: alt-lid-accel { + compatible = "cros-ec,bma4xx"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_LID"; + mutex = <&lid_mutex_bma422>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&lid_rot_bma422>; + default-range = <2>; + drv-data = <&bma422_data>; + i2c-spi-addr-flags = "BMA4_I2C_ADDR_PRIMARY"; + alternate-for = <&lid_accel>; + alternate-ssfc-indicator = <&lid_sensor_1>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + alt_base_accel: alt-base-accel { + compatible = "cros-ec,bmi3xx-accel"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex_bmi323>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_bmi323>; + drv-data = <&bmi323_data>; + alternate-for = <&base_accel>; + alternate-ssfc-indicator = <&base_sensor_1>; + configs { + compatible = + "cros-ec,motionsense-sensor-config"; + ec-s0 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + ec-s3 { + odr = <(10000 | ROUND_UP_FLAG)>; + }; + }; + }; + + alt_base_gyro: alt-base-gyro { + compatible = "cros-ec,bmi3xx-gyro"; + status = "okay"; + + active-mask = "SENSOR_ACTIVE_S0_S3"; + location = "MOTIONSENSE_LOC_BASE"; + mutex = <&base_mutex_bmi323>; + port = <&i2c_ec_i2c_sensor>; + rot-standard-ref = <&base_rot_bmi323>; + drv-data = <&bmi323_data>; + alternate-for = <&base_gyro>; + alternate-ssfc-indicator = <&base_sensor_1>; + }; + }; + + motionsense-sensor-info { + compatible = "cros-ec,motionsense-sensor-info"; + + /* + * list of GPIO interrupts that have to + * be enabled at initial stage + */ + sensor-irqs = <&int_imu>; + /* list of sensors in force mode */ + accel-force-mode-sensors = <&lid_accel>; + }; +}; diff --git a/zephyr/projects/nissa/craask/overlay.dtsi b/zephyr/projects/nissa/craask/overlay.dtsi new file mode 100644 index 0000000000..b3a510c111 --- /dev/null +++ b/zephyr/projects/nissa/craask/overlay.dtsi @@ -0,0 +1,360 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <cros/thermistor/thermistor.dtsi> + +/ { + aliases { + gpio-cbi-wp = &gpio_ec_cbi_wp; + gpio-wp = &gpio_ec_wp_odl; + int-wp = &int_wp_l; + gpio-kbd-kso2 = &gpio_ec_kso_02_inv; + }; + + ec-console { + compatible = "ec-console"; + disabled = "events", "lpc", "hostcmd"; + }; + + batteries { + default_battery: lgc { + compatible = "lgc,ap18c8k", "battery-smart"; + }; + cosmx { + compatible = "cosmx,ap20cbl", "battery-smart"; + }; + cosmx-2 { + compatible = "cosmx,ap20cbl-2", "battery-smart"; + }; + }; + + hibernate-wake-pins { + compatible = "cros-ec,hibernate-wake-pins"; + wakeup-irqs = < + &int_power_button + &int_lid_open + >; + }; + + gpio-interrupts { + compatible = "cros-ec,gpio-interrupts"; + + int_power_button: power_button { + irq-pin = <&gpio_gsc_ec_pwr_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "power_button_interrupt"; + }; + int_wp_l: wp_l { + irq-pin = <&gpio_ec_wp_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "switch_interrupt"; + }; + int_lid_open: lid_open { + irq-pin = <&gpio_lid_open>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "lid_interrupt"; + }; + int_tablet_mode: tablet_mode { + irq-pin = <&gpio_tablet_mode_l>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "gmr_tablet_switch_isr"; + }; + int_imu: ec_imu { + irq-pin = <&gpio_imu_int_l>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "motion_interrupt"; + }; + int_vol_down: vol_down { + irq-pin = <&gpio_voldn_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_vol_up: vol_up { + irq-pin = <&gpio_volup_btn_odl>; + flags = <GPIO_INT_EDGE_BOTH>; + handler = "button_interrupt"; + }; + int_usb_c0: usb_c0 { + irq-pin = <&gpio_usb_c0_int_odl>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + int_usb_c1: usb_c1 { + irq-pin = <&gpio_sb_1>; + flags = <GPIO_INT_EDGE_FALLING>; + handler = "usb_interrupt"; + }; + }; + + named-gpios { + gpio_sb_1: sb-1 { + gpios = <&gpio0 2 GPIO_PULL_UP>; + no-auto-init; + }; + + gpio_sb_2: sb-2 { + gpios = <&gpiod 4 GPIO_OUTPUT>; + no-auto-init; + }; + + /* + * Set I2C pins for type C sub-board to be low voltage (I2C5_1). + * We do this for all boards, since the pins are 3.3V tolerant, + * and the only 2 types of sub-boards used on nivviks both have + * type-C ports on them. + */ + gpio_sb_3: sb-3 { + gpios = <&gpiof 4 (GPIO_OPEN_DRAIN | GPIO_VOLTAGE_1P8)>; + no-auto-init; + }; + gpio_sb_4: sb-4 { + gpios = <&gpiof 5 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + no-auto-init; + }; + ec-i2c-sensor-scl { + gpios = <&gpio9 0 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + ec-i2c-sensor-sda { + gpios = <&gpio8 7 (GPIO_INPUT | GPIO_VOLTAGE_1P8)>; + }; + }; + + /* + * Aliases used for sub-board GPIOs. + */ + aliases { + /* + * Input GPIO when used with type-C port 1 + * Output when used with HDMI sub-board + */ + gpio-usb-c1-int-odl = &gpio_sb_1; + gpio-en-rails-odl = &gpio_sb_1; + /* + * Sub-board with type A USB, enable. + */ + gpio-en-usb-a1-vbus = &gpio_sb_2; + /* + * HPD pins for HDMI sub-board. + */ + gpio-hdmi-en-odl = &gpio_sb_3; + gpio-hpd-odl = &gpio_sb_4; + /* + * Enable S5 rails for LTE sub-board + */ + gpio-en-sub-s5-rails = &gpio_sb_2; + }; + + temp_memory: memory { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_1>; + }; + temp_charger: charger { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_2>; + }; + temp_ambient: ambient { + compatible = "cros-ec,temp-sensor-thermistor"; + thermistor = <&thermistor_3V3_51K1_47K_4050B>; + adc = <&adc_temp_sensor_3>; + }; + + named-temp-sensors { + compatible = "cros-ec,temp-sensors"; + memory { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_memory>; + }; + charger { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_charger>; + }; + ambient { + temp_fan_off = <35>; + temp_fan_max = <60>; + temp_host_high = <85>; + temp_host_halt = <90>; + temp_host_release_high = <80>; + power-good-pin = <&gpio_ec_soc_dsw_pwrok>; + sensor = <&temp_ambient>; + }; + }; + + usba { + compatible = "cros-ec,usba-port-enable-pins"; + /* + * sb_2 is only configured as GPIO when USB-A1 is present, + * but it's still safe to control when disabled. + * + * ILIM_SEL pins are referred to by legacy enum name, + * GPIO_USB*_ILIM_SEL. The one for port A1 is unused on + * sub-boards that don't have USB-A so is safe to control + * regardless of system configuration. + */ + enable-pins = <&gpio_en_usb_a0_vbus &gpio_sb_2>; + status = "okay"; + }; + + usbc { + #address-cells = <1>; + #size-cells = <0>; + + port0@0 { + compatible = "named-usbc-port"; + reg = <0>; + bc12 = <&bc12_port0>; + chg = <&chg_port0>; + usb-mux-chain-0 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_0>; + }; + }; + port0-muxes { + virtual_mux_0: virtual-mux-0 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + /* + * TODO(b:211693800): port1 may not be present on some + * sub-boards. + */ + port1@1 { + compatible = "named-usbc-port"; + reg = <1>; + bc12 = <&bc12_port1>; + chg = <&chg_port1>; + usb-mux-chain-1 { + compatible = "cros-ec,usb-mux-chain"; + usb-muxes = <&virtual_mux_1 &anx7483_mux_1>; + }; + usb_mux_chain_1_no_mux: usb-mux-chain-1-no-mux { + compatible = "cros-ec,usb-mux-chain"; + alternative-chain; + usb-muxes = <&virtual_mux_1>; + }; + }; + port1-muxes { + virtual_mux_1: virtual-mux-1 { + compatible = "cros-ec,usbc-mux-virtual"; + }; + }; + }; + + kblight { + compatible = "cros-ec,kblight-pwm"; + pwms = <&pwm6 6 PWM_HZ(2400) PWM_POLARITY_NORMAL>; + }; +}; + +&thermistor_3V3_51K1_47K_4050B { + status = "okay"; +}; + +&adc_ec_vsense_pp3300_s5 { + /* + * Voltage divider on input has 47k upper and 220k lower legs with + * 2714 mV full-scale reading on the ADC. Apply the largest possible + * multiplier (without overflowing int32) to get the best possible + * approximation of the actual ratio, but derate by a factor of two to + * ensure unexpectedly high values won't overflow. + */ + mul = <(791261 / 2)>; + div = <(651975 / 2)>; +}; + +/* Set bus speeds for I2C */ +&i2c0_0 { + label = "I2C_EEPROM"; + clock-frequency = <I2C_BITRATE_FAST>; + + cbi_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + size = <2048>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + }; +}; + +&i2c1_0 { + label = "I2C_SENSOR"; + clock-frequency = <I2C_BITRATE_FAST>; +}; + +&i2c3_0 { + label = "I2C_USB_C0_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + + bc12_port0: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + /* + * BC1.2 interrupt is shared with TCPC, so + * IRQ is not specified here and handled by + * usb_c0_interrupt. + */ + }; + + chg_port0: isl923x@9 { + compatible = "intersil,isl923x"; + status = "okay"; + reg = <0x9>; + }; +}; + +&i2c5_1 { + label = "I2C_SUB_C1_TCPC"; + clock-frequency = <I2C_BITRATE_FAST_PLUS>; + + bc12_port1: pi3usb9201@5f { + compatible = "pericom,pi3usb9201"; + status = "okay"; + reg = <0x5f>; + }; + + chg_port1: isl923x@9 { + compatible = "intersil,isl923x"; + status = "okay"; + reg = <0x9>; + }; + + anx7483_mux_1: anx7483-mux-1@3e { + compatible = "analogix,anx7483"; + reg = <0x3e>; + board-set = "anx7483_set_default_tuning"; + }; +}; + +&i2c7_0 { + label = "I2C_BATTERY"; + clock-frequency = <I2C_BITRATE_STANDARD>; +}; + +&pwm6 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm6_gpc0>; + pinctrl-names = "default"; +}; + +/* host interface */ +&espi0 { + status = "okay"; + pinctrl-0 = <&espi_lpc_gp46_47_51_52_53_54_55_57>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/craask/power_signals.dtsi b/zephyr/projects/nissa/craask/power_signals.dtsi new file mode 100644 index 0000000000..1d2b23069d --- /dev/null +++ b/zephyr/projects/nissa/craask/power_signals.dtsi @@ -0,0 +1,220 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + chosen { + intel-ap-pwrseq,espi = &espi0; + }; + + common-pwrseq { + compatible = "intel,ap-pwrseq"; + + sys-pwrok-delay = <10>; + all-sys-pwrgd-timeout = <20>; + }; + + pwr-en-pp5000-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP5000_S5 enable output to regulator"; + enum-name = "PWR_EN_PP5000_A"; + gpios = <&gpio4 0 0>; + output; + }; + pwr-en-pp3300-s5 { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PP3300_S5 enable output to LS"; + enum-name = "PWR_EN_PP3300_A"; + gpios = <&gpiob 6 0>; + output; + }; + pwr-pg-ec-rsmrst-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST power good from regulator"; + enum-name = "PWR_RSMRST"; + gpios = <&gpio9 4 0>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-pch-rsmrst-odl { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "RSMRST output to PCH"; + enum-name = "PWR_EC_PCH_RSMRST"; + gpios = <&gpioa 6 0>; + output; + }; + pwr-slp-s0-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S0_L input from PCH"; + enum-name = "PWR_SLP_S0"; + gpios = <&gpio9 7 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-s3-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_S3_L input from PCH"; + enum-name = "PWR_SLP_S3"; + gpios = <&gpioa 5 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-slp-sus-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SLP_SUS_L input from PCH"; + enum-name = "PWR_SLP_SUS"; + gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; + interrupt-flags = <GPIO_INT_EDGE_BOTH>; + }; + pwr-ec-soc-dsw-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "DSW_PWROK output to PCH"; + enum-name = "PWR_EC_SOC_DSW_PWROK"; + gpios = <&gpio6 1 0>; + output; + }; + pwr-vccst-pwrgd-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VCCST_PWRGD output to PCH"; + enum-name = "PWR_VCCST_PWRGD"; + gpios = <&gpioa 4 GPIO_OPEN_DRAIN>; + output; + }; + pwr-imvp9-vrrdy-od { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "VRRDY input from IMVP9"; + enum-name = "PWR_IMVP9_VRRDY"; + gpios = <&gpio4 3 0>; + }; + pwr-pch-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "PCH_PWROK output to PCH"; + enum-name = "PWR_PCH_PWROK"; + gpios = <&gpio7 2 GPIO_OPEN_DRAIN>; + output; + }; + pwr-ec-pch-sys-pwrok { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_PWROK output to PCH"; + enum-name = "PWR_EC_PCH_SYS_PWROK"; + gpios = <&gpio3 7 0>; + output; + }; + pwr-sys-rst-l { + compatible = "intel,ap-pwrseq-gpio"; + dbg-label = "SYS_RESET# output to PCH"; + enum-name = "PWR_SYS_RST"; + gpios = <&gpioc 5 (GPIO_ACTIVE_LOW|GPIO_OPEN_DRAIN)>; + output; + }; + pwr-slp-s4 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S4 virtual wire input from PCH"; + enum-name = "PWR_SLP_S4"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S4"; + vw-invert; + }; + pwr-slp-s5 { + compatible = "intel,ap-pwrseq-vw"; + dbg-label = "SLP_S5 virtual wire input from PCH"; + enum-name = "PWR_SLP_S5"; + virtual-wire = "ESPI_VWIRE_SIGNAL_SLP_S5"; + vw-invert; + }; + pwr-all-sys-pwrgd { + compatible = "intel,ap-pwrseq-external"; + dbg-label = "Combined all power good"; + enum-name = "PWR_ALL_SYS_PWRGD"; + }; + pwr-adc-pp3300 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP3300 PWROK (from ADC)"; + enum-name = "PWR_DSW_PWROK"; + trigger-high = <&cmp_pp3300_s5_high>; + trigger-low = <&cmp_pp3300_s5_low>; + }; + pwr-adc-pp1p05 { + compatible = "intel,ap-pwrseq-adc"; + dbg-label = "PP1P05 PWROK (from ADC)"; + enum-name = "PWR_PG_PP1P05"; + trigger-high = <&cmp_pp1p05_high>; + trigger-low = <&cmp_pp1p05_low>; + }; + + adc-cmp { + cmp_pp3300_s5_high: pp3300_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* + * This is 90% of nominal voltage considering voltage + * divider on ADC input. + */ + threshold-mv = <2448>; + }; + cmp_pp3300_s5_low: pp3300_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 6>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <2448>; + }; + cmp_pp1p05_high: pp1p05_high { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_GREATER"; + /* Setting at 90% of nominal voltage */ + threshold-mv = <945>; + }; + cmp_pp1p05_low: pp1p05_low { + compatible = "nuvoton,adc-cmp"; + io-channels = <&adc0 4>; + comparison = "ADC_CMP_NPCX_LESS_OR_EQUAL"; + threshold-mv = <945>; + }; + }; +}; + +/* + * Because the power signals directly reference the GPIOs, + * the correspinding named-gpios need to have no-auto-init set. + */ +&gpio_ec_soc_dsw_pwrok { + no-auto-init; +}; +&gpio_ec_soc_pch_pwrok_od { + no-auto-init; +}; +&gpio_ec_soc_rsmrst_l { + no-auto-init; +}; +&gpio_ec_soc_sys_pwrok { + no-auto-init; +}; +&gpio_ec_soc_vccst_pwrgd_od { + no-auto-init; +}; +&gpio_en_pp3300_s5 { + no-auto-init; +}; +&gpio_en_pp5000_s5 { + no-auto-init; +}; +&gpio_imvp91_vrrdy_od { + no-auto-init; +}; +&gpio_rsmrst_pwrgd_l { + no-auto-init; +}; +&gpio_slp_s0_l { + no-auto-init; +}; +&gpio_slp_s3_l { + no-auto-init; +}; +&gpio_slp_s4_l { + no-auto-init; +}; +&gpio_slp_sus_l { + no-auto-init; +}; +&gpio_sys_rst_odl { + no-auto-init; +}; diff --git a/zephyr/projects/nissa/craask/project.conf b/zephyr/projects/nissa/craask/project.conf new file mode 100644 index 0000000000..b7f31cee63 --- /dev/null +++ b/zephyr/projects/nissa/craask/project.conf @@ -0,0 +1,15 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +CONFIG_BOARD_CRAASK=y +CONFIG_PLATFORM_EC_OCPC=y + +# Sensor drivers +CONFIG_PLATFORM_EC_ACCELGYRO_LSM6DSO=y +CONFIG_PLATFORM_EC_ACCEL_BMA4XX=y +CONFIG_PLATFORM_EC_ACCELGYRO_BMI_COMM_I2C=y +CONFIG_PLATFORM_EC_ACCELGYRO_BMI3XX=y +CONFIG_PLATFORM_EC_DYNAMIC_MOTION_SENSOR_COUNT=y + +CONFIG_PLATFORM_EC_BUTTONS_RUNTIME_CONFIG=y diff --git a/zephyr/projects/nissa/craask/project.overlay b/zephyr/projects/nissa/craask/project.overlay new file mode 100644 index 0000000000..9ca681d979 --- /dev/null +++ b/zephyr/projects/nissa/craask/project.overlay @@ -0,0 +1,14 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "../cbi.dtsi" + +#include "cbi.dtsi" +#include "generated.dtsi" +#include "keyboard.dtsi" +#include "motionsense.dtsi" +#include "overlay.dtsi" +#include "power_signals.dtsi" +#include "pwm_leds.dtsi" diff --git a/zephyr/projects/nissa/craask/pwm_leds.dtsi b/zephyr/projects/nissa/craask/pwm_leds.dtsi new file mode 100644 index 0000000000..e55aa1c9ef --- /dev/null +++ b/zephyr/projects/nissa/craask/pwm_leds.dtsi @@ -0,0 +1,62 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/ { + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm2 2 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm0 0 PWM_HZ(324) PWM_POLARITY_INVERTED>, + <&pwm1 1 PWM_HZ(324) PWM_POLARITY_INVERTED>; + }; + }; + + cros-pwmleds { + compatible = "cros-ec,pwm-leds"; + + leds = <&pwm_led0>; + + /*<red green blue>*/ + color-map-red = <100 0 0>; + color-map-green = < 0 100 0>; + color-map-blue = < 0 0 100>; + color-map-yellow = < 0 50 50>; + color-map-white = <100 100 100>; + color-map-amber = < 90 10 0>; + + brightness-range = <100 100 100 0 0 0>; + + #address-cells = <1>; + #size-cells = <0>; + + pwm_led_0@0 { + reg = <0>; + ec-led-name = "EC_LED_ID_BATTERY_LED"; + }; + }; +}; + +/* Enable LEDs to work while CPU suspended */ + +&pwm0 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm0_gpc3>; + pinctrl-names = "default"; +}; + +&pwm1 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm1_gpc2>; + pinctrl-names = "default"; +}; + +&pwm2 { + status = "okay"; + clock-bus = "NPCX_CLOCK_BUS_LFCLK"; + pinctrl-0 = <&pwm2_gpc4>; + pinctrl-names = "default"; +}; diff --git a/zephyr/projects/nissa/craask/src/charger.c b/zephyr/projects/nissa/craask/src/charger.c new file mode 100644 index 0000000000..d4723e4a0a --- /dev/null +++ b/zephyr/projects/nissa/craask/src/charger.c @@ -0,0 +1,56 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "battery.h" +#include "charger.h" +#include "charger/isl923x_public.h" +#include "console.h" +#include "extpower.h" +#include "usb_pd.h" +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +int extpower_is_present(void) +{ + int port; + int rv; + bool acok; + + for (port = 0; port < board_get_usb_pd_port_count(); port++) { + rv = raa489000_is_acok(port, &acok); + if ((rv == EC_SUCCESS) && acok) + return 1; + } + + return 0; +} + +/* + * Craask does not have a GPIO indicating whether extpower is present, + * so detect using the charger(s). + */ +__override void board_check_extpower(void) +{ + static int last_extpower_present; + int extpower_present = extpower_is_present(); + + if (last_extpower_present ^ extpower_present) + extpower_handle_update(extpower_present); + + last_extpower_present = extpower_present; +} + +__override void board_hibernate(void) +{ + /* Shut down the chargers */ + if (board_get_usb_pd_port_count() == 2) + raa489000_hibernate(CHARGER_SECONDARY, true); + raa489000_hibernate(CHARGER_PRIMARY, true); + LOG_INF("Charger(s) hibernated"); + cflush(); +} diff --git a/zephyr/projects/nissa/craask/src/form_factor.c b/zephyr/projects/nissa/craask/src/form_factor.c new file mode 100644 index 0000000000..59869eaa2f --- /dev/null +++ b/zephyr/projects/nissa/craask/src/form_factor.c @@ -0,0 +1,121 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/devicetree.h> +#include <zephyr/logging/log.h> + +#include "accelgyro.h" +#include "button.h" +#include "cros_board_info.h" +#include "cros_cbi.h" +#include "driver/accelgyro_bmi323.h" +#include "driver/accelgyro_lsm6dso.h" +#include "gpio/gpio_int.h" +#include "hooks.h" +#include "motionsense_sensors.h" +#include "motion_sense.h" +#include "tablet_mode.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +/* + * Mainboard orientation support. + */ + +#define LIS_ALT_MAT SENSOR_ROT_STD_REF_NAME(DT_NODELABEL(lid_rot_bma422)) +#define BMA_ALT_MAT SENSOR_ROT_STD_REF_NAME(DT_NODELABEL(lid_rot_ref)) +#define ALT_MAT SENSOR_ROT_STD_REF_NAME(DT_NODELABEL(base_rot_ver1)) +#define LID_SENSOR SENSOR_ID(DT_NODELABEL(lid_accel)) +#define BASE_SENSOR SENSOR_ID(DT_NODELABEL(base_accel)) +#define BASE_GYRO SENSOR_ID(DT_NODELABEL(base_gyro)) +#define ALT_LID_S SENSOR_ID(DT_NODELABEL(alt_lid_accel)) + +static bool use_alt_sensor; + +void motion_interrupt(enum gpio_signal signal) +{ + if (use_alt_sensor) + bmi3xx_interrupt(signal); + else + lsm6dso_interrupt(signal); +} + +static void form_factor_init(void) +{ + int ret; + uint32_t val; + enum nissa_sub_board_type sb = nissa_get_sb_type(); + + ret = cbi_get_board_version(&val); + if (ret != EC_SUCCESS) { + LOG_ERR("Error retrieving CBI BOARD_VER."); + return; + } + /* + * The volume up/down button are exchanged on ver3 USB + * sub board. + * + * LTE: + * volup -> gpioa2, voldn -> gpio93 + * USB: + * volup -> gpio93, voldn -> gpioa2 + */ + if (val == 3 && sb == NISSA_SB_C_A) { + LOG_INF("Volume up/down btn exchanged on ver3 USB sku"); + buttons[BUTTON_VOLUME_UP].gpio = GPIO_VOLUME_DOWN_L; + buttons[BUTTON_VOLUME_DOWN].gpio = GPIO_VOLUME_UP_L; + } + + /* + * If the board version is 1 + * use ver1 rotation matrix. + */ + if (val == 1) { + LOG_INF("Switching to ver1 base"); + motion_sensors[BASE_SENSOR].rot_standard_ref = &ALT_MAT; + motion_sensors[BASE_GYRO].rot_standard_ref = &ALT_MAT; + } + + /* + * If the firmware config indicates + * an craaskbowl form factor, use the alternative + * rotation matrix. + */ + ret = cros_cbi_get_fw_config(FW_LID_INVERSION, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", + FW_LID_INVERSION); + return; + } + if (val == FW_LID_XY_ROT_180) { + LOG_INF("Lid sensor placement rotate 180 on xy plane"); + motion_sensors[LID_SENSOR].rot_standard_ref = &LIS_ALT_MAT; + motion_sensors_alt[ALT_LID_S].rot_standard_ref = &BMA_ALT_MAT; + } + + /* check which base sensor is used for motion_interrupt */ + use_alt_sensor = cros_cbi_ssfc_check_match( + CBI_SSFC_VALUE_ID(DT_NODELABEL(base_sensor_1))); + + motion_sensors_check_ssfc(); + + /* Check if it's clamshell or convertible */ + ret = cros_cbi_get_fw_config(FORM_FACTOR, &val); + if (ret != 0) { + LOG_ERR("Error retrieving CBI FW_CONFIG field %d", FORM_FACTOR); + return; + } + if (val == CLAMSHELL) { + LOG_INF("Clamshell: disable motionsense function."); + motion_sensor_count = 0; + gmr_tablet_switch_disable(); + gpio_disable_dt_interrupt(GPIO_INT_FROM_NODELABEL(int_imu)); + gpio_pin_configure_dt(GPIO_DT_FROM_NODELABEL(gpio_imu_int_l), + GPIO_DISCONNECTED); + } +} +DECLARE_HOOK(HOOK_INIT, form_factor_init, HOOK_PRIO_POST_I2C); diff --git a/zephyr/projects/nissa/craask/src/keyboard.c b/zephyr/projects/nissa/craask/src/keyboard.c new file mode 100644 index 0000000000..65229eb43f --- /dev/null +++ b/zephyr/projects/nissa/craask/src/keyboard.c @@ -0,0 +1,29 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "ec_commands.h" + +static const struct ec_response_keybd_config craask_kb = { + .num_top_row_keys = 10, + .action_keys = { + TK_BACK, /* T1 */ + TK_REFRESH, /* T2 */ + TK_FULLSCREEN, /* T3 */ + TK_OVERVIEW, /* T4 */ + TK_SNAPSHOT, /* T5 */ + TK_BRIGHTNESS_DOWN, /* T6 */ + TK_BRIGHTNESS_UP, /* T7 */ + TK_VOL_MUTE, /* T8 */ + TK_VOL_DOWN, /* T9 */ + TK_VOL_UP, /* T10 */ + }, + .capabilities = KEYBD_CAP_SCRNLOCK_KEY, +}; + +__override const struct ec_response_keybd_config * +board_vivaldi_keybd_config(void) +{ + return &craask_kb; +} diff --git a/zephyr/projects/nissa/craask/src/led.c b/zephyr/projects/nissa/craask/src/led.c new file mode 100644 index 0000000000..0af0202cf4 --- /dev/null +++ b/zephyr/projects/nissa/craask/src/led.c @@ -0,0 +1,56 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Battery LED control for nissa + */ +#include "common.h" +#include "ec_commands.h" +#include "led_common.h" +#include "led_onoff_states.h" +#include "led_pwm.h" + +__override const int led_charge_lvl_1 = 5; +__override const int led_charge_lvl_2 = 97; +__override struct led_descriptor + led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { + [STATE_CHARGING_LVL_1] = { { EC_LED_COLOR_AMBER, + LED_INDEFINITE } }, + [STATE_CHARGING_LVL_2] = { { EC_LED_COLOR_AMBER, + LED_INDEFINITE } }, + [STATE_CHARGING_FULL_CHARGE] = { { EC_LED_COLOR_BLUE, + LED_INDEFINITE } }, + [STATE_DISCHARGE_S0] = { { EC_LED_COLOR_BLUE, + LED_INDEFINITE } }, + [STATE_DISCHARGE_S0_BAT_LOW] = { { EC_LED_COLOR_AMBER, + LED_INDEFINITE } }, + [STATE_DISCHARGE_S3] = { { EC_LED_COLOR_AMBER, + 1 * LED_ONE_SEC }, + { LED_OFF, 3 * LED_ONE_SEC } }, + [STATE_DISCHARGE_S5] = { { LED_OFF, LED_INDEFINITE } }, + [STATE_BATTERY_ERROR] = { { EC_LED_COLOR_AMBER, + 1 * LED_ONE_SEC }, + { LED_OFF, 1 * LED_ONE_SEC } }, + [STATE_FACTORY_TEST] = { { EC_LED_COLOR_AMBER, + 2 * LED_ONE_SEC }, + { EC_LED_COLOR_BLUE, + 2 * LED_ONE_SEC } }, + }; + +__override void led_set_color_battery(enum ec_led_colors color) +{ + switch (color) { + case EC_LED_COLOR_RED: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_RED); + break; + case EC_LED_COLOR_BLUE: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_BLUE); + break; + case EC_LED_COLOR_AMBER: + set_pwm_led_color(EC_LED_ID_BATTERY_LED, EC_LED_COLOR_AMBER); + break; + default: /* LED_OFF and other unsupported colors */ + set_pwm_led_color(EC_LED_ID_BATTERY_LED, -1); + break; + } +} diff --git a/zephyr/projects/nissa/craask/src/usbc.c b/zephyr/projects/nissa/craask/src/usbc.c new file mode 100644 index 0000000000..a15460a212 --- /dev/null +++ b/zephyr/projects/nissa/craask/src/usbc.c @@ -0,0 +1,277 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <zephyr/logging/log.h> + +#include "charge_state_v2.h" +#include "chipset.h" +#include "hooks.h" +#include "usb_mux.h" +#include "system.h" +#include "driver/charger/isl923x_public.h" +#include "driver/retimer/anx7483_public.h" +#include "driver/tcpm/tcpci.h" +#include "driver/tcpm/raa489000.h" + +#include "nissa_common.h" + +LOG_MODULE_DECLARE(nissa, CONFIG_NISSA_LOG_LEVEL); + +struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C0_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, + { /* sub-board */ + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_USB_C1_TCPC, + .addr_flags = RAA489000_TCPC0_I2C_FLAGS, + }, + .drv = &raa489000_tcpm_drv, + /* RAA489000 implements TCPCI 2.0 */ + .flags = TCPC_FLAGS_TCPCI_REV2_0 | + TCPC_FLAGS_VBUS_MONITOR, + }, +}; + +int board_is_sourcing_vbus(int port) +{ + int regval; + + tcpc_read(port, TCPC_REG_POWER_STATUS, ®val); + return !!(regval & TCPC_REG_POWER_STATUS_SOURCING_VBUS); +} + +int board_set_active_charge_port(int port) +{ + int is_real_port = (port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); + int i; + int old_port; + + if (!is_real_port && port != CHARGE_PORT_NONE) + return EC_ERROR_INVAL; + + old_port = charge_manager_get_active_charge_port(); + + LOG_INF("New chg p%d", port); + + /* Disable all ports. */ + if (port == CHARGE_PORT_NONE) { + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW); + raa489000_enable_asgate(i, false); + } + + return EC_SUCCESS; + } + + /* Check if port is sourcing VBUS. */ + if (board_is_sourcing_vbus(port)) { + LOG_WRN("Skip enable p%d", port); + return EC_ERROR_INVAL; + } + + /* + * Turn off the other ports' sink path FETs, before enabling the + * requested charge port. + */ + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (i == port) + continue; + + if (tcpc_write(i, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_LOW)) + LOG_WRN("p%d: sink path disable failed.", i); + raa489000_enable_asgate(i, false); + } + + /* + * Stop the charger IC from switching while changing ports. Otherwise, + * we can overcurrent the adapter we're switching to. (crbug.com/926056) + */ + if (old_port != CHARGE_PORT_NONE) + charger_discharge_on_ac(1); + + /* Enable requested charge port. */ + if (raa489000_enable_asgate(port, true) || + tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_SNK_CTRL_HIGH)) { + LOG_WRN("p%d: sink path enable failed.", port); + charger_discharge_on_ac(0); + return EC_ERROR_UNKNOWN; + } + + /* Allow the charger IC to begin/continue switching. */ + charger_discharge_on_ac(0); + + return EC_SUCCESS; +} + +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + int regval; + + /* + * The interrupt line is shared between the TCPC and BC1.2 detector IC. + * Therefore, go out and actually read the alert registers to report the + * alert status. + */ + if (!gpio_pin_get_dt(GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl))) { + if (!tcpc_read16(0, TCPC_REG_ALERT, ®val)) { + /* The TCPCI Rev 1.0 spec says to ignore bits 14:12. */ + if (!(tcpc_config[0].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_0; + } + } + + if (board_get_usb_pd_port_count() == 2 && + !gpio_pin_get_dt(GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl))) { + if (!tcpc_read16(1, TCPC_REG_ALERT, ®val)) { + /* TCPCI spec Rev 1.0 says to ignore bits 14:12. */ + if (!(tcpc_config[1].flags & TCPC_FLAGS_TCPCI_REV2_0)) + regval &= ~((1 << 14) | (1 << 13) | (1 << 12)); + + if (regval) + status |= PD_STATUS_TCPC_ALERT_1; + } + } + + return status; +} + +void pd_power_supply_reset(int port) +{ + /* Disable VBUS */ + tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_LOW); + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); +} + +__override void typec_set_source_current_limit(int port, enum tcpc_rp_value rp) +{ + if (port < 0 || port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return; + + raa489000_set_output_current(port, rp); +} + +int pd_set_power_supply_ready(int port) +{ + int rv; + + if (port >= CONFIG_USB_PD_PORT_MAX_COUNT) + return EC_ERROR_INVAL; + + /* Disable charging. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SNK_CTRL_LOW); + if (rv) + return rv; + + /* Our policy is not to source VBUS when the AP is off. */ + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return EC_ERROR_NOT_POWERED; + + /* Provide Vbus. */ + rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_SRC_CTRL_HIGH); + if (rv) + return rv; + + rv = raa489000_enable_asgate(port, true); + if (rv) + return rv; + + /* Notify host of power info change. */ + pd_send_host_event(PD_EVENT_POWER_CHANGE); + + return EC_SUCCESS; +} + +void board_reset_pd_mcu(void) +{ + /* + * TODO(b:147316511): could send a reset command to the TCPC here + * if needed. + */ +} + +/* + * Because the TCPCs and BC1.2 chips share interrupt lines, it's possible + * for an interrupt to be lost if one asserts the IRQ, the other does the same + * then the first releases it: there will only be one falling edge to trigger + * the interrupt, and the line will be held low. We handle this by running a + * deferred check after a falling edge to see whether the IRQ is still being + * asserted. If it is, we assume an interrupt may have been lost and we need + * to poll each chip for events again. + */ +#define USBC_INT_POLL_DELAY_US 5000 + +static void poll_c0_int(void); +DECLARE_DEFERRED(poll_c0_int); +static void poll_c1_int(void); +DECLARE_DEFERRED(poll_c1_int); + +static void usbc_interrupt_trigger(int port) +{ + schedule_deferred_pd_interrupt(port); + usb_charger_task_set_event(port, USB_CHG_EVENT_BC12); +} + +static inline void poll_usb_gpio(int port, const struct gpio_dt_spec *gpio, + const struct deferred_data *ud) +{ + if (!gpio_pin_get_dt(gpio)) { + usbc_interrupt_trigger(port); + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); + } +} + +static void poll_c0_int(void) +{ + poll_usb_gpio(0, GPIO_DT_FROM_NODELABEL(gpio_usb_c0_int_odl), + &poll_c0_int_data); +} + +static void poll_c1_int(void) +{ + poll_usb_gpio(1, GPIO_DT_FROM_ALIAS(gpio_usb_c1_int_odl), + &poll_c1_int_data); +} + +void usb_interrupt(enum gpio_signal signal) +{ + int port; + const struct deferred_data *ud; + + if (signal == GPIO_SIGNAL(DT_NODELABEL(gpio_usb_c0_int_odl))) { + port = 0; + ud = &poll_c0_int_data; + } else { + port = 1; + ud = &poll_c1_int_data; + } + /* + * We've just been called from a falling edge, so there's definitely + * no lost IRQ right now. Cancel any pending check. + */ + hook_call_deferred(ud, -1); + /* Trigger polling of TCPC and BC1.2 in respective tasks */ + usbc_interrupt_trigger(port); + /* Check for lost interrupts in a bit */ + hook_call_deferred(ud, USBC_INT_POLL_DELAY_US); +} |