Compare commits

...

277 Commits

Author SHA1 Message Date
Sravan Balaji
e41716575c Fan Curve Adjustment to avoid CPU Throttling
- Modify fan curve to avoid CPU throttling
- Reduce fan curve cooldown time for oryp7
2024-10-06 17:08:07 -04:00
Tim Crawford
3d8204c3f4 Require Intel for PECI, add empty AMD power module
PECI is an Intel-only mechanism for getting CPU temp. AMD will use
SB-TSI to get temps.

Add empty power functions for AMD so the project will compile with AMD
selected.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-09-05 17:19:42 -06:00
Tim Crawford
2c6977bc6b Add config for host platform
Introduce a new config to determine the host platform and use it to
conditionally include power sequence logic.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-09-05 17:19:42 -06:00
Tim Crawford
ae63a9e3fb fan: Replace interpolation, smoothing with stepping
Fan noise is one of the top complaints reported. The existing
interpolation and smoothing logic has not sufficiently addressed the
issues with fans changing speeds too quickly in response to rapid
changes in thermals (particularly from PECI).

This behavior can be observed by with very basic tasks, such as:

- Powering on a system and logging into GNOME
- Starting a GUI application such as Firefox

Replace them with a fixed step update per event interval. Fans now have
a maximum amount they change change over time (3.9%/sec) as they move
towards a target duty.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-08-29 08:44:23 -06:00
Tim Crawford
88ad52491a Use CTR0 for max fan
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-08-29 08:44:23 -06:00
Tim Crawford
85cd3aa9ce Move fan-specific PWM logic to fan module
Better define the scope of the tachometer variables by moving them to
the fan module. `fan_update_duty` is renamed to `fan_event` to reflect
that it handles more than just updating the PWM duties.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-08-29 08:44:23 -06:00
Tim Crawford
710b4795fb Sync fans based on temp instead of duty
Fans may be different sizes, placed in asymmetrical positions, or have
different amounts of venting through the chassis. These characteristics
affect the ability for each fan, separately, to dissipate heat and
generate noise.

Replace syncing fans to the highest duty calculated for each fan, based
on separate thermal sensors, to using the highest reported temperature
across all sensors to calculate each fan's duty for that highest
temperature.

In other words: The old behavior synced fans based on the *output* value
(duty), while this new behavior syncs fans based on the *input* value
(temperature).

This allows tuning fans separately to better manage total system
thermals and mitigate noise.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-08-15 09:34:36 -06:00
Tim Crawford
2925376b6b bonw15-b: Add new Bonobo
The new Bonobo has the same pin layout as the original bonw15, but
uses the larger IT5570E-256 instead of keeping the IT5570E-128.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-08-07 11:36:53 -06:00
Tim Crawford
51d35cb272 Remove GPH7 on IT8587E
On IT8587E, pin 3 is VBAT and not a GPIO pin.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-29 18:41:30 -06:00
Tim Crawford
716efd4eb5 kbscan: Work around IT8587E hang
IT8587E is hanging when reading the keyboard matrix.

- Increasing the delay does not fix it
- Placing delays between KSO* writes does not fix it
- Code generated by SDCC looks valid to me

Rewriting it like this does fix it, although I don't know why.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-29 17:17:46 +02:00
Tim Crawford
984428b6a8 darp10: Add custom fan points
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-26 14:04:11 -06:00
Tim Crawford
0f7642defb Use a 16-bit system tick
The maximum interval when configured for a 1ms tick:

- 16-bit: ~65 seconds
- 32-bit: ~49.7 days

The value is used for scheduling and timeouts, and not to track the
uptime of the system, so the 32-bit value is excessive.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-25 11:38:35 -06:00
Tim Crawford
9e7f1952fa Add enum for PECI command codes
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-24 08:06:59 -06:00
Tim Crawford
face381354 Require boards to declare fan points
Thermal properties of each model differ and they should not rely on an
arbitrary, unoptimized set of fan points.

It is one thing to copy the points from the previous generation for a
model, as a lot of the time the chassis design is nearly identical, but
it should be always be explicit.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-17 16:28:39 -06:00
Tim Crawford
a7bd81432e fan: Allow FAN2 without dGPU
Fully support fan points for the second fan on darp10.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-17 16:28:39 -06:00
Tim Crawford
ffd0b7cbde fan: Do not make functions reentrant
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-17 16:28:39 -06:00
Tim Crawford
e75a2f1e10 Improve handling of second fan
Replace hard-coded PWM channels with defines so the second fan on darp10
can be handled like the second fan on units with a dGPU.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-17 16:28:39 -06:00
Tim Crawford
f8697a7ec4 Make fan names more generic
darp10 demonstrates that a board without a dGPU may still have a second
fan, so rename the CPU (PECI) fan to FAN1 and dGPU fan to FAN2.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-17 16:28:39 -06:00
Tim Crawford
ceba69d7fa Refactor reading thermals, updating fan duty
Move the fan-related logic from the PECI and dGPU modules to the fan
module. The PECI and dGPU modules are now only responsible for reading
the thermal data, and the fan module handles calculating and updating
the fans duties based on that data.
2024-07-17 16:28:39 -06:00
Tim Crawford
e01536005a peci: Perform offset calculation in temp function
Have peci_get_temp() return the actual temp instead of the offset,
requiring the caller to make another calculation for the temp.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-17 16:28:39 -06:00
Tim Crawford
8f88c0c7aa dgpu: Split out getting temp to a function
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-17 16:28:39 -06:00
Tim Crawford
80cfa91b9f acpi: Report RPM values instead of raw tachometer values
Ref: IT5570E V0.3.2 datasheet; 7.12.3.2 Manual Fan Control Mode
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-17 16:28:39 -06:00
Tim Crawford
2a44e03a40 Update Rust toolchain config
Remove rust-src as it is not required. Use a minimal profile with
clippy and rustfmt installed, instead of the default profile, as
rust-docs is not needed.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-17 13:00:13 -06:00
Tim Crawford
70c8678a5f tool: Add error for write locked
Add a new error for the case of trying to flash when security is enabled
and it is still locked and update the related docs.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-15 11:49:32 -06:00
Tim Crawford
54d795480c ci: Show memory layout
I regularly use the `.mem` file to determine the impact changes have on
the RAM and flash usage. Print it as part of CI so I can easily see it
for all boards.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-12 08:17:26 -06:00
Tim Crawford
426dc99f10 tool: Update clap to 4.5
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-10 13:20:53 -06:00
Tim Crawford
1e02be1cbe Format with uncrustify
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-03 15:58:28 -06:00
Tim Crawford
d3894392d5 Replace clang-format with uncrustify
LLVM/clang is not used for any compilation due to it not supporting the
8-bit architectures we use (MCS-51, AVR). This means we are effectively
installing 250+ MiB of dependencies for a C formatting tool.

Replace it with uncrustify, which uses only ~600 KiB of space and has
more granular control of formatting (800+ options).

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-03 15:58:28 -06:00
Tim Crawford
6c3b34ee6e ci: Update runner to Ubuntu 24.04
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-03 15:58:28 -06:00
Tim Crawford
3d09a0b546 Conditionally compile dGPU support
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-07-03 13:47:40 -06:00
Jeremy Soller
5b0766a209 USe debounce bit and do not use interrupts for touchpad 2024-06-21 18:18:02 -06:00
Jeremy Soller
d88a175e23 Clear PS/2 touchpad status when waiting for write to finish 2024-06-21 18:18:02 -06:00
Tim Crawford
2c5c708569 oryp12: Fix USB-PD config
Fixes: 1e4667f1d3 ("Conditionally compile USB-PD support")
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-06-17 17:12:38 -06:00
Tim Crawford
a67b0c98b8 lemp13-b: Remove GPB7
Fixes: f79f4d1157 ("Remove GPB7 on IT5570E")
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-06-17 16:38:22 -06:00
Tim Crawford
f79f4d1157 Remove GPB7 on IT5570E
On IT5570E, pin A1 is VSTBY0 and not a GPIO pin.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-06-17 15:37:01 -06:00
Tim Crawford
1e4667f1d3 Conditionally compile USB-PD support
Boards may not have USB-PD. Remove the need for a "none" option by only
adding USB-PD sources when enabled.

The resulting binary for boards with USB-PD enabled (addw3, bonw15,
serw13) are identical. The binary for boards without USB-PD now have the
empty calls optimized out.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-06-17 14:52:34 -06:00
Tim Crawford
fc3bad29a2 pnp: Match EC2I programming guide
Use the sequence specified by the flowcharts in the ITE manuals.

Ref: IT5570E V0.3.2 datasheet; 7.15.5 EC2I Programming Guide
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-05-17 10:02:22 -06:00
Tim Crawford
8382c81b9d tool: Update Rust toolchain to nightly-2024-05-11
Update toolchain to match the version used in Redox.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-05-17 09:57:27 -06:00
Jeremy Soller
09c5a3b5f0 lemp13-b: use darp10-b keymap 2024-05-17 08:34:54 -06:00
Jeremy Soller
b4768ed2dd Add lemp13-b 2024-05-17 08:34:54 -06:00
Tim Crawford
88c77aa1d3 darp10-b: Add custom keymap
The darp10-b replaces the display toggle with mic mute like other newer
units.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-05-07 14:35:29 -06:00
Jeremy Soller
522284e5d5 Add darp10-b 2024-05-07 14:35:29 -06:00
Tim Crawford
e7ad77898b darp10: Add custom keymap
The customer units for darp10 will have custom keyboard with the alt
legend on Num / removed.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-05-07 14:35:29 -06:00
Tim Crawford
b744529960 [HACK] darp10: Set FAN2 duty to FAN1
This model has a second CPU fan connected to PWM3.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-05-07 14:35:29 -06:00
Tim Crawford
748ec13132 darp10: Add Darter Pro 10
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-05-07 14:35:29 -06:00
Tim Crawford
38d4666a90 oryp12: Use OZ26786 charger
Ref: Schematics sheet 58 ("AC In Charger")
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-21 13:32:38 -06:00
Tim Crawford
637036ec02 oryp12: Enable security
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-19 17:22:49 -06:00
Tim Crawford
6a40a54932 oryp12: Add Oryx Pro 12
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-19 14:28:24 -06:00
Jeremy Soller
91b8c48773 Add lemp13 2024-03-19 13:22:24 -06:00
Jeremy Soller
90af96faf5 eSPI: debug all vwire indexes 2024-03-19 13:22:24 -06:00
Jeremy Soller
17aae5af71 Update ecspy 2024-03-19 13:22:24 -06:00
Tim Crawford
6aced2fd57 ci: Update actions/checkout to v4
Fixes the following warnings in Actions:

    Node.js 16 actions are deprecated. Please update the following
    actions to use Node.js 20: actions/checkout@v3.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-18 14:27:58 -06:00
Tim Crawford
16e4f93f2c Mark pointed-to data const where possible
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-18 14:27:36 -06:00
Tim Crawford
9fb08ffa46 Mark pointers as const
Resulting binaries are identical.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-18 14:27:36 -06:00
Tim Crawford
d60a8e4c8e scripts: Remove explicit rustup self update
Commit 17f8e37ed5 ("Convert toolchain file to TOML syntax") switched
from the bare toolchain file to the TOML-based one for better management
of the toolchain and components used.

Commit 1cb61e6918 ("deps.sh: Update rustup or inform user of env
vars") added an explicit `rustup self update` because there were still
cases, a year later, of people not having a rustup new enough to support
the TOML-based toolchain file.

Now 2 years after that, it should be safe to drop the explicit self
update. The TOML format has widespread adoption and rustup now self
updates by default. This should allow distro-provided rustup, which
disables the self update feature, to work if it is already installed in
place of the one downloaded from https://rustup.rs.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-18 14:20:31 -06:00
Jeremy Soller
8c52c313e1 addw4: improved fan curve 2024-03-11 08:54:13 -06:00
Tim Crawford
8af7fd5bad addw4: Enable security
Development is sufficiently far along that this can default to enabled.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-01 11:15:40 -07:00
Tim Crawford
2174b4593a addw4: Enable KBLED support
Fixes: fff6208f98 ("Conditionally compile KBLED support")
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-01 09:44:34 -07:00
Tim Crawford
fff6208f98 Conditionally compile KBLED support
Remove the need for a "none" option by only adding KBLED sources when
enabled.

The resulting binaries with KBLED enabled (all of them) are identical.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-02-28 13:20:23 -07:00
Tim Crawford
ecac574671 addw4: Add Adder WS 4
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-02-28 11:40:32 -07:00
Tim Crawford
acf67d4413 tool: Assume ROM size is total flash size
Remove the hard-coded assumption that the EC is always 128K, as ITE
chips can also be 256K (which Clevo has started using since addw4).
Instead assume the ROM is correctly sized, which we do since
0d83819a21 ("Pad binary file to total flash size") and proprietary
firmware has always done.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-02-28 11:40:32 -07:00
Tim Crawford
183778c32f make: Fix printing error if BOARD unset
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-02-28 11:40:32 -07:00
Tim Crawford
82b9e19746 time: Replace hard-coded values with macro
This is more descriptive than the comment and allows for changing
values, such as using a chip with a different clock frequency.

The resulting binary is identical.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-02-26 09:06:05 -07:00
Tim Crawford
449bafd130 main: Remove empty switch case
SDCC 4.4.0 now fails to compile if there are empty switch cases.

    src/board/system76/common/main.c:105: error 110: conditional flow changed by optimizer: so said EVELYN the modified DOG

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-02-24 21:03:21 -07:00
Tim Crawford
ef4eeae2df ite: Add support for 256K flash
The upcoming addw4 will use the IT5570E-256, which requires removing the
assumption that every ITE chip is 128K. Introduce new configs so boards
may select which flash size they use.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-01-25 13:26:43 -07:00
Tim Crawford
4b86176659 main: Replace MOD with bitwise AND
This prevents `moduint` from being called for the superloop.

A bitwise AND is used instead of using the equivalent `% 4` as an
indication that modulo should not be used, as not using a power of 2
(which is optimized) will result in an expensive call to SDCC library
functions.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-01-05 15:04:28 -07:00
Tim Crawford
766fb738a0 kbscan: Remove unused array
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-01-04 15:05:40 -07:00
Tim Crawford
0ccb8079ae kbscan: Do not read matrix if lid is closed
Pull the lid check out to the loop to avoid accessing the matrix when we
know we do not need the data. It is left in kbscan (instead of simply
disabling reading) to clear the state of the matrix data.

The lid check for wake is removed as it will never be true.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-01-04 15:05:40 -07:00
Tim Crawford
0e1a748b16 kbscan: Disable reading columns at init
The functionality is split into a separate function to optimize the use
case for each.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-01-04 11:55:56 -07:00
Tim Crawford
11b1e724b5 docs: Add note about write lock for flashing
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-01-03 09:45:34 -07:00
Ian Douglas Scott
47b070418a ectool: Use clap derive syntax
Co-authored-by: Tim Crawford <tcrawford@system76.com>
2023-12-08 16:04:37 -07:00
Tim Crawford
cbad8e09be smfi: Remove always true conditional
SDCC 4.3.3 (terribly) reports this as an error:

    src/board/system76/common/smfi.c:244: error 110: conditional flow changed by optimizer: so said EVELYN the modified DOG

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-10-19 08:02:41 -06:00
Tim Crawford
713e1d9681 Add void to function declarations with no args
SDCC 4.3.3 complains about the declaration not matching the prototype:

    error 283: function declarator with no prototype

Add `void` to the AVR functions as well, even though no warning is
issued by GCC.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-10-19 08:02:41 -06:00
Tim Crawford
01be30f107 Only support building a single board at a time
As a follow up to c461e20df3 ("make: Remove version from build output
path"), only support building a single version of a single board by
default. The build directory can still be specified by passing `BUILD`.

Fixes running the `clean` target when `BUILD` is a custom value or
`BOARD` isn't set.

Fixes: b03c960b4f ("make: Reduce build output")
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-10-12 12:49:43 -06:00
Tim Crawford
946415f3a7 peci: Add timeouts to infinitely blocking waits
Add timeouts to the legacy PECI implementation to prevent the EC locking
up when PECI stops working, such as during S0ix opportunistic suspend.

This is not the optimal solution, as PECI should not be available at all
to cause the lock up in the first place, but it at least prevents the
issue.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-10-12 09:09:20 -06:00
Tim Crawford
a3fb9e1c77 avr: Fix compiling with GCC 13
Apply the CFLAGS workaround for GCC 13.

The issue is fixed in GCC 14, so only 12 and 13 are affected.

Ref: 84fe76cad4 ("avr: Fix compiling with GCC 12")
Ref: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-10-06 13:58:27 -06:00
Tim Crawford
166e03972b tool: Derive Eq, PartialEq on enums
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-10-05 14:32:15 -06:00
Tim Crawford
4fa389e1bd tool: Fix clippy warnings
Fix:

- clippy::unnecessary_cast
- clippy::needless_borrow

Allow:

- clippy::uninlined_format_args
- clippy::get_first

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-10-05 14:32:15 -06:00
Tim Crawford
782f18a3f6 tool: Update toolchain, edition, deps
- Update toolchain to nightly-2023-09-07
- Update edition to 2021
- Update deps

`OpenHidDeviceError` is deprecated, and is removed in newer versions.
Replace it with `HidApiErrorEmpty`, because there are no descriptions
for what anything means so I just picked one that didn't require fields.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-10-05 14:32:15 -06:00
Tim Crawford
c461e20df3 make: Remove version from build output path
Support building only a single version for a model. This removes the
need to determine the git commit hash and date in order to access build
artifacts.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-10-03 09:40:42 -06:00
Matt Parnell
bb1ce2273b fix sdcc 4.3.0 #14184 build error - error 283: function declarator with no prototype 2023-09-20 09:36:34 -06:00
Tim Crawford
181d4c5d59 kbscan: Increase debounce time from 5ms to 10ms
Some users are reporting that a debounce time of 5ms is not enough to
prevent keys from registering twice. Split the difference between the
old and the new debounce times and set it to 10ms.

Ref: https://github.com/system76/firmware-open/issues/471
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-09-07 17:14:44 -06:00
Jeremy Soller
1097fd999a Do not force charging if end threshold is not set 2023-08-17 17:55:04 -06:00
Tim Crawford
34dd9ccbac battery: Disable charger if full or not on AC
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-08-17 17:55:04 -06:00
Jeremy Soller
894b82d4fb Set default battery start threshold to 90% 2023-08-17 17:55:04 -06:00
Tim Crawford
dc482dd11a Add basic support for IT5571E
The IT5571E is nearly identical to the IT5570E.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-08-15 08:24:02 -06:00
Winston Hoy
13dd6a1038 Update debugging.md 2023-08-02 09:14:35 -06:00
Winston Hoy
c0bfb257db Update debugging.md 2023-08-02 09:14:35 -06:00
Winston Hoy
8d844cf966 add console_internal debugging instructions 2023-08-02 09:14:35 -06:00
Tim Crawford
01907011bb Add a FnLock key
Implement a FnLock toggle that behaves as follows:

- Disabled: F1-F12 are normal
- Enabled: F1-F12 are the alternate function

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-08-01 14:39:59 -06:00
Tim Crawford
b63e2092ce peci: Check PECI available based on eSPI usage
If eSPI is used, use Virtual Wires to determine if PECI is available.

Fixes incorrectly reporting PECI as available on systems using S0ix, as
the CPU would be in C10 but `PLTRST#` would not be asserted.

Requires enabling `HOST_C10` reporting in FSP-S.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-08-01 14:24:21 -06:00
Tim Crawford
ebc5168cb0 Remove the use of symlinks
Replace symlinks with directories with `board.mk`, using relative paths
to include the files rather than duplicate them.

This allows making board-specific changes without affecting other
boards, such as when firmware security had to be enabled on galp6 when
it was enabled on galp7 (2d5cbadf71).

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-31 09:06:23 -06:00
Tim Crawford
9b7c6704c3 docs: Build with mdBook
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-31 09:05:53 -06:00
Tim Crawford
bd291871f4 Rename doc/ to docs/
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-31 09:05:53 -06:00
Tim Crawford
9302a30a2d pmc: Add interrupt control and enable registers
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-31 09:04:52 -06:00
Tim Crawford
459e5a3614 ec/ite: Add WUC functions to handle interrupts
Add functions to enable, disable, and clear an interrupt.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-31 09:04:20 -06:00
Tim Crawford
120ed1e2c5 ec/ite: Add INTC functions to handle interrupts
Add functions to enable, disable, and clear an interrupt.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-31 09:04:20 -06:00
Tim Crawford
d4ecd8a79a kbscan: Remove comparing matrix to keymap
Remove checking against the real keys declared in the keymap. It appears
to have no effect on behavior.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-28 20:07:24 -06:00
Tim Crawford
0f2ff7e540 kbscan: Switch from GPIO mode to KBS (Normal) mode
Use the default mode for reading the keyboard scan matrix when being
used as a keyboard. There should be no perceived change in behavior, but
should make the code easier to understand.

Note: `KSO[17:16]` are configured by `GPCRC` on boards that use them.
They are now set to alternate function to use in KBS mode rather than
GPIO mode, with the pull-up enabled to prevent them from floating when
configured as open-drain.

As part of this change, we now only read the hardware matrix state once
upfront, instead of on every iteration through the loop applying the
logic.

Tested by verifying that typing still works on darp9.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-28 20:07:24 -06:00
Tim Crawford
546458e368 kbscan: Return early if debouncing
A single timer is used for debouncing all keys, so there is no reason to
perform any operations if the matrix is being debounced. Just return
early and remove some of the convoluted logic.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-25 13:03:25 -06:00
Tim Crawford
8a1adc2bdc Enable power switch WDT on IT5570E boards
Enable PWRSW WDT 2 and use the default timeout of 10 seconds.

Allows forcing an EC reset in case it gets into an invalid state.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-22 06:35:42 -06:00
Tim Crawford
45520646aa power: Reset KBC on CPU reset
Ensure the keyboard controller is not left locked/disabled.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-22 06:32:07 -06:00
Tim Crawford
de546fa761 kbc: Add reset function
This function can be called after EC init to put the KBC into a known
working state.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-22 06:32:07 -06:00
Tim Crawford
0d83819a21 Pad binary file to total flash size
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-19 06:13:17 -06:00
Tim Crawford
64e5b8308d lemp: Remove pull-down from CPU fan sense
Matches the GPIO for all other boards.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-17 18:06:35 -06:00
Tim Crawford
1ebc0bc6c2 galp6: Set CPU/VGA fan sense to TACH functionality
Set D6 and D7 to ALT to use as tachometers inputs from the fans.

Matches config for all other boards.

Ref: IT5570E V0.3.2 datasheet; 7.5.4 Alternate Function Selection
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-17 18:06:35 -06:00
Tim Crawford
e093952dd2 kbscan: Reduce debounce time from 15ms to 5ms
Allows increased typing speed while avoiding repeating keys due to
contact bounce and keys being rejected by ghost key detection.

This is the default value for QMK.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-17 13:38:15 -06:00
Tim Crawford
1fded3f7bf Use %cs format when getting the commit date
From the man page:

    %cs
        committer date, short format (YYYY-MM-DD)

This is identical to what we use, without having to specify a custom
date format for it.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-07 23:20:51 -06:00
Tim Crawford
4458d5dbe2 bonw15: Set battery Rsense to 5
PRS3 is 0.005 Ohms.

However, I am unsure about this change because PRS1 and PRS2 are also
both 0.005 Ohms, but are in *parallel*.

Ref: bonw15 schematics, Charger (Sheet 70)
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-06 12:31:03 -06:00
Tim Crawford
42a19b3d6b oryp11,serw13: Set adapter Rsense to 10 milliohms
PRS1 is 5, but it is in series with PRS3, which is also 5. PRS1 by
itself is only connected to ACP/ACN.

Ref: oryp11 schematics, AC In Charger (Sheet 59)
Ref: serw13 schematics, AC_In, Charger (Sheet 70)
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-07-06 12:31:03 -06:00
Tim Crawford
dd555b9012 peci: Clear status on completion
The PECI-over-eSPI implementation, like the legacy implementation, must
acknowledge when the transaction is done by clearing the bit in the
register.

Fixes a hang during shutdown on oryp11 after unplugging a TBT display.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-21 12:44:12 -06:00
Tim Crawford
c7288a5a60 darp9,oryp11: Update keyboard
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-16 14:49:54 -06:00
Tim Crawford
8e6d938f90 Add new keyboards
Replace micmute and darp9 layouts with new keyboards.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-16 14:40:43 -06:00
Yethal
347bbf0d9a reuse make target for board list 2023-06-15 13:45:12 -06:00
Yethal
faede6264a Generate matrix from directory 2023-06-15 13:45:12 -06:00
13r0ck
fe6faa21fc Add reset command to ectool 2023-06-14 13:50:20 -06:00
Tim Crawford
485f390077 darp9: Set CC_EN high
Fixes using the non-TBT USB-C port.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-08 12:18:53 -06:00
Jeremy Soller
9b111bafc6 Fix K_MIC_MUTE keycode 2023-06-07 17:24:06 -06:00
Tim Crawford
c09960cbc6 Replace Call Mute with random key for micmute
Replace the Windows specific key with an arbitrary keycode to remap to
micmute on Linux.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-07 17:24:06 -06:00
Tim Crawford
2dd33ffec5 Add "Call Mute" combo key for darp9
The proprietary firmware for the darp9 adds the mic mute hotkey using
the new "Call Mute" hotkey from Windows 11 22H2, which is mapped to
`Super+Alt+K` [1]. Match the behavior in open firmware.

[1]: https://support.microsoft.com/en-us/windows/keyboard-shortcuts-in-windows-dcc61a57-8ff0-cffe-9796-cb9706c75eec#WindowsVersion=Windows_11

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-07 17:24:06 -06:00
Tim Crawford
399415fdf6 Add custom keymap for darp9
Despite the darp9 supporting an RGB backlit keyboard, the keyboard
option was removed and it ships with a white-only LED backlit keyboard
instead. The keypad `/` still has the cycle symbol printed on it, so
replace the color cycling function with the keyboard brightness
function used by other white-only LED keyboards (the 14" TKL ones).

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-07 17:24:06 -06:00
Tim Crawford
9ac513128a kbled: Add a "step" function for BKL hotkey
Replace the get+set logic with a step function to change the backlight
level for `K_KBD_BKL`.

Keyboards using a DAC have a different set of levels due to the
brightness difference between the keyboards.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-07 17:24:06 -06:00
Tim Crawford
4c9d3197b8 kbled: Make white_dac work like others
Make `white_dac` functions work based on the DAC power level like the
other I2C and PWM mechanisms, instead of preset values from an array.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-07 17:24:06 -06:00
Tim Crawford
bfbbfe43e6 acpi: Update keyboard backlight functions
Existing FDAT values remain unchanged in their functionality.
New functionality is added to fill unused FDAT values.

FDAT values correspond to the following functionality:

- 0: Set brightness
- 1: Get brightness
- 2: Get backlight type (new)
- 3: Set color
- 4: Get color (new)
- 5: <unused>
- 6: Set brightness (duplicate)

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-07 17:24:06 -06:00
Tim Crawford
598aef8c4a kbled: Check if using white or RGB keyboard
Use RGBKB-DET# to determine the type of keyboard connected.

If a white keyboard is attached, always set the color to white, and
always return white for the color.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-07 17:24:06 -06:00
Tim Crawford
c71a58f7cf Add RGBKB-DET# GPIO
This GPIO can be used to detect if the connected keyboard is RGB.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-07 17:24:06 -06:00
Tim Crawford
e60873a82c darp9: Add Darter Pro 9
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-07 17:24:06 -06:00
Jeremy Soller
002823908a oryp9,oryp10: enable firmware security 2023-06-07 11:56:11 -06:00
Tim Crawford
498508f2f1 scripts: Disable showing signature when getting date
Fixes building when `log.showSignature` is enabled.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-06-04 13:48:35 -06:00
Jeremy Soller
f4ad9520a8 bonw15: invert USB power GPIO 2023-05-31 20:20:44 -06:00
Tim Crawford
82f091ef55 galp{6,7}: Reduce PL4 on AC to 65W
Reduce PL4 to the same value as other non-GPU units, even though the
galp7 has an H series CPU.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-05-25 10:27:42 -06:00
Tim Crawford
2d5cbadf71 galp6,galp7: Enable firmware security
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-05-18 08:56:37 -06:00
Tim Crawford
43dfbb055b Increase PL4 on battery to 45W for dGPU boards
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-05-17 10:43:26 -06:00
Tim Crawford
99dfbeaec3 power: Set PL4 based on AC state on all boards
Limit PL4 based on AC state for all units, not just those with dGPUs.
This will allow setting standard values in coreboot.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-05-17 10:43:26 -06:00
Tim Crawford
b967e7c921 Format code
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-05-15 10:25:44 -06:00
Jeremy Soller
f5c4eaba97 lemp12: hack to drain LDO_3V3 capacitors 2023-05-12 11:00:27 -06:00
Jeremy Soller
ca1996dd44 lemp12: Reset GPIO to match lemp11 2023-05-12 11:00:27 -06:00
Jeremy Soller
bc92291c26 lemp12: set PSYS current gain to 0.5uA/W 2023-05-12 11:00:27 -06:00
Jeremy Soller
e6b8eb4c42 charger/oz26786: support different PSYS current gains 2023-05-12 11:00:27 -06:00
Jeremy Soller
93c2784eb3 lemp12: adjust GPIOs some more 2023-05-12 11:00:27 -06:00
Jeremy Soller
f5c2548d04 lemp12: check and fix all GPIO config 2023-05-12 11:00:27 -06:00
Jeremy Soller
36e6059e90 lemp12: remove unused GPIOs 2023-05-12 11:00:27 -06:00
Jeremy Soller
3f4c65931a lemp12: enable firmware security 2023-05-12 11:00:27 -06:00
Jeremy Soller
55632aab7a lemp12: set PD_POWER_EN to output 2023-05-12 11:00:27 -06:00
Jeremy Soller
f80f40f006 Add lemp12 2023-05-12 11:00:27 -06:00
Tim Crawford
5d2f2fd5c0 galp7: Symlink to galp6
galp7 is a CPU refresh of galp6 and contains no EC changes.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-05-09 14:43:40 -06:00
Jeremy Soller
930f16b230 addw3, oryp11, serw13: Set VBATT_BOOST# to input 2023-04-03 13:06:16 -06:00
Jeremy Soller
d38ef1413f Fix style 2023-04-03 13:06:16 -06:00
Jeremy Soller
916c9f8c5f Fixup bonw15 gpios 2023-04-03 13:06:16 -06:00
Jeremy Soller
5d11cc14f8 bonw15: Change keyboard model to 15in_102 2023-04-03 13:06:16 -06:00
Jeremy Soller
a03ce8d1c3 Set bonw15 smart charger 2023-04-03 13:06:16 -06:00
Jeremy Soller
da9648dddb Add bonw15 2023-04-03 13:06:16 -06:00
Tim Crawford
d0596100bd serw13: Hook up USB-PD
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Jeremy Soller
cd0321bfbb Ensure smart charger uses new input current limits when detected 2023-04-03 13:06:16 -06:00
Jeremy Soller
658f24a8a8 Hack and slash until it is done 2023-04-03 13:06:16 -06:00
Jeremy Soller
7a5c111786 Set CPU power limit based on input current 2023-04-03 13:06:16 -06:00
Jeremy Soller
c5229fafab Set input current based on USB-PD charger data 2023-04-03 13:06:16 -06:00
Jeremy Soller
a5ea9f4f05 Expose input current setting 2023-04-03 13:06:16 -06:00
Jeremy Soller
49aee51343 Fix gaze17-3050 input current 2023-04-03 13:06:16 -06:00
Jeremy Soller
edcfac1050 Make INPUT_CURRENT a macro taking arguments 2023-04-03 13:06:16 -06:00
Jeremy Soller
5b55048ef3 WIP: USB-PD current detection 2023-04-03 13:06:16 -06:00
Jeremy Soller
a1f4bb55bb oryp11: Adjust fan curve 2023-04-03 13:06:16 -06:00
Jeremy Soller
cd53d28d2e oryp11: Increase DC power limit to 55W 2023-04-03 13:06:16 -06:00
Jeremy Soller
5adacc4241 serw13: Increase DC power limit to 55W 2023-04-03 13:06:16 -06:00
Jeremy Soller
4745b109d8 addw3: Increase DC power limit to 55W 2023-04-03 13:06:16 -06:00
Jeremy Soller
c76919b189 Add PD_EN to oryp11 to ensure it powers off 2023-04-03 13:06:16 -06:00
Tim Crawford
3eaa5e6e06 Only use PECI over eSPI on oryp11
Make all boards except oryp11 use the legacy PECI implementation. The
oryp11 removed the legacy pin (H_PECI) and must use PECI over eSPI.

All boards that use eSPI should switch to using PECI over eSPI once the
implementation is working correctly.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
c1c082d2cc power: Set PL4 after CPU reset
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
568fae6aba power: Remove last AC check from power_set_limit
Unconditionally set the power limit based on the current AC state when
power_set_limit is called. The contional logic to run it only on ACIN#
state change is already done in power_event.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
a198289695 Remove power_set_limit from board_event
This is already handled by power_event.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
b1bd244d49 gaze18: Set PWM pin to ALT
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Jeremy Soller
546dd30b5e Fix cold reset by using VW_SUS_PWRDN_ACK again 2023-04-03 13:06:16 -06:00
Jeremy Soller
1dd25e0bf0 Remove unnecessary config USE_S0IX from all boards 2023-04-03 13:06:16 -06:00
Jeremy Soller
8228362c5d Do not try to use peci between VW_HOST_RST_WARN and VW_PLTRST_N 2023-04-03 13:06:16 -06:00
Jeremy Soller
584e397b07 addw3, gaze18, oryp11, serw13: enable CONFIG_SECURITY 2023-04-03 13:06:16 -06:00
Jeremy Soller
86f281b410 Add ME_WE gpio for all boards 2023-04-03 13:06:16 -06:00
Jeremy Soller
4a1e0a5aa8 Add optional EC security state and documentation 2023-04-03 13:06:16 -06:00
Tim Crawford
4567f99015 peci: Clear status after command completion
Per the flow charts for PECI programming guide, clear the status
register after the command has completed.

Ref: IT5570E V0.3.2 datasheet
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
3dde812dba peci: Check FINISH for completed transaction
Per the IT5570E datasheet, FINISH should be used to check if a
transaction completed, not HOBY.

> For the polling mode, software continues reading the Host Status
> Register to check whether the transaction is completed or not (the
> Finish bit in the Host Status Register will be set when the
> transaction is completed).

Ref: IT5570E V0.3.2 datasheet
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
dd97946056 peci: Check for hardware error
Check if any hardware error bits are set instead of checking for only
command completion.

Move logging of WrPkgConfig() errors from power to peci.

Ref: IT5570E V0.3.2 datasheet
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
373dc36676 kbc: Enable Transaction Done interrupt
Step 2 for data transmission (both RX and TX) is to enable the
Transaction Done interrupt.

Ref: IT5570 V0.3.2, 7.9.3.1 Hardware Mode Selected
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
22487f737d gaze18: Set CC_EN high
Fixes using the TBT port (rear USB-C).

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Jeremy Soller
0348800411 addw3: Enable USB-C power 2023-04-03 13:06:16 -06:00
Jeremy Soller
f73160fad5 oryp11: Enable thunderbolt power 2023-04-03 13:06:16 -06:00
Jeremy Soller
4aeb3669a0 Fix formatting 2023-04-03 13:06:16 -06:00
Jeremy Soller
7587a6412d oryp11: set EC_AMP_EN high 2023-04-03 13:06:16 -06:00
Jeremy Soller
ba5438a79a Update power state prior to using PECI 2023-04-03 13:06:16 -06:00
Jeremy Soller
55df52a013 Remove unnecessary code from espi_event 2023-04-03 13:06:16 -06:00
Jeremy Soller
cb8e0971c6 PECI ESPI timeout of 10ms 2023-04-03 13:06:16 -06:00
Jeremy Soller
34ef03b19a Fix ESPI vw_get and vw_set 2023-04-03 13:06:16 -06:00
Jeremy Soller
33eaef2dd0 Reorder power plane detection 2023-04-03 13:06:16 -06:00
Jeremy Soller
0d438a3314 Make sure power_state is S0 before attempting PECI 2023-04-03 13:06:16 -06:00
Jeremy Soller
962d55309a Gate peci_available on ESPI availability 2023-04-03 13:06:16 -06:00
Jeremy Soller
fc1fda0725 Use EC_RSMRST# for S5 detection on eSPI systems as well 2023-04-03 13:06:16 -06:00
Jeremy Soller
35d3c4f161 Fix style 2023-04-03 13:06:16 -06:00
Jeremy Soller
6b80721138 oryp11: set prochot the right way 2023-04-03 13:06:16 -06:00
Jeremy Soller
a0c81f6304 Improvements for determining CPU state using virtual wires 2023-04-03 13:06:16 -06:00
Jeremy Soller
4e11f6220b Fix comparisons of vw_get values 2023-04-03 13:06:16 -06:00
Jeremy Soller
cea89a78d8 Use ESPI VW signals wherever possible 2023-04-03 13:06:16 -06:00
Jeremy Soller
a5a677ee63 oryp11: fix some GPIO configuration 2023-04-03 13:06:16 -06:00
Jeremy Soller
8c52a51af1 addw3: fix some GPIO configuration 2023-04-03 13:06:16 -06:00
Jeremy Soller
cda67e6d1e Fix stalls in getting PECI information over eSPI 2023-04-03 13:06:16 -06:00
Jeremy Soller
9abd9d853a common: peci: WIP peci_get_temp over espi 2023-04-03 13:06:16 -06:00
Jeremy Soller
83f40c643f ite: Add more eSPI registers 2023-04-03 13:06:16 -06:00
Jeremy Soller
95a654aaff common: peci: Remove extra shift in peci_get_temp 2023-04-03 13:06:16 -06:00
Jeremy Soller
53f22a6658 common: Break out PECI GetTemp logic, prepare for PECI over ESPI 2023-04-03 13:06:16 -06:00
Jeremy Soller
c8df652723 Rename gaze18-3050 to gaze18 2023-04-03 13:06:16 -06:00
Jeremy Soller
9c59871986 Rename gaze18-40x0 to addw3 2023-04-03 13:06:16 -06:00
Jeremy Soller
cd3e5ac329 Rename addp3 to oryp11 2023-04-03 13:06:16 -06:00
Jeremy Soller
d68a42180b Rename oryp11 to serw13 2023-04-03 13:06:16 -06:00
Jeremy Soller
55f961406c addp3: Use virtual wire for calculating power state 2023-04-03 13:06:16 -06:00
Jeremy Soller
db10c198b3 addp3: Add new board 2023-04-03 13:06:16 -06:00
Tim Crawford
c7bc078cbd gaze18-3050: Fix GPIOs for power sequence
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
60f9cfc8d6 gaze18-3050: Add new board
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
e4542d2aa5 oryp11: Adjust fan points
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Tim Crawford
e4d7196b5c oryp11: Increase AC power limit to 280W
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Jeremy Soller
d723e2e13d gaze18-40x0: Fix prochot polarity 2023-04-03 13:06:16 -06:00
Jeremy Soller
ff7d7138b0 Support power limits above 256W 2023-04-03 13:06:16 -06:00
Jeremy Soller
8bd3b49273 gaze18-40x0: gpio fixes 2023-04-03 13:06:16 -06:00
Tim Crawford
213f79e2b6 oryp11: Add new board
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-04-03 13:06:16 -06:00
Jeremy Soller
bc111b7a4b gaze18-40x0: Let PCH handle panel 2023-04-03 13:06:16 -06:00
Jeremy Soller
ef6ea32c37 Add gaze18-40x0 2023-04-03 13:06:16 -06:00
Tim Crawford
1046dd7aec Update Rust toolchain to 2023-01-21
Update the toolchain and deps, and use the sparse registry access.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-02-18 06:28:21 -07:00
Tim Crawford
96b2d78c2e Remove PMC hack for S0ix
Whatever the issue was appears to be fixed after rebasing coreboot on
the 4.19 release. lemp11 has successfully reached S0ix with SLP_S0#
asserted when booted on battery power for 100 cycles.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-02-18 06:27:17 -07:00
Tim Crawford
ddb19e8738 ec/ite: Add Wake-Up Control registers
Groups 1, 3, and 4 require explicitly enabling the wake-up function
before unmasking them in INTC.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-02-07 10:47:24 -07:00
Tim Crawford
084aefd506 ec/ite: Add Interrupt Controller registers
- IT8587E has groups 0-18
- IT5570E has groups 0-21
- IT81202E has groups 0-23

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-02-07 10:47:24 -07:00
Tim Crawford
59c386ec12 Move gpio_debug from board to EC code
The gpio_debug() functionality depends on the ITE registers and not
anything board-specific.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-23 14:26:30 -07:00
Tim Crawford
f687000a4f ci: Install deps before running lints
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-18 13:52:14 -07:00
Tim Crawford
7205f1a49e Add shellcheck lint
Run shellcheck [1] on the bash files.

[1]: https://www.shellcheck.net/

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-18 13:52:14 -07:00
Tim Crawford
623d3ce8ab make: Add new targets
- fmt: Apply clang-format
- list-boards: list of available build targets
- help: Short description of make targets

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-18 13:52:14 -07:00
Tim Crawford
58f9ed4051 Run lints at pre-commit
Install a hook to run lints at pre-commit to force issues to be fixed
during development.

This introduces a 5-10 second delay when committing due to how slow
clang-format is.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-18 13:52:14 -07:00
Tim Crawford
1aadc68257 scripts: Rewrite lint scripts
Rewrite lint scripts to report what they do and if they pass. In the
case they fail list the files that caused the failure, except for
clang-format, which will be slow to run of every file individually
(should just run `make fmt` anyway). Also add a script to run all the
lints in order with a single command.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-18 13:52:14 -07:00
Tim Crawford
b03c960b4f make: Reduce build output
Default to silent builds, only outputting the file being generated. This
gives output similar to Linux/coreboot output when building. `VERBOSE=1`
can be passed to show the actual commands.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-18 12:18:31 -07:00
Tim Crawford
2056d4d5e0 make: Disable built-in rules and variables
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-18 12:18:31 -07:00
Tim Crawford
9a52042f95 Generate and use compiler dep rules
SDCC supports the `-MMD` option. Use it instead of having every file
depend on *all* the headers. Reduces incremental build time after
modifying headers as it will now only rebuild the actual dependents and
not the entire project.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-18 12:18:31 -07:00
Tim Crawford
84fe76cad4 avr: Fix compiling with GCC 12
Compiling the Arduino targets with GCC 12 fails with the following:

    error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]

Apply the workaround from the bug discussion to fix it.

Ref: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-13 12:10:49 -07:00
Tim Crawford
28882975e3 make: Ensure git hash is 7 characters
Specify abbrev so the version string is the same across systems with
different values for core.abbrev.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-13 12:01:49 -07:00
Tim Crawford
f46360fb45 make: Ensure main object file is first
Per the SDCC manual, the object that declares main must be passed first
to the linker. The resulting binary is identical, and this has not
caused a problem yet, so I'm unsure how "required" this is.

Ref: Section 3.2.3 Projects with Multiple Source Files
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-13 12:01:49 -07:00
Tim Crawford
7ebec4f7b1 make: Enable compiling asm files
Allow specifying asm files the same way C files are added:

    board-common-y += foo.asm

The file must use an `.asm` extension. The toolchain file filters the
sources to compile them into objects correctly, as the C compiler
doesn't handle asm files itself.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-13 12:01:49 -07:00
Tim Crawford
e032c5f0f2 Update .clang-format and apply
Update .clang-format for LLVM 14.0, available on Ubuntu 22.04.

There is still plenty that clang-format sucks at or does wrong, so
either add some more blocks to disable it, or just put up with it.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-10 12:02:21 -07:00
Tim Crawford
c3267fc4ad ci: Update to Ubuntu 22.04
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-10 12:02:21 -07:00
Tim Crawford
d687df482a Conditionally compile eSPI support
A board may use either the LPC bus or the eSPI bus. Only include eSPI
support for boards that use it.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-06 12:47:54 -07:00
Tim Crawford
5e884cf413 scratch: Use relative path for source
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2023-01-06 12:47:54 -07:00
Tim Crawford
a8e37276e9 tool: Disable default features of redox-hwio
Fixes using as a dependency in no-std environments.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-12-20 13:41:02 -07:00
Tim Crawford
1019878e3c tool: Update dependencies
clap is only updated to 3.2 instead of 4.0 because I didn't want to deal
with all the changes.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-11-30 08:39:16 -07:00
Ian Douglas Scott
cd28de382d Add a K_NONE define
Seems like this define might as well be included. It means `layouts.py`
doesn't need to handle it specially.
2022-11-29 09:20:41 -07:00
Ian Douglas Scott
004c7acf6c Remove scripts/layouts.sh
Superseded by `keyboard-configurator/layouts.py`.
2022-11-29 09:20:41 -07:00
Tim Crawford
2a8befc195 Enable WLAN at power_on() instead of board_init()
If the board is on AC power when powered off the EC will not reset, and
WLAN power will not be enabled on next boot. Move enabling WLAN from
`board_init()` to `power_on()`.

Fixes: be4659a0cb ("Set wireless power at init and power off")
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-11-18 19:11:01 -07:00
Tim Crawford
be4659a0cb Set wireless power at init and power off
Add a new wireless object for controlling WLAN power state. Change the
power sequence to enable WLAN at board init and disable it at power off.

Newer galp5 units sold to customers have an issue where they do not
fully power off. This is apparently somehow caused by `WLAN_PWR_EN`.

The unit received for development do not have this issue.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-11-18 07:32:18 -07:00
Tim Crawford
839abf7878 galp5: Remove BT_EN
BT is enabled PCH side by `PCH_BT_EN`. `BT_EN` is not connected.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-11-18 07:32:18 -07:00
Tim Crawford
861f1f2cc8 make: Add config for each ITE EC
EC_VARIANT is only used on AVR as a parameter to avrdude.

Replace its use on ITE with 2 choices:

- CONFIG_EC_ITE_IT8587E
- CONFIG_EC_ITE_IT5570E

Replace the EC defines with a matching define for the variable.
2022-11-17 14:19:39 -07:00
Tim Crawford
ac9631f948 make: Specify source files to include
Replace use of wildcard with list of source files to include. The `-y`
suffix is added, but has no significance since conditional compilation
has not been added yet.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-11-17 14:19:39 -07:00
Tim Crawford
ce66685c70 make: Move arch.mk to toolchain.mk
The arch.mk file contains variables/rules to build, so rename it. Leave
an empty arch.mk so it can still be used in a follow-up commit.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-11-17 14:19:39 -07:00
Jeremy Soller
c5b737f505 ESPI systems should always power off if in S5 state 2022-11-17 13:54:43 -07:00
Tim Crawford
edbb5b594a HACK: pmc: Apply hack for S0ix to all ADL boards
For some reason, *all* the ADL boards are now failing to enter S0ix.
Apply the PMC hack to the remaining boards.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-11-08 09:44:14 -07:00
13r0ck
be5d34dc0d Add other launch keyboards 2022-11-01 16:22:11 -06:00
Tim Crawford
d36fb62cd7 Replace makebin with objcopy
Replace custom SDCC tool with the more standard binutils tool.

scratch.rom and flash.rom are different (no unnecessary padding), but
resulting ec.rom is the same.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-10-28 15:01:45 -06:00
Tim Crawford
69f97fe149 Merge common EC directories
Split the EC define into base and variant. Merge the 3 ATmega chips as
atmega, and the 2 ITE chips as ite.

Tested that the generated files are identical.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-10-27 09:42:45 -06:00
Tim Crawford
01885609e8 HACK: pmc: Add hack to force S0ix entry on lemp11
lemp11 sometimes fails to reach C10 and gets stuck in C0 during s2idle.
For some reason, sending a PMC SCI allows the CPU to go to C10.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-10-17 18:36:35 -06:00
Tim Crawford
f8d1123934 pwm: Reload counters when they reach 0
Add IT5570E register that controls when the down counters are updated.
Set them to update when they reach 0, instead of immediately when DCRi
is written.

Fixes keyboard color changing when changing brightness levels if not
using 0xFF for an RGB value.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-10-14 08:38:34 -06:00
Tim Crawford
76019bdb61 Fix charger values, again (#303)
* common: Add macros for min, max, clamp

Simple macros, with no type checking.

Signed-off-by: Tim Crawford <tcrawford@system76.com>

* charger: Limit charger values to max valid value

Use the maximum valid value instead of discarding bits.

Fixes: 6295f60172 ("Fix smart charger values")

Signed-off-by: Tim Crawford <tcrawford@system76.com>

* charger/bq24780s: Fix charge current mask

bq24780s uses bit 12 for 4096 a current weight.

Fixes: 6295f60172 ("Fix smart charger values")

Signed-off-by: Tim Crawford <tcrawford@system76.com>

* oryp: Reduce charge current to 2A

Signed-off-by: Tim Crawford <tcrawford@system76.com>

* charger/bq24780s: Set RSENSE ratio option

Signed-off-by: Tim Crawford <tcrawford@system76.com>

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-10-06 13:02:15 -06:00
leviport
a32a3e3e95 Docs: update models that use 0.5mm pitch FPC cable (#302) 2022-09-15 11:42:12 -06:00
Tim Crawford
7f28764436 battery: Fix condition to start/stop charging
Change the condition, which is currently a level *at* which charging
will start/stop.

Per sysfs [1], these values are a level:

- *below* which charging will begin
- *above* which charging will stop

[1]: https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-09-02 11:22:56 -06:00
Tim Crawford
5cf57d69b9 gaze17: Define SLP_S0# to CPU_C10_GATE#
gaze17 does not connect SLP_S0# to the EC, so continue using
CPU_C10_GATE# for S0ix detection.

Fixes: 4b888ae9a501 ("board/system76/common: use SLP_S0# pin for modern standby detection")
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-08-30 08:47:30 -06:00
Michał Kopeć
cc3effb6a4 board/system76/common: use SLP_S0# pin for modern standby detection
Previously, CPU_C10_GATE# was used for detecting entry into s0ix /
Modern Standby.

Intel documentation says that SLP_S0# should be used for s0ix detection
instead, and CPU_C10_GATE# is intended for VCCSTG power gating, so
switch the pin to improve s0ix detection reliability.

Fixes https://github.com/system76/firmware-open/issues/199

References:

- Intel docs #575570 rev 0.5, #607872 rev 2.2
- Chromium EC: https://chromium.googlesource.com/chromiumos/platform/ec/+/master/power/intel_x86.c#41

Signed-off-by: Michał Kopeć <michal.kopec@3mdeb.com>
2022-08-30 08:47:30 -06:00
Tim Crawford
49abf83c08 Add config for using S0ix
S0ix does not require eSPI, and eSPI does not mandate S0ix.

Enable S0ix for:

- darp7 (TGL-U)
- darp8 (ADL-P)
- galp5 (TGL-U)
- galp6 (ADL-P)
- lemp10 (TGL-U)
- lemp11 (ADL-U)

It is also currently enabled on ADL-H due to a bug with S3:

- gaze17-3050
- gaze17-3060-b
- oryp9

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-08-30 08:47:30 -06:00
Tim Crawford
b78631e316 oryp10: Symlink to oryp9
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-08-26 11:38:49 -06:00
Tim Crawford
a8213311b1 galp6: Do not provide power while off
The previous commit incorrectly enabled power while off. Model PD_EN
after VA_EC_EN, which it replaced on galp6 for TCP0.

Fixes: a6a6c5fba4 ("galp6: Fix TCP0 power")
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-08-03 11:11:28 -06:00
Tim Crawford
a6a6c5fba4 galp6: Fix TCP0 power
galp6 uses `PD_EN` instead of `VA_EC_EN` for enabling power to TCP0.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-08-02 16:02:06 -06:00
Tim Crawford
cd86c1e7d7 galp6: Fix USB power
The schematics incorrectly show the pin as `USB_PWR_EN#`. There is a
comment on the port side clarifying that it is actually active high.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-08-02 16:02:06 -06:00
Tim Crawford
371f6d3047 galp6: Add Galago Pro 6
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-08-01 19:26:36 -06:00
Tim Crawford
6295f60172 Fix smart charger values
Fix all smart charger values by having boards provide the RSENSE values
and perform the register calculations in the code.

The galp3-c, galp5, gaze16, and gaze17 do not seem to have the same
behavior as the rest of the boards, and further investigation is needed.
In the mean time, reduce their charge current values to preserve current
behavior.

Ref: OZ26786-DS v1.0
Ref: bq24780S Rev. C datasheet
Signed-off-by: Tim Crawford <tcrawford@system76.com
2022-08-01 19:26:36 -06:00
Tim Crawford
20d40f3477 gaze17-3050: Adjust fan points
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-07-26 09:27:44 -06:00
Tim Crawford
22fa2769ad gaze17-3050: Update configs
- Add to CI
- Correct smart charger values
- Enable WLAN power
- Enable USB power
- Disable mute

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-07-26 09:27:44 -06:00
Tim Crawford
7ab91e9f1d oryp9: Sync fans
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-07-20 14:20:31 -06:00
Tim Crawford
5ef477ab5b ci: Add darp8 and lemp11
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-07-12 15:31:35 -06:00
Tim Crawford
e8d91e5c2d oryp9: Add Oryx Pro 9
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2022-07-12 15:31:35 -06:00
342 changed files with 13250 additions and 4183 deletions

View File

@@ -1,133 +0,0 @@
# https://releases.llvm.org/10.0.0/tools/clang/docs/ClangFormatStyleOptions.html
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignConsecutiveMacros: true
AlignEscapedNewlines: DontAlign
AlignOperands: true
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakAfterJavaFieldAnnotations: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
BreakStringLiterals: false
ColumnLimit: 96
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DeriveLineEnding: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: true
FixNamespaceComments: false
ForEachMacros:
- foreach
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentGotoLabels: false
IndentPPDirectives: BeforeHash
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 10
PenaltyBreakBeforeFirstCallParameter: 10
PenaltyBreakComment: 100
PenaltyBreakFirstLessLess: 5
PenaltyBreakString: 100
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 5
PenaltyReturnTypeOnItsOwnLine: 100
PointerAlignment: Middle
ReflowComments: false
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Latest
StatementMacros:
- ARRAY_SIZE
- xstr
TabWidth: 4
UseCRLF: false
UseTab: Never
...

View File

@@ -6,17 +6,27 @@ on:
jobs:
lint:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
outputs:
boards: ${{ steps.board-matrix.outputs.boards }}
steps:
- uses: actions/checkout@v2
- name: Check SPDX identifiers
run: ./scripts/lint/spdx.sh
- name: Check indentation
run: ./scripts/lint/indent.sh
- uses: actions/checkout@v4
- name: Install dependencies
run: ./scripts/deps.sh
- name: Check SPDX tags
run: ./scripts/lint/01-spdx-tags.sh
- name: Check formatting
run: ./scripts/clang-format.sh
continue-on-error: true
run: ./scripts/lint/02-uncrustify.sh
- name: Check shell scripts
run: ./scripts/lint/03-shellcheck.sh
- name: Generate board matrix
id: board-matrix
run: echo "boards=$(make list-boards | jq -sRc 'split("\n")[:-1]')" >> $GITHUB_OUTPUT
tool:
strategy:
@@ -25,9 +35,9 @@ jobs:
- features:
- features: --no-default-features --features="redox_hwio"
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install dependencies
run: ./scripts/deps.sh
@@ -36,54 +46,22 @@ jobs:
run: cargo build ${{ matrix.features }} --release --manifest-path tool/Cargo.toml
ec:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
needs: lint
strategy:
matrix:
# TODO: Generate matrix from directory?
boards: ${{ fromJson(needs.lint.outputs.boards) }}
# TODO: Conditionally build based on files changed?
include:
- vendor: arduino
board: mega2560
- vendor: system76
board: addw1
- vendor: system76
board: addw2
- vendor: system76
board: bonw14
- vendor: system76
board: darp5
- vendor: system76
board: darp7
- vendor: system76
board: galp3-c
- vendor: system76
board: galp5
- vendor: system76
board: gaze15
- vendor: system76
board: gaze16-3050
- vendor: system76
board: gaze16-3060
- vendor: system76
board: gaze17-3060-b
- vendor: system76
board: lemp9
- vendor: system76
board: lemp10
- vendor: system76
board: oryp5
- vendor: system76
board: oryp6
- vendor: system76
board: oryp7
- vendor: system76
board: oryp8
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install dependencies
run: ./scripts/deps.sh
- name: Build firmware
run: make BOARD=${{ matrix.vendor}}/${{ matrix.board }}
run: make BOARD=${{ matrix.boards }} VERBOSE=1
- name: Show memory layout
run: cat build/ec.mem
continue-on-error: true

156
.uncrustify.cfg Normal file
View File

@@ -0,0 +1,156 @@
# SPDX-License-Identifier: CC0-1.0
# SPDX-FileCopyrightText: NONE
# Uncrustify-0.78.1_f
# https://github.com/uncrustify/uncrustify/blob/uncrustify-0.78.1/documentation/htdocs/config.txt
newlines = lf
input_tab_size = 4
output_tab_size = 4
disable_processing_cmt = "uncrustify:off"
enable_processing_cmt = "uncrustify:on"
utf8_bom = remove
sp_arith_additive = force
sp_assign = force
sp_enum_brace = force
sp_enum_after_assign = force
sp_pp_concat = ignore
sp_bool = force
sp_compare = force
sp_inside_paren = remove
sp_paren_paren = remove
sp_cparen_oparen = remove
sp_paren_brace = force
sp_before_ptr_star = force
sp_between_ptr_star = remove
sp_between_ptr_ref = remove
sp_after_ptr_star = remove
sp_after_type = ignore # XXX: Fixes using macros in assignments
sp_before_sparen = force
sp_inside_sparen = remove
sp_inside_for = remove
sp_sparen_paren = remove
sp_sparen_brace = force
sp_do_brace_open = force
sp_brace_close_while = force
sp_before_semi_for = remove
sp_before_semi_for_empty = remove
sp_between_semi_for_empty = remove
sp_after_semi_for_empty = remove
sp_before_square = remove
sp_before_squares = remove
sp_inside_square = remove
sp_after_comma = add
sp_after_cast = remove
sp_inside_paren_cast = remove
sp_sizeof_paren = remove
sp_inside_braces = add
sp_inside_braces_empty = remove
sp_func_proto_paren = remove
sp_func_def_paren = remove
sp_inside_fparens = remove
sp_inside_fparen = remove
sp_inside_tparen = remove
sp_after_tparen_close = remove
sp_fparen_brace = force
sp_func_call_paren = remove
sp_return_paren = force
sp_attribute_paren = remove
sp_defined_paren = remove
sp_else_brace = force
sp_brace_else = force
sp_brace_typedef = force
sp_before_nl_cont = force
sp_cond_colon = force
sp_cond_question = force
sp_endif_cmt = force
sp_before_tr_cmt = add
sp_num_before_tr_cmt = 1
indent_columns = 4
indent_with_tabs = 0
indent_macro_brace = false
indent_ignore_label = true
indent_paren_close = 2
indent_align_assign = false
indent_align_paren = false
indent_compound_literal_return = false
nl_collapse_empty_body = true
nl_collapse_empty_body_functions = true
nl_start_of_file = remove
nl_end_of_file = force
nl_end_of_file_min = 1
nl_assign_brace = remove
nl_fcall_brace = remove
nl_enum_brace = remove
nl_struct_brace = remove
nl_union_brace = remove
nl_if_brace = remove
nl_brace_else = remove
nl_else_brace = remove
nl_else_if = remove
nl_for_brace = remove
nl_while_brace = remove
nl_do_brace = remove
nl_brace_while = remove
nl_switch_brace = remove
nl_after_case = true
nl_enum_own_lines = force
nl_func_type_name = remove
nl_func_proto_type_name = remove
nl_func_paren = remove
nl_func_def_paren = remove
nl_func_call_paren = remove
nl_fdef_brace = remove
nl_return_expr = remove
nl_after_semicolon = true
nl_brace_struct_var = remove
nl_ds_struct_enum_close_brace = true
nl_split_if_one_liner = true
nl_split_for_one_liner = true
nl_split_while_one_liner = true
nl_max = 2
eat_blanks_after_open_brace = true
eat_blanks_before_close_brace = true
code_width = 100
ls_for_split_full = true
ls_func_split_full = true
align_on_tabstop = true
align_var_def_star_style = 1
align_var_def_amp_style = 1
align_typedef_star_style = 1
align_typedef_amp_style = 1
align_func_proto_star_style = 1
align_func_proto_amp_style = 1
align_pp_define_together = true
cmt_width = 100
cmt_convert_tab_to_spaces = true
cmt_trailing_single_line_c_to_cpp = true
mod_paren_on_return = remove
mod_remove_extra_semicolon = true
mod_remove_duplicate_include = true
mod_sort_incl_import_prioritize_filename = true
mod_move_case_break = true
mod_move_case_return = true
mod_remove_empty_return = true
mod_enum_last_comma = add
pp_multiline_define_body_indent = 4
pp_indent_case = false
pp_indent_func_def = false
pp_indent_extern = false
#set QUALIFIER __at # XXX: Allow it to be treated as a function call
set QUALIFIER __code
set QUALIFIER __critical
set QUALIFIER __data
set QUALIFIER __idata
set QUALIFIER __pdata
set QUALIFIER __reentrant
set QUALIFIER __xdata
set TYPE __bit
set TYPE __sbit
set TYPE __sfr
set TYPE __sfr16
set TYPE __sfr32
set FUNC_CALL __asm__

View File

@@ -2,60 +2,102 @@
-include config.mk
# Disable built-in rules and variables
MAKEFLAGS += -rR
# Default to silent builds
ifneq ($(VERBOSE),1)
MAKEFLAGS += -s
endif
# Set build directory
BUILD = build
# Parameter for current board
ifeq ($(BOARD),)
all:
@echo "Please set BOARD to one of the following:"
@cd src/board && for board in */*/board.mk; do \
echo " $$(dirname "$$board")"; \
done
@exit 1
$(error BOARD must be specified)
else
# Calculate version
DATE=$(shell git show --format="%cd" --date="format:%Y-%m-%d" --no-patch)
REV=$(shell git describe --always --dirty)
DATE=$(shell git show --format="%cs" --no-patch --no-show-signature)
REV=$(shell git describe --abbrev=7 --always --dirty)
VERSION?=$(DATE)_$(REV)
# Set build directory
BUILD=build/$(BOARD)/$(VERSION)
# Default target - build the board's EC firmware
all: $(BUILD)/ec.rom
$(info Built '$(VERSION)' for '$(BOARD)')
$(info Built $(VERSION) for $(BOARD))
# Include common source
COMMON_DIR=src/common
SRC=$(wildcard $(COMMON_DIR)/*.c)
INCLUDE=$(wildcard $(COMMON_DIR)/include/common/*.h) $(COMMON_DIR)/common.mk
INCLUDE += $(COMMON_DIR)/common.mk
CFLAGS=-I$(COMMON_DIR)/include -D__FIRMWARE_VERSION__=$(VERSION)
include $(COMMON_DIR)/common.mk
SRC += $(foreach src, $(common-y), $(COMMON_DIR)/$(src))
# Include the board's source
BOARD_DIR=src/board/$(BOARD)
SRC+=$(wildcard $(BOARD_DIR)/*.c)
INCLUDE+=$(wildcard $(BOARD_DIR)/include/board/*.h) $(BOARD_DIR)/board.mk
INCLUDE += $(BOARD_DIR)/board.mk
CFLAGS+=-I$(BOARD_DIR)/include -D__BOARD__=$(BOARD)
include $(BOARD_DIR)/board.mk
SRC += $(foreach src, $(board-y), $(BOARD_DIR)/$(src))
SRC += $(foreach src, $(board-common-y), $(SYSTEM76_COMMON_DIR)/$(src))
SRC += $(foreach src, $(keyboard-y), $(KEYBOARD_DIR)/$(src))
# The board will define the embedded controller
# Include the embedded controller's source
EC_DIR=src/ec/$(EC)
SRC+=$(wildcard $(EC_DIR)/*.c)
INCLUDE+=$(wildcard $(EC_DIR)/include/ec/*.h) $(EC_DIR)/ec.mk
CFLAGS+=-I$(EC_DIR)/include -D__EC__=$(EC) -D$(EC)
INCLUDE += $(EC_DIR)/ec.mk
CFLAGS+=-I$(EC_DIR)/include
include $(EC_DIR)/ec.mk
SRC += $(foreach src, $(ec-y), $(EC_DIR)/$(src))
# The EC will define the architecture
# Include the architecture's source
ARCH_DIR=src/arch/$(ARCH)
SRC+=$(wildcard $(ARCH_DIR)/*.c)
INCLUDE+=$(wildcard $(ARCH_DIR)/include/arch/*.h) $(ARCH_DIR)/arch.mk
INCLUDE += $(ARCH_DIR)/arch.mk
CFLAGS+=-I$(ARCH_DIR)/include -D__ARCH__=$(ARCH)
include $(ARCH_DIR)/arch.mk
SRC += $(foreach src, $(arch-y), $(ARCH_DIR)/$(src))
include $(ARCH_DIR)/toolchain.mk
# The architecture defines build targets, no more is required
endif
# Target to remove build artifacts
.PHONY: docs
docs:
mdbook build docs/
.PHONY: clean
clean:
rm -rf build
rm -rf $(BUILD)
.PHONY: fmt
fmt:
uncrustify -c .uncrustify.cfg -q --no-backup $(shell git ls-files '*.c' '*.h')
.PHONY: lint
lint:
./scripts/lint/lint.sh
.PHONY: list-boards
list-boards:
@cd src/board && for board in */*/board.mk; do \
echo "$$(dirname "$$board")"; \
done
# This target is run during setup, and is not shown in the help text.
.PHONY: git-config
git-config:
$(eval HOOKS = "$(shell git rev-parse --git-dir)/hooks")
ln -sfrv scripts/hooks/pre-commit.sh "$(HOOKS)/pre-commit"
.PHONY: help
help:
@echo "System76 EC build targets"
@echo " [all] BOARD=<B> Build the specified board"
@echo " list-boards List available target boards"
@echo " clean Remove build artifacts"
@echo " fmt Format the source code"
@echo " lint Run lint checks"
@echo " help Print this message"

View File

@@ -5,12 +5,12 @@ laptops.
## Documentation
- [Supported embedded controllers](./doc/controllers.md)
- [Flashing firmware](./doc/flashing.md)
- [Debugging](./doc/debugging.md)
- [Creating a custom keyboard layout](./doc/keyboard-layout-customization.md)
- [Development environment](./doc/dev-env.md)
- [Adding a new board](./doc/adding-a-new-board.md)
- [Supported embedded controllers](./docs/controllers.md)
- [Flashing firmware](./docs/flashing.md)
- [Debugging](./docs/debugging.md)
- [Creating a custom keyboard layout](./docs/keyboard-layout-customization.md)
- [Development environment](./docs/dev-env.md)
- [Adding a new board](./docs/adding-a-new-board.md)
## Quickstart
@@ -34,7 +34,7 @@ Then build the firmware for your laptop model.
make BOARD=system76/<model>
```
See [Flashing](./doc/flashing.md) for how to use the new firmware image.
See [Flashing](./docs/flashing.md) for how to use the new firmware image.
## Releases

10
docs/SUMMARY.md Normal file
View File

@@ -0,0 +1,10 @@
# Summary
- [Index](./index.md)
- [Development environment](./dev-env.md)
- [Adding a new board](./adding-a-new-board.md)
- [Supported controllers](./controllers.md)
- [Debugging](./debugging.md)
- [Flashing](./flashing.md)
- [Custom keyboard layouts](./keyboard-layout-customization.md)
- [Mega2560](./mega2560.md)

View File

@@ -2,7 +2,9 @@
## Charger parameters
- `CHARGER_CHARGE_CURRENT`: Currently the same for all boards (1536).
- `CHARGER_ADAPTER_RSENSE`: The adapter RSENSE value in milliohms.
- `CHARGER_BATTERY_RSENSE`: The battery RSENSE value in milliohms.
- `CHARGER_CHARGE_CURRENT`: The desired charge current in milliamps.
- `CHARGER_CHARGE_VOLTAGE`: On the battery, look for 充电限制电压 (charge limit
voltage). Convert this from volts to millivolts.
- `CHARGER_INPUT_CURRENT`: On the charger, look for DC output. Convert the
@@ -10,23 +12,28 @@
#### Example
The gaze15 battery has
The gaze15 battery has:
```
充电限制电压: 16.8Vdc
```
and its charger has
Its charger has:
```
DC OUTPUT (输出/輸出): 19.5V⎓9.23A 180W
```
This gives
The schematics show it uses a 0.005 ohm sense resistor for both the adapter and
the battery.
This gives:
```
CFLAGS+=\
-DCHARGER_CHARGE_CURRENT=1536 \
-DCHARGER_ADAPTER_RSENSE=5 \
-DCHARGER_BATTERY_RSENSE=5 \
-DCHARGER_CHARGE_CURRENT=3072 \
-DCHARGER_CHARGE_VOLTAGE=16800 \
-DCHARGER_INPUT_CURRENT=9230
```

20
docs/book.toml Normal file
View File

@@ -0,0 +1,20 @@
# SPDX-License-Identifier: GPL-3.0-only
[book]
title = "System76 EC"
description = "System76 EC documentation"
language = "en"
src = "."
[build]
build-dir = "../build/docs"
create-missing = false
[output.html]
default-theme = "rust"
preferred-dark-theme = "coal"
no-section-label = true
git-repository-url = "https://github.com/system76/ec"
[output.html.print]
enable = false

View File

@@ -5,7 +5,25 @@ Terms used:
- *host*: The system that will have all devices connected to it and
will receive the EC logs
## Parallel port
## Debugging with target device
1. Install dependencies
```bash
./scripts/deps.sh
```
1. Start the console
```bash
make BOARD=system76/<model> console_internal
```
1. If you're not seeing seeing expected output, check the
[`LEVEL` cflag][level_cflag]. This is an EC compile time configuration and
changing will require a build and flash of the EC.
[level_cflag]: https://github.com/system76/ec/blob/01907011bb63/src/board/system76/common/common.mk#L31-L39
## Debugging with external device
### Parallel port
This method replaces the keyboard with a device used for debug logging.
An alternate method of interacting with the target is needed; e.g., an
@@ -20,7 +38,7 @@ Requirements:
For details on configuring the Mega 2560 and breakout board, see
[mega2560](./mega2560.md).
### Setup
#### Setup
1. Enable parallel port debugging in the EC firmware
- Uncomment `PARALLEL_DEBUG` in `src/board/system76/common/common.mk`
@@ -46,12 +64,12 @@ To return the Mega 2560 to host mode, reset the device.
If logs are corrupted, try power cycling the Mega or reseating the cable.
## I2C connection
### I2C connection
**Failure to follow steps in order, or performing steps on an
unsupported board, may result in damaged board components.**
### Wiring the target
#### Wiring the target
The I2C connection is made through the battery pins. Find the pins marked
`SMC_BAT` (clock) and `SMD_BAT` (data) in the service manual.
@@ -86,7 +104,7 @@ oryp7 | 6 | 5
9. Reconnect battery
10. Replace bottom panel
### Setup
#### Setup
Requirements:
- Target wired for EC debugging

View File

@@ -1,11 +1,27 @@
# Flashing firmware
## UEFI application
The `flash.sh` script from the top-level firmware-open project will use
firmware-update, the UEFI application which is used for normal system updates.
This will flash both the SBIOS and the EC after building the firmware. To
flash just the EC, delete the built `firmware.rom` before running `flash.sh`.
## Internal programmer
Use this method for flashing a system already running System76 EC.
This will trigger a watchdog reset causing the system to **immediately power
off**. OS data may be lost or corrupted as a result. Save and close all
This method will only work if the running firmware is not locked. Firmware is
write locked if it was built with `CONFIG_SECURITY=y`. The firmware can be
unlocked using ectool for a single boot:
```
./scripts/ectool.sh security unlock
```
This method will trigger a watchdog reset causing the system to **immediately
power off**. OS data may be lost or corrupted as a result. Save and close all
applications before flashing.
```

View File

@@ -104,10 +104,6 @@ make
See [flashing firmware](./flashing.md) for details.
```sh
make flash_internal
```
Do not use the keyboard or touchpad while it is flashing.
The system will power off as part of the flash process. Turn it back on after

View File

@@ -18,7 +18,7 @@ it uses the ATmega16U2, find a different model.
A flexible printed circuit (FPC) breakout board is required. It should have:
- 24 pins with 0.1" (2.54mm) pitch
- One side with 0.5mm pitch FPC connector (for the Lemur Pro)
- One side with 0.5mm pitch FPC connector (for lemp9, lemp10, lemp11, galp5, and galp6)
- One side with 1.0mm pitch FPC connector (for all other models)
Depending on the vendor, the connectors may not come soldered to the board (or

13
docs/security.md Normal file
View File

@@ -0,0 +1,13 @@
# Firmware security
The firmware security feature can be configured by setting `CONFIG_SECURITY=1`
in the `src/board/system76/[board]/board.mk` file. This feature prevents
programming the EC firmware at runtime, unless the EC is unlocked with the
`system76-ectool security unlock` command. After this, on the next reboot, the
EC will respond to the SPI and reset commands. On boards where the `ME_WE` GPIO
exists, it will be set high when the EC security state is unlocked.
Other firmware components can use this state to perform their own locking and
unlocking primitives. For example, in `coreboot`, flash regions may be locked
when the EC security state is locked. In `EDK2`, a physical presence dialog may
be shown when the EC security state is unlocked.

2
ecspy

Submodule ecspy updated: 3ff52b2348...f0bf26d577

View File

@@ -1,3 +1,4 @@
[toolchain]
channel = "nightly-2022-03-18"
components = ["rust-src"]
channel = "nightly-2024-05-11"
components = ["clippy", "rustfmt"]
profile = "minimal"

View File

@@ -1,16 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
FILES=($(git ls-files '*.[ch]'))
FMT_OPTS=(
"-style=file"
"--fallback-style=none"
"--Werror"
)
if [[ "$1" = "apply" ]]; then
clang-format "${FMT_OPTS[@]}" -i "${FILES[@]}"
else
clang-format "${FMT_OPTS[@]}" --dry-run "${FILES[@]}"
fi

View File

@@ -19,7 +19,6 @@ if [[ "${ID}" =~ "debian" ]] || [[ "${ID_LIKE}" =~ "debian" ]]; then
--yes \
avr-libc \
avrdude \
clang-format \
curl \
gcc \
gcc-avr \
@@ -29,6 +28,8 @@ if [[ "${ID}" =~ "debian" ]] || [[ "${ID_LIKE}" =~ "debian" ]]; then
make \
pkgconf \
sdcc \
shellcheck \
uncrustify \
xxd
elif [[ "${ID}" =~ "fedora" ]] || [[ "${ID_LIKE}" =~ "fedora" ]]; then
sudo dnf install \
@@ -36,12 +37,13 @@ elif [[ "${ID}" =~ "fedora" ]] || [[ "${ID_LIKE}" =~ "fedora" ]]; then
avr-gcc \
avr-libc \
avrdude \
clang-tools-extra \
curl \
gcc \
make \
sdcc \
ShellCheck \
systemd-devel \
uncrustify \
vim-common
elif [[ "${ID}" =~ "arch" ]] || [[ "${ID_LIKE}" =~ "arch" ]]; then
sudo pacman -S \
@@ -49,13 +51,14 @@ elif [[ "${ID}" =~ "arch" ]] || [[ "${ID_LIKE}" =~ "arch" ]]; then
avr-gcc \
avr-libc \
avrdude \
clang \
curl \
gcc \
make \
pkgconf \
sdcc \
shellcheck \
systemd-libs \
uncrustify \
vim
else
msg "Please add support for your distribution to:"
@@ -66,11 +69,11 @@ fi
msg "Initializing submodules"
git submodule update --init --recursive
msg "Installing git hooks"
make git-config
RUSTUP_NEW_INSTALL=0
if which rustup &> /dev/null; then
msg "Updating rustup"
rustup self update
else
if ! command -v rustup >/dev/null 2>&1; then
RUSTUP_NEW_INSTALL=1
msg "Installing Rust"
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \

View File

@@ -2,5 +2,5 @@
# SPDX-License-Identifier: GPL-3.0-only
set -e
cargo build --release --manifest-path tool/Cargo.toml
cargo build --release --quiet --manifest-path tool/Cargo.toml
sudo tool/target/release/system76_ectool "$@"

7
scripts/hooks/pre-commit.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
make lint 2>/dev/null || {
echo -e "\nissues found, not committing"
exit 1
}

View File

@@ -1,65 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
# This script produces layout data for the System76 Keyboard Configurator
set -e
rm -rf build/layouts
mkdir -p build/layouts
D="$(realpath build/layouts)"
binary="$D/keymap"
source="$binary.c"
header="src/common/include/common/keymap.h"
echo "#include <stdio.h>" > "$source"
echo "#include \"$header\"" >> "$source"
echo "int main(int argc, char **argv) {" >> "$source"
grep '^#define \(K_\|KT_FN\)' "$header" \
| cut -d ' ' -f2 \
| while read keycode
do
name="$(echo "$keycode" | cut -d '_' -f2-)"
echo "printf(\"${name},0x%04X\\n\", $keycode);" >> "$source"
done
echo "return 0;" >> "$source"
echo "}" >> "$source"
gcc -I. "$source" -o "$binary"
"$binary" | tee "$D/keymap.csv"
cd src/board
for board in */*
do
file="$board/include/board/keymap.h"
if [ ! -e "$file" ]
then
continue
fi
echo "# $board"
mkdir -p "$D/$board"
cp "$D/keymap.csv" "$D/$board"
row=0
rg \
--multiline \
--multiline-dotall \
--regexp '#define LAYOUT\(.*\) \{.*\}' \
"$file" \
| grep --only-matching '\{.*\}' \
| sed 's/^{ //' \
| sed 's/ }$//' \
| sed 's/, / /g' \
| while read line
do
col=0
for word in $line
do
if [ "$word" != "___" ]
then
echo "$word,$row,$col"
fi
col=$(expr $col + 1)
done
row=$(expr $row + 1)
done \
| sort -n \
| tee "$D/${board}/layout.csv"
done

52
scripts/lint/01-spdx-tags.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
# Check that all files have a SPDX license identifier
# TODO: Validate license tags against a whitelist
LINT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
. "$LINT_DIR/util.sh"
echo -n "Checking for SPDX tags..."
EXCLUDES=(
# Ignore license files
':!:LICENSE'
':!:**/LICENSE'
# Ignore cargo files
':!:**/Cargo.lock'
':!:**/Cargo.toml'
':!:rust-toolchain.toml'
# Ignore text files
':!:*.md'
':!:*.txt'
# Ignore dotfiles
':!:\.*'
':!:**/\.*'
)
needs_tag=()
for file in $(git ls-files "${EXCLUDES[@]}"); do
# Only check regular files
if [[ ! -f "$file" ]]; then
continue
fi
# SPDX must appear at head of file
if ! head "$file" | grep -q 'SPDX-License-Identifier:'; then
needs_tag+=("$file")
fi
done
if [[ "${#needs_tag[@]}" != "0" ]]; then
failed
for file in "${needs_tag[@]}"; do
echo "- $file"
done
exit 1
fi
passed

36
scripts/lint/02-uncrustify.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
# Check if any C files or headers need to be formatted.
# shellcheck disable=SC1091
LINT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
. "$LINT_DIR/util.sh"
echo -n "Checking C style..."
if ! command -v uncrustify > /dev/null; then
skipped "uncrustify not found"
exit 0
fi
needs_formatting=()
for file in $(git ls-files '*.c' '*.h'); do
if ! uncrustify -c .uncrustify.cfg -q --check "$file" >/dev/null 2>&1; then
needs_formatting+=("$file")
fi
done
if [[ "${#needs_formatting[@]}" != "0" ]]; then
failed
for file in "${needs_formatting[@]}"; do
echo "- $file"
done
exit 1
fi
passed

36
scripts/lint/03-shellcheck.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
# Check if any shell scripts have issues.
LINT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
. "$LINT_DIR/util.sh"
echo -n "Checking shell scripts..."
if ! command -v shellcheck > /dev/null; then
skipped "shellcheck not found"
exit 0
fi
readarray -t FILES < <(git ls-files '*.sh')
needs_formatting=()
for file in "${FILES[@]}"; do
# SC1091: Ignore external scripts
if ! shellcheck -f quiet --exclude=SC1091 "$file"; then
needs_formatting+=("$file")
fi
done
if [[ "${#needs_formatting[@]}" != "0" ]]; then
failed
for file in "${needs_formatting[@]}"; do
echo "- $file"
done
exit 1
fi
passed

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
# Check files do not use tabs for indentation
git ls-files '*.[c\|h\|rs\|sh]' | xargs grep --line-number $'^\s*\t' && exit 1
exit 0

14
scripts/lint/lint.sh Executable file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
# Run all lints.
LINT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
LINTS=$(find "$LINT_DIR" -type f -name "[0-9][0-9]-*" | sort)
FAILED=0
for lint in $LINTS; do
$lint || FAILED=1
done
[[ "$FAILED" = "0" ]] || exit 1

View File

@@ -1,35 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
# Check that all files have a SPDX license identifier
set -e
# File patterns to check
FILE_TYPES=(
'*.c'
'*.h'
'*.mk'
'*.rs'
'*.sh'
'Makefile'
)
ret=0
for ft in "${FILE_TYPES[@]}"; do
files=$(git ls-files "$ft")
for f in ${files}; do
# Skip empty files
if [[ "$(wc -l < "$f")" = "0" ]]; then
continue
fi
# SPDX must appear at head of file
if ! head "$f" | grep -q 'SPDX-License-Identifier:'; then
echo "$f: Missing SPDX identifier"
ret=1
fi
done
done
exit ${ret}

15
scripts/lint/util.sh Normal file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
passed() {
echo -e "\x1B[32mPASSED\x1B[0m"
}
skipped() {
local reason=$1
echo -e "\x1B[33mSKIPPED\x1B[0m ($reason)"
}
failed() {
echo -e "\x1B[31mFAILED\x1B[0m"
}

View File

@@ -60,7 +60,7 @@ do
else
F="$(date "+%T")"
last_E="$(sudo cat /sys/class/powercap/intel-rapl\:0/energy_uj)"
last_E="$(sudo cat '/sys/class/powercap/intel-rapl:0/energy_uj')"
sleep 1
if [ "${has_bat}" == "1" ]
@@ -73,15 +73,15 @@ do
F="${F}\t$(printf "%.2f" "${bat_W}")"
fi
E="$(sudo cat /sys/class/powercap/intel-rapl\:0/energy_uj)"
E="$(sudo cat '/sys/class/powercap/intel-rapl:0/energy_uj')"
W="$(echo "(${E} - ${last_E})/1000000" | bc -lq)"
F="${F}\t$(printf "%.1f" "${W}")"
PL1_uW="$(sudo cat /sys/class/powercap/intel-rapl\:0/constraint_0_power_limit_uw)"
PL1_uW="$(sudo cat '/sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw')"
PL1_W="$(echo "${PL1_uW}/1000000" | bc -lq)"
F="${F}\t$(printf "%.1f" "${PL1_W}")"
PL2_uW="$(sudo cat /sys/class/powercap/intel-rapl\:0/constraint_1_power_limit_uw)"
PL2_uW="$(sudo cat '/sys/class/powercap/intel-rapl:0/constraint_1_power_limit_uw')"
PL2_W="$(echo "${PL2_uW}/1000000" | bc -lq)"
F="${F}\t$(printf "%.1f" "${PL2_W}")"

View File

@@ -1,27 +1,5 @@
# SPDX-License-Identifier: GPL-3.0-only
CC=sdcc -mmcs51 --model-large --code-size $(CODE_SIZE) --xram-size $(SRAM_SIZE) --Werror
OBJ=$(sort $(patsubst src/%.c,$(BUILD)/%.rel,$(SRC)))
# Run EC rom in simulator
sim: $(BUILD)/ec.rom
cargo run \
--release \
--manifest-path ecsim/Cargo.toml \
--no-default-features \
-- $<
# Convert from Intel Hex file to binary file
$(BUILD)/ec.rom: $(BUILD)/ec.ihx
@mkdir -p $(@D)
makebin -s $(CODE_SIZE) -p < $< > $@
# Link object files into Intel Hex file
$(BUILD)/ec.ihx: $(OBJ)
@mkdir -p $(@D)
$(CC) $(LDFLAGS) -o $@ $^
# Compile C files into object files
$(OBJ): $(BUILD)/%.rel: src/%.c $(INCLUDE)
@mkdir -p $(@D)
$(CC) $(CFLAGS) -o $@ -c $<
arch-y += arch.c
arch-y += delay.c
arch-y += time.c

View File

@@ -9,13 +9,11 @@ void delay_ticks(uint16_t ticks);
// 1 us * 9.2 MHz / 12 is 69/90
// Warning: this will round to the nearest tick
#define delay_us(X) \
delay_ticks((uint16_t)((((uint32_t)(X)) * 69UL + 89UL) / 90UL));
#define delay_us(X) delay_ticks((uint16_t)((((uint32_t)(X)) * 69UL + 89UL) / 90UL));
// 1 ns * 9.2 MHz / 12 is 69/90000
// Warning: this will round to the nearest tick
#define delay_ns(X) \
delay_ticks((uint16_t)((((uint32_t)(X)) * 69UL + 89999UL) / 90000UL));
#define delay_ns(X) delay_ticks((uint16_t)((((uint32_t)(X)) * 69UL + 89999UL) / 90000UL));
void delay_ms(uint8_t ms);

View File

@@ -5,7 +5,9 @@
#include <stdint.h>
typedef uint16_t systick_t;
void time_init(void);
uint32_t time_get(void);
systick_t time_get(void);
#endif // _ARCH_TIME_H

View File

@@ -3,23 +3,34 @@
// Uses timer 0 to keep track of global time
#include <8051.h>
#include <arch/time.h>
static volatile uint32_t time_overflows = 0;
#define OSC_DIVISOR 12
#define TICK_INTERVAL_MS 1
// Value to reload into the timer when the overflow interrupt is triggered.
#define TIMER_RELOAD (0xFFFF - (TICK_INTERVAL_MS * (CONFIG_CLOCK_FREQ_KHZ / OSC_DIVISOR)))
static volatile systick_t time_overflows = 0;
void timer_0(void) __interrupt(1) {
// Hardware automatically clears the the interrupt
// Stop timer
TR0 = 0;
time_overflows++;
// Start timer
TH0 = 0xFD;
TL0 = 0x01;
// Reload the values
TH0 = TIMER_RELOAD >> 8;
TL0 = TIMER_RELOAD & 0xFF;
// Restart the timer
TR0 = 1;
}
/**
* Set up Timer 0 as the system tick.
*/
void time_init(void) __critical {
// Stop the timer
TR0 = 0;
@@ -27,17 +38,20 @@ void time_init(void) __critical {
time_overflows = 0;
// Enable timer interrupts
// Enable the interrupt
ET0 = 1;
// Start timer in mode 1
// (65536 - 64769) / (9.2 MHz / 12) = ~1 ms interval
// Set the timer to mode 1 (16-bit timer)
TMOD = (TMOD & 0xF0) | 0x01;
TH0 = 0xFD;
TL0 = 0x01;
// Set the initial values
TH0 = TIMER_RELOAD >> 8;
TL0 = TIMER_RELOAD & 0xFF;
// Start the timer
TR0 = 1;
}
uint32_t time_get(void) __critical {
systick_t time_get(void) __critical {
return time_overflows;
}

View File

@@ -0,0 +1,58 @@
# SPDX-License-Identifier: GPL-3.0-only
CC = sdcc -mmcs51 -MMD --model-large --code-size $(CODE_SIZE) --xram-size $(SRAM_SIZE) --Werror
AS = sdas8051
ASFLAGS = -plosgff
# XXX: SDCC "requires" main() to be in the first item passed to the linker.
# Ref: SDCC Manual 4.2.8; Section 3.2.3 Projects with Multiple Source Files
MAIN_SRC = $(filter %/main.c, $(SRC))
MAIN_OBJ = $(sort $(patsubst src/%.c, $(BUILD)/%.rel, $(MAIN_SRC)))
# NOTE: sdas *must* be used for assembly files as sdcc cannot compile them
# itself. They must use an extension of `.asm` so they can be filtered here.
ASM_SRC = $(filter %.asm, $(SRC))
ASM_OBJ = $(sort $(patsubst src/%.asm, $(BUILD)/%.rel, $(ASM_SRC)))
C_SRC = $(filter %.c, $(SRC))
C_OBJ = $(sort $(patsubst src/%.c, $(BUILD)/%.rel, $(C_SRC)))
OBJ = $(MAIN_OBJ) $(sort $(ASM_OBJ) $(C_OBJ))
# Run EC rom in simulator
sim: $(BUILD)/ec.rom
cargo run \
--release \
--manifest-path ecsim/Cargo.toml \
--no-default-features \
-- $<
# Convert from Intel Hex file to binary file
$(BUILD)/ec.rom: $(BUILD)/ec.ihx
@echo " OBJCOPY $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
objcopy -I ihex -O binary --gap-fill=0xFF --pad-to=$(CONFIG_EC_FLASH_SIZE) $< $@
# Link object files into Intel Hex file
$(BUILD)/ec.ihx: $(OBJ)
@echo " LINK $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
$(CC) $(LDFLAGS) -o $@ $^
# Compile ASM files into object files
$(ASM_OBJ): $(BUILD)/%.rel: src/%.asm
@echo " AS $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
$(AS) $(ASFLAGS) $@ $<
# Compile C files into object files
$(C_OBJ): $(BUILD)/%.rel: src/%.c $(INCLUDE)
@echo " CC $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
$(CC) $(CFLAGS) -o $@ -c $<
# Add dependency rules
DEP = $(OBJ:%.rel=%.d)
-include $(DEP)

View File

@@ -1,29 +1,6 @@
# SPDX-License-Identifier: GPL-3.0-only
CC=avr-gcc -mmcu=$(EC)
CFLAGS+=-Os -fstack-usage -Wall -Werror -Wl,--gc-sections -Wl,-u,vfprintf -lprintf_flt
OBJ=$(sort $(patsubst src/%.c,$(BUILD)/%.o,$(SRC)))
# Run EC rom in simulator
sim: $(BUILD)/ec.elf
simavr $< --mcu $(EC)
# Convert from Intel Hex file to binary file
$(BUILD)/ec.rom: $(BUILD)/ec.ihx
@mkdir -p $(@D)
makebin -p < $< > $@
# Convert from ELF file to Intel Hex file
$(BUILD)/ec.ihx: $(BUILD)/ec.elf
@mkdir -p $(@D)
avr-objcopy -j .text -j .data -O ihex $< $@
# Link object files into ELF file
$(BUILD)/ec.elf: $(OBJ)
@mkdir -p $(@D)
$(CC) -o $@ $^
# Compile C files into object files
$(BUILD)/%.o: src/%.c $(INCLUDE)
@mkdir -p $(@D)
$(CC) $(CFLAGS) -o $@ -c $<
arch-y += gpio.c
arch-y += i2c.c
arch-y += i2c_slave.c
arch-y += uart.c

View File

@@ -2,7 +2,7 @@
#include <arch/gpio.h>
bool gpio_get_dir(struct Gpio * gpio) {
bool gpio_get_dir(const struct Gpio *const gpio) {
if (*gpio->ddr & gpio->value) {
return true;
} else {
@@ -10,7 +10,7 @@ bool gpio_get_dir(struct Gpio * gpio) {
}
}
void gpio_set_dir(struct Gpio * gpio, bool value) {
void gpio_set_dir(struct Gpio *const gpio, bool value) {
if (value) {
*gpio->ddr |= gpio->value;
} else {
@@ -18,7 +18,7 @@ void gpio_set_dir(struct Gpio * gpio, bool value) {
}
}
bool gpio_get(struct Gpio * gpio) {
bool gpio_get(const struct Gpio *const gpio) {
if (*gpio->pin & gpio->value) {
return true;
} else {
@@ -26,7 +26,7 @@ bool gpio_get(struct Gpio * gpio) {
}
}
void gpio_set(struct Gpio * gpio, bool value) {
void gpio_set(struct Gpio *const gpio, bool value) {
if (value) {
*gpio->port |= gpio->value;
} else {

View File

@@ -8,9 +8,9 @@
#include <common/i2c.h>
#include <common/macro.h>
#define TIMEOUT (F_CPU/1000)
#define TIMEOUT (F_CPU / 1000)
int16_t i2c_start(struct I2C * i2c, uint8_t addr, bool read) {
int16_t i2c_start(struct I2C *const i2c, uint8_t addr, bool read) {
uint32_t count;
// reset TWI control register
@@ -19,11 +19,14 @@ int16_t i2c_start(struct I2C * i2c, uint8_t addr, bool read) {
TWCR = BIT(TWINT) | BIT(TWSTA) | BIT(TWEN);
// wait for end of transmission
count = TIMEOUT;
while(!(TWCR & BIT(TWINT)) && count > 0) count -= 1;
if (count == 0) return -1;
while (!(TWCR & BIT(TWINT)) && count > 0)
count -= 1;
if (count == 0)
return -1;
// check if the start condition was successfully transmitted
if((TWSR & 0xF8) != TW_START) return -1;
if ((TWSR & 0xF8) != TW_START)
return -1;
// load slave addr into data register
TWDR = ((addr << 1) | read);
@@ -31,22 +34,25 @@ int16_t i2c_start(struct I2C * i2c, uint8_t addr, bool read) {
TWCR = BIT(TWINT) | BIT(TWEN);
// wait for end of transmission
count = TIMEOUT;
while(!(TWCR & BIT(TWINT)) && count > 0) count -= 1;
if (count == 0) return -1;
while (!(TWCR & BIT(TWINT)) && count > 0)
count -= 1;
if (count == 0)
return -1;
// check if the device has acknowledged the READ / WRITE mode
uint8_t twst = TW_STATUS & 0xF8;
if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) return -1;
uint8_t twst = TW_STATUS;
if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK))
return -1;
return 0;
}
void i2c_stop(struct I2C * i2c) {
void i2c_stop(struct I2C *const i2c) {
// transmit STOP condition
TWCR = BIT(TWINT) | BIT(TWEN) | BIT(TWSTO);
}
int16_t i2c_write(struct I2C * i2c, uint8_t * data, uint16_t length) {
int16_t i2c_write(struct I2C *const i2c, const uint8_t *const data, uint16_t length) {
uint16_t i;
for (i = 0; i < length; i++) {
// load data into data register
@@ -55,17 +61,20 @@ int16_t i2c_write(struct I2C * i2c, uint8_t * data, uint16_t length) {
TWCR = BIT(TWINT) | BIT(TWEN);
// wait for end of transmission
uint32_t count = TIMEOUT;
while(!(TWCR & BIT(TWINT)) && count > 0) count -= 1;
while (!(TWCR & BIT(TWINT)) && count > 0)
count -= 1;
// timed out
if (count == 0) return -1;
if (count == 0)
return -1;
// failed to receive ack
if((TWSR & 0xF8) != TW_MT_DATA_ACK) return -1;
if ((TWSR & 0xF8) != TW_MT_DATA_ACK)
return -1;
}
return i;
}
int16_t i2c_read(struct I2C * i2c, uint8_t * data, uint16_t length) {
int16_t i2c_read(struct I2C *const i2c, uint8_t *const data, uint16_t length) {
uint16_t i;
for (i = 0; i < length; i++) {
if ((i + 1) < length) {
@@ -77,8 +86,10 @@ int16_t i2c_read(struct I2C * i2c, uint8_t * data, uint16_t length) {
}
// wait for end of transmission
uint32_t count = TIMEOUT;
while(!(TWCR & BIT(TWINT)) && count > 0) count -= 1;
if (count == 0) return -1;
while (!(TWCR & BIT(TWINT)) && count > 0)
count -= 1;
if (count == 0)
return -1;
// return received data from TWDR
data[i] = TWDR;
}

View File

@@ -11,11 +11,18 @@
#include <arch/i2c_slave.h>
#include <common/macro.h>
static void (* volatile i2c_slave_new_cb)() = NULL;
static void (* volatile i2c_slave_recv_cb)(uint8_t) = NULL;
static uint8_t (* volatile i2c_slave_send_cb)() = NULL;
// uncrustify:off
static void (*volatile i2c_slave_new_cb)() = NULL;
static void (*volatile i2c_slave_recv_cb)(uint8_t) = NULL;
static uint8_t (*volatile i2c_slave_send_cb)() = NULL;
// uncrustify:on
void i2c_slave_init(uint8_t address, void (*new_cb)(), void (*recv_cb)(uint8_t), uint8_t (*send_cb)()){
void i2c_slave_init(
uint8_t address,
void (*new_cb)(),
void (*recv_cb)(uint8_t),
uint8_t (*send_cb)()
) {
// ensure correct behavior by stopping before changing callbacks or address
i2c_slave_stop();
@@ -35,7 +42,7 @@ void i2c_slave_init(uint8_t address, void (*new_cb)(), void (*recv_cb)(uint8_t),
sei();
}
void i2c_slave_stop(){
void i2c_slave_stop(void) {
// clear interrupts
cli();
@@ -54,7 +61,7 @@ void i2c_slave_stop(){
ISR(TWI_vect) {
uint8_t status = TW_STATUS;
switch(status) {
switch (status) {
case TW_SR_SLA_ACK:
// master has started a new transaction, call the new callback
if (i2c_slave_new_cb != NULL) {
@@ -64,7 +71,7 @@ ISR(TWI_vect) {
break;
case TW_SR_DATA_ACK:
// received data from master, call the receive callback
if(i2c_slave_send_cb != NULL){
if (i2c_slave_send_cb != NULL) {
i2c_slave_recv_cb(TWDR);
}
TWCR = BIT(TWIE) | BIT(TWINT) | BIT(TWEA) | BIT(TWEN);
@@ -72,7 +79,7 @@ ISR(TWI_vect) {
case TW_ST_SLA_ACK:
case TW_ST_DATA_ACK:
// master is requesting data, call the send callback
if(i2c_slave_recv_cb != NULL) {
if (i2c_slave_recv_cb != NULL) {
TWDR = i2c_slave_send_cb();
}
TWCR = BIT(TWIE) | BIT(TWINT) | BIT(TWEA) | BIT(TWEN);

View File

@@ -10,24 +10,22 @@
#include <stdint.h>
struct Gpio {
volatile uint8_t * pin;
volatile uint8_t * ddr;
volatile uint8_t * port;
volatile uint8_t *pin;
volatile uint8_t *ddr;
volatile uint8_t *port;
uint8_t value;
};
// clang-format off
#define GPIO(BLOCK, NUMBER) { \
.pin = &PIN ## BLOCK, \
.ddr = &DDR ## BLOCK, \
.port = &PORT ## BLOCK, \
.value = BIT(NUMBER), \
}
// clang-format on
bool gpio_get(struct Gpio * gpio);
void gpio_set(struct Gpio * gpio, bool value);
bool gpio_get_dir(struct Gpio * gpio);
void gpio_set_dir(struct Gpio * gpio, bool value);
bool gpio_get(const struct Gpio *const gpio);
void gpio_set(struct Gpio *const gpio, bool value);
bool gpio_get_dir(const struct Gpio *const gpio);
void gpio_set_dir(struct Gpio *const gpio, bool value);
#endif // _ARCH_GPIO_H

View File

@@ -3,7 +3,12 @@
#ifndef _ARCH_I2C_SLAVE_H
#define _ARCH_I2C_SLAVE_H
void i2c_slave_init(uint8_t address, void (*new_cb)(), void (*recv_cb)(uint8_t), uint8_t (*send_cb)());
void i2c_slave_stop();
void i2c_slave_init(
uint8_t address,
void (*new_cb)(),
void (*recv_cb)(uint8_t),
uint8_t (*send_cb)()
);
void i2c_slave_stop(void);
#endif // _ARCH_I2C_SLAVE_H

View File

@@ -6,12 +6,12 @@
#include <stdint.h>
struct Uart {
volatile uint8_t * a;
volatile uint8_t * b;
volatile uint8_t * c;
volatile uint8_t * data;
volatile uint8_t * baud_l;
volatile uint8_t * baud_h;
volatile uint8_t *a;
volatile uint8_t *b;
volatile uint8_t *c;
volatile uint8_t *data;
volatile uint8_t *baud_l;
volatile uint8_t *baud_h;
uint8_t a_read;
uint8_t a_write;
uint8_t a_init;
@@ -19,18 +19,18 @@ struct Uart {
uint8_t c_init;
};
void uart_init(struct Uart * uart, uint32_t baud);
void uart_init(struct Uart *const uart, uint32_t baud);
int16_t uart_count();
struct Uart * uart_new(int16_t num);
int16_t uart_count(void);
struct Uart *uart_new(int16_t num);
uint8_t uart_can_read(struct Uart * uart);
uint8_t uart_can_write(struct Uart * uart);
uint8_t uart_can_read(struct Uart *const uart);
uint8_t uart_can_write(struct Uart *const uart);
uint8_t uart_read(struct Uart * uart);
void uart_write(struct Uart * uart, uint8_t data);
uint8_t uart_read(struct Uart *const uart);
void uart_write(struct Uart *const uart, uint8_t data);
extern struct Uart * uart_stdio;
extern struct Uart *uart_stdio;
void uart_stdio_init(int16_t num, uint32_t baud);
#endif // _ARCH_UART_H

49
src/arch/avr/toolchain.mk Normal file
View File

@@ -0,0 +1,49 @@
# SPDX-License-Identifier: GPL-3.0-only
CC = avr-gcc -mmcu=$(EC_VARIANT)
CFLAGS += -MMD -Os -fstack-usage -Wall -Werror \
-Wl,--gc-sections -Wl,-u,vfprintf -lprintf_flt
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523
_gcc_version = $(shell avr-gcc --version 2>/dev/null)
ifneq ($(findstring 12.,$(_gcc_version)),)
CFLAGS += --param=min-pagesize=0
else ifneq ($(findstring 13.,$(_gcc_version)),)
CFLAGS += --param=min-pagesize=0
endif
OBJCOPY = avr-objcopy
OBJ=$(sort $(patsubst src/%.c,$(BUILD)/%.o,$(SRC)))
# Run EC rom in simulator
sim: $(BUILD)/ec.elf
simavr $< --mcu $(EC_VARIANT)
# Convert from Intel Hex file to binary file
$(BUILD)/ec.rom: $(BUILD)/ec.ihx
@echo " OBJCOPY $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
$(OBJCOPY) -I ihex -O binary --gap-fill 0xFF $< $@
# Convert from ELF file to Intel Hex file
$(BUILD)/ec.ihx: $(BUILD)/ec.elf
@echo " OBJCOPY $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
$(OBJCOPY) -j .text -j .data -O ihex $< $@
# Link object files into ELF file
$(BUILD)/ec.elf: $(OBJ)
@echo " LINK $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
$(CC) -o $@ $^
# Compile C files into object files
$(BUILD)/%.o: src/%.c $(INCLUDE)
@echo " CC $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
$(CC) $(CFLAGS) -o $@ -c $<
# Add dependency rules
DEP = $(OBJ:%.o=%.d)
-include $(DEP)

View File

@@ -6,7 +6,6 @@
#include <arch/uart.h>
#include <board/cpu.h>
// clang-format off
#define UART(N) \
{ \
&UCSR ## N ## A, \
@@ -23,30 +22,29 @@
}
#if defined(__AVR_ATmega328P__)
static struct Uart UARTS[] = {
UART(0)
};
static struct Uart UARTS[] = {
UART(0)
};
#elif defined(__AVR_ATmega32U4__)
static struct Uart UARTS[] = {
UART(1)
};
static struct Uart UARTS[] = {
UART(1)
};
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
static struct Uart UARTS[] = {
UART(0),
UART(1),
UART(2),
UART(3)
};
static struct Uart UARTS[] = {
UART(0),
UART(1),
UART(2),
UART(3)
};
#else
#error "Could not find UART definitions"
#endif
// clang-format on
int16_t uart_count() {
return sizeof(UARTS)/sizeof(struct Uart);
int16_t uart_count(void) {
return sizeof(UARTS) / sizeof(struct Uart);
}
struct Uart * uart_new(int16_t num) {
struct Uart *uart_new(int16_t num) {
if (num < uart_count()) {
return &UARTS[num];
} else {
@@ -54,40 +52,40 @@ struct Uart * uart_new(int16_t num) {
}
}
void uart_init(struct Uart * uart, uint32_t baud) {
void uart_init(struct Uart *const uart, uint32_t baud) {
uint32_t baud_prescale = (F_CPU / (baud * 16UL)) - 1;
*(uart->baud_h) = (uint8_t)(baud_prescale>>8);
*(uart->baud_h) = (uint8_t)(baud_prescale >> 8);
*(uart->baud_l) = (uint8_t)(baud_prescale);
*(uart->a) = uart->a_init;
*(uart->b) = uart->b_init;
*(uart->c) = uart->c_init;
}
uint8_t uart_can_read(struct Uart * uart) {
uint8_t uart_can_read(struct Uart *const uart) {
return (*(uart->a)) & uart->a_read;
}
uint8_t uart_read(struct Uart * uart) {
while (!uart_can_read(uart)) ;
uint8_t uart_read(struct Uart *const uart) {
while (!uart_can_read(uart)) {}
return *(uart->data);
}
uint8_t uart_can_write(struct Uart * uart) {
uint8_t uart_can_write(struct Uart *const uart) {
return (*(uart->a)) & uart->a_write;
}
void uart_write(struct Uart * uart, uint8_t data) {
while (!uart_can_write(uart)) ;
void uart_write(struct Uart *const uart, uint8_t data) {
while (!uart_can_write(uart)) {}
*(uart->data) = data;
}
struct Uart * uart_stdio = NULL;
struct Uart *uart_stdio = NULL;
int16_t uart_stdio_get(FILE * stream) {
int16_t uart_stdio_get(FILE *stream) {
return (int16_t)uart_read(uart_stdio);
}
int16_t uart_stdio_put(char data, FILE * stream) {
int16_t uart_stdio_put(char data, FILE *stream) {
uart_write(uart_stdio, (uint8_t)data);
return 0;
}
@@ -95,8 +93,8 @@ int16_t uart_stdio_put(char data, FILE * stream) {
FILE uart_stdio_file = FDEV_SETUP_STREAM(uart_stdio_put, uart_stdio_get, _FDEV_SETUP_RW);
void uart_stdio_init(int16_t num, uint32_t baud) {
struct Uart * uart = uart_new(num);
if(uart != NULL) {
struct Uart *uart = uart_new(num);
if (uart != NULL) {
uart_init(uart, baud);
uart_stdio = uart;
stdin = stdout = stderr = &uart_stdio_file;

View File

@@ -4,7 +4,7 @@
#include <common/i2c.h>
int16_t smbus_read(uint8_t address, uint8_t command, uint16_t * data) {
int16_t smbus_read(uint8_t address, uint8_t command, uint16_t *const data) {
return i2c_get(NULL, address, command, (uint8_t *)data, 2);
}
@@ -16,7 +16,8 @@ void battery_debug(void) {
uint16_t data = 0;
int16_t res = 0;
#define command(N, A, V) { \
#define command(N, A, V) \
{ \
printf(#N ": "); \
res = smbus_read(A, V, &data); \
if (res < 0) { \
@@ -45,5 +46,5 @@ void battery_debug(void) {
command(ProchotOption1, 0x09, 0x3D);
command(ProchotStatus, 0x09, 0x3A);
#undef command
#undef command
}

View File

@@ -1,6 +1,12 @@
# SPDX-License-Identifier: GPL-3.0-only
EC=atmega2560
board-y += battery.c
board-y += i2c.c
board-y += main.c
board-y += parallel.c
EC=atmega
EC_VARIANT=atmega2560
PORT=$(wildcard /dev/ttyACM*)
CONSOLE_BAUD=1000000
@@ -10,4 +16,4 @@ console:
sudo tio -b $(CONSOLE_BAUD) $(PORT)
flash: $(BUILD)/ec.ihx
sudo avrdude -v -v -p $(EC) -c wiring -P $(PORT) -b 115200 -D -U flash:w:$<:i
sudo avrdude -v -v -p $(EC_VARIANT) -c wiring -P $(PORT) -b 115200 -D -U flash:w:$<:i

View File

@@ -7,6 +7,6 @@
void i2c_init(uint32_t baud) {
TWAR = 0;
TWBR = (uint8_t)(((F_CPU / baud) - 16 ) / 2);
TWBR = (uint8_t)(((F_CPU / baud) - 16) / 2);
TWCR = 0;
}

View File

@@ -11,7 +11,6 @@
#include <arch/gpio.h>
#include <arch/uart.h>
// clang-format off
// Mapping of 24-pin ribbon cable to parallel pins. See schematic
#define PINS \
/* Data (KSO0 - KSO7) - bi-directional */ \
@@ -89,7 +88,6 @@ static struct Gpio GPIOS[24] = {
GPIO(A, 0), GPIO(A, 1),
};
#endif // !defined(FLIP)
// clang-format on
enum ParallelState {
PARALLEL_STATE_UNKNOWN,
@@ -101,47 +99,51 @@ enum ParallelState {
// Parallel struct definition
// See http://efplus.com/techref/io/parallel/1284/eppmode.htm
struct Parallel {
#define PIN(N, P) struct Gpio * N;
#define PIN(N, P) struct Gpio *N;
PINS
#undef PIN
#undef PIN
enum ParallelState state;
};
// Parallel struct instance
static struct Parallel PORT = {
#define PIN(N, P) .N = &GPIOS[P - 1],
#define PIN(N, P) .N = &GPIOS[P - 1],
PINS
#undef PIN
#undef PIN
.state = PARALLEL_STATE_UNKNOWN,
};
// Set port to all high-impedance inputs
void parallel_hiz(struct Parallel * port) {
#define PIN(N, P) \
gpio_set_dir(port->N, false); \
gpio_set(port->N, false);
void parallel_hiz(struct Parallel *const port) {
#define PIN(N, P) \
gpio_set_dir(port->N, false); \
gpio_set(port->N, false);
PINS
#undef PIN
#undef PIN
}
// Place all data lines in high or low impendance state
void parallel_data_dir(struct Parallel * port, bool dir) {
#define DATA_BIT(B) gpio_set_dir(port->d ## B, dir);
void parallel_data_dir(struct Parallel *const port, bool dir) {
#define DATA_BIT(B) gpio_set_dir(port->d##B, dir);
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
}
#define parallel_data_forward(P) parallel_data_dir(P, true)
#define parallel_data_reverse(P) parallel_data_dir(P, false)
void parallel_data_set_high(struct Parallel * port, uint8_t byte) {
void parallel_data_set_high(struct Parallel *const port, uint8_t byte) {
// By convention all lines are high, so only set the ones needed
#define DATA_BIT(B) if (!(byte & (1 << B))) gpio_set(port->d ## B, true);
#define DATA_BIT(B) \
if (!(byte & (1 << B))) { \
gpio_set(port->d##B, true); \
}
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
}
// Set port to initial state required before being able to perform cycles
void parallel_reset(struct Parallel * port, bool host) {
void parallel_reset(struct Parallel *const port, bool host) {
parallel_hiz(port);
// nRESET: output on host, input on peripherals
@@ -166,9 +168,9 @@ void parallel_reset(struct Parallel * port, bool host) {
gpio_set_dir(port->wait_n, !host);
// Pull up data lines on host, leave floating on peripherals
#define DATA_BIT(B) gpio_set(port->d ## B, host);
#define DATA_BIT(B) gpio_set(port->d##B, host);
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
//TODO: something with straps
@@ -180,42 +182,57 @@ void parallel_reset(struct Parallel * port, bool host) {
}
}
void parallel_state(struct Parallel * port, enum ParallelState state) {
void parallel_state(struct Parallel *const port, enum ParallelState state) {
if (port->state != state) {
switch (state) {
case PARALLEL_STATE_UNKNOWN:
return;
case PARALLEL_STATE_HIZ:
parallel_hiz(port);
break;
case PARALLEL_STATE_HOST:
parallel_reset(port, true);
break;
case PARALLEL_STATE_PERIPHERAL:
parallel_reset(port, false);
break;
case PARALLEL_STATE_UNKNOWN:
return;
case PARALLEL_STATE_HIZ:
parallel_hiz(port);
break;
case PARALLEL_STATE_HOST:
parallel_reset(port, true);
break;
case PARALLEL_STATE_PERIPHERAL:
parallel_reset(port, false);
break;
}
port->state = state;
}
}
uint8_t parallel_read_data(struct Parallel * port) {
uint8_t parallel_read_data(struct Parallel *const port) {
uint8_t byte = 0;
#define DATA_BIT(B) if (gpio_get(port->d ## B)) byte |= (1 << B);
#define DATA_BIT(B) \
if (gpio_get(port->d##B)) { \
byte |= (1 << B); \
}
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
return byte;
}
void parallel_write_data(struct Parallel * port, uint8_t byte) {
void parallel_write_data(struct Parallel *const port, uint8_t byte) {
// By convention all lines are high, so only set the ones needed
#define DATA_BIT(B) if (!(byte & (1 << B))) gpio_set(port->d ## B, false);
#define DATA_BIT(B) \
if (!(byte & (1 << B))) { \
gpio_set(port->d##B, false); \
}
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
}
//TODO: timeout
int16_t parallel_transaction(struct Parallel * port, uint8_t * data, int16_t length, bool read, bool addr) {
int16_t parallel_transaction(
struct Parallel *const port,
uint8_t *const data,
int16_t length,
bool read,
bool addr
) {
if (!read) {
// Set write line low
gpio_set(port->write_n, false);
@@ -285,7 +302,12 @@ int16_t parallel_transaction(struct Parallel * port, uint8_t * data, int16_t len
// host write -> peripheral read
// host read -> peripheral write
bool parallel_peripheral_cycle(struct Parallel * port, uint8_t * data, bool * read, bool * addr) {
bool parallel_peripheral_cycle(
struct Parallel *const port,
uint8_t *const data,
bool *const read,
bool *const addr
) {
if (!gpio_get(port->reset_n)) {
// XXX: Give host some time to get ready
_delay_ms(1);
@@ -337,55 +359,76 @@ static uint8_t ZERO = 0x00;
static uint8_t SPI_ENABLE = 0xFE;
static uint8_t SPI_DATA = 0xFD;
int16_t parallel_ecms_read(struct Parallel *port, uint16_t addr, uint8_t * data, int16_t length) {
int16_t parallel_ecms_read(
struct Parallel *const port,
uint16_t addr,
uint8_t *const data,
int16_t length
) {
int16_t res;
res = parallel_set_address(port, &ADDRESS_ECMSADDR1, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_write(port, ((uint8_t *)&addr) + 1, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_set_address(port, &ADDRESS_ECMSADDR0, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_write(port, (uint8_t *)&addr, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_set_address(port, &ADDRESS_ECMSDATA, 1);
if (res < 0) return res;
if (res < 0)
return res;
return parallel_read(port, data, length);
}
// Disable chip
int16_t parallel_spi_reset(struct Parallel *port) {
int16_t parallel_spi_reset(struct Parallel *const port) {
int16_t res;
res = parallel_set_address(port, &ADDRESS_INDAR1, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_write(port, &SPI_ENABLE, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_set_address(port, &ADDRESS_INDDR, 1);
if (res < 0) return res;
if (res < 0)
return res;
return parallel_write(port, &ZERO, 1);
}
// Enable chip and read or write data
int16_t parallel_spi_transaction(struct Parallel *port, uint8_t * data, int16_t length, bool read) {
int16_t parallel_spi_transaction(
struct Parallel *const port,
uint8_t *const data,
int16_t length,
bool read
) {
int16_t res;
res = parallel_set_address(port, &ADDRESS_INDAR1, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_write(port, &SPI_DATA, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_set_address(port, &ADDRESS_INDDR, 1);
if (res < 0) return res;
if (res < 0)
return res;
return parallel_transaction(port, data, length, read, false);
}
@@ -394,16 +437,22 @@ int16_t parallel_spi_transaction(struct Parallel *port, uint8_t * data, int16_t
#define parallel_spi_write(P, D, L) parallel_spi_transaction(P, D, L, false)
// "Hardware" accelerated SPI programming, requires ECINDARs to be set
int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t length, bool initialized) {
int16_t parallel_spi_program(
struct Parallel *const port,
const uint8_t *const data,
int16_t length,
bool initialized
) {
static uint8_t aai[6] = { 0xAD, 0, 0, 0, 0, 0 };
int16_t res;
int16_t i;
uint8_t status;
for(i = 0; (i + 1) < length; i+=2) {
for (i = 0; (i + 1) < length; i += 2) {
// Disable chip to begin command
res = parallel_spi_reset(port);
if (res < 0) return res;
if (res < 0)
return res;
if (!initialized) {
// If not initialized, the start address must be sent
@@ -415,7 +464,8 @@ int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t len
aai[5] = data[i + 1];
res = parallel_spi_write(port, aai, 6);
if (res < 0) return res;
if (res < 0)
return res;
initialized = true;
} else {
@@ -423,30 +473,35 @@ int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t len
aai[2] = data[i + 1];
res = parallel_spi_write(port, aai, 3);
if (res < 0) return res;
if (res < 0)
return res;
}
// Wait for SPI busy flag to clear
for (;;) {
// Disable chip to begin command
res = parallel_spi_reset(port);
if (res < 0) return res;
if (res < 0)
return res;
status = 0x05;
res = parallel_spi_write(port, &status, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_spi_read(port, &status, 1);
if (res < 0) return res;
if (res < 0)
return res;
if (!(status & 1)) break;
if (!(status & 1))
break;
}
}
return i;
}
int16_t serial_transaction(uint8_t * data, int16_t length, bool read) {
int16_t serial_transaction(uint8_t *const data, int16_t length, bool read) {
int16_t i;
for (i = 0; i < length; i++) {
if (read) {
@@ -465,7 +520,7 @@ int16_t serial_transaction(uint8_t * data, int16_t length, bool read) {
int parallel_main(void) {
int16_t res = 0;
struct Parallel * port = &PORT;
struct Parallel *port = &PORT;
parallel_state(port, PARALLEL_STATE_HIZ);
static uint8_t data[128];
@@ -481,7 +536,8 @@ int parallel_main(void) {
for (;;) {
// Read command and length
res = serial_read(data, 2);
if (res < 0) goto err;
if (res < 0)
goto err;
// Command is a character
command = (char)data[0];
@@ -499,164 +555,183 @@ int parallel_main(void) {
// Length is received data + 1
length = ((int16_t)data[1]) + 1;
// Truncate length to size of data
if (length > sizeof(data)) length = sizeof(data);
if (length > sizeof(data))
length = sizeof(data);
switch (command) {
// Buffer size
case 'B':
// Fill buffer size - 1
for (i = 0; i < length; i++) {
if (i == 0) {
data[i] = (uint8_t)(sizeof(data) - 1);
} else {
data[i] = 0;
// Buffer size
case 'B':
// Fill buffer size - 1
for (i = 0; i < length; i++) {
if (i == 0) {
data[i] = (uint8_t)(sizeof(data) - 1);
} else {
data[i] = 0;
}
}
// Write data to serial
res = serial_write(data, length);
if (res < 0)
goto err;
break;
// Debug console
case 'C':
// Set parallel lines to peripheral mode
parallel_state(port, PARALLEL_STATE_PERIPHERAL);
// Tell the user the console is ready
serial_write(console_msg, sizeof(console_msg));
for (;;) {
bool read = false;
bool addr = false;
if (parallel_peripheral_cycle(port, data, &read, &addr)) {
if (!read && !addr) {
res = serial_write(data, 1);
if (res < 0)
goto err;
}
}
}
// Write data to serial
res = serial_write(data, length);
if (res < 0) goto err;
break;
break;
// Echo
case 'E':
// Read data from serial
res = serial_read(data, length);
if (res < 0)
goto err;
// Debug console
case 'C':
// Set parallel lines to peripheral mode
parallel_state(port, PARALLEL_STATE_PERIPHERAL);
// Write data to serial
res = serial_write(data, length);
if (res < 0)
goto err;
// Tell the user the console is ready
serial_write(console_msg, sizeof(console_msg));
for (;;) {
bool read = false;
bool addr = false;
if (parallel_peripheral_cycle(port, data, &read, &addr)) {
if (!read && !addr) {
res = serial_write(data, 1);
if (res < 0) goto err;
}
}
break;
// Forced debug console (can be used on all firmware but may miss bytes)
case 'F':
serial_write(console_msg, sizeof(console_msg));
// We must be in host mode
parallel_state(port, PARALLEL_STATE_HOST);
uint16_t head = 0;
for (;;) {
// Read current position
res = parallel_ecms_read(port, 0xF00, data, 1);
if (res < 0)
goto err;
uint16_t tail = (uint16_t)data[0];
if (tail == 0 || head == tail) {
// No new data
continue;
}
break;
// Echo
case 'E':
// Read data from serial
res = serial_read(data, length);
if (res < 0) goto err;
// Write data to serial
res = serial_write(data, length);
if (res < 0) goto err;
break;
// Forced debug console (can be used on all firmware but may miss bytes)
case 'F':
serial_write(console_msg, sizeof(console_msg));
// We must be in host mode
parallel_state(port, PARALLEL_STATE_HOST);
uint16_t head = 0;
for (;;) {
// Read current position
res = parallel_ecms_read(port, 0xF00, data, 1);
if (res < 0) goto err;
uint16_t tail = (uint16_t)data[0];
if (tail == 0 || head == tail) {
// No new data
continue;
}
if (head == 0) {
// Set head if necessary
head = tail;
continue;
}
while (head != tail) {
head += 1;
if (head >= 256) { head = 1; }
// Read byte at head
res = parallel_ecms_read(port, 0xF00 + head, data, 1);
if (res < 0) goto err;
// Print read byte
serial_write(data, 1);
}
if (head == 0) {
// Set head if necessary
head = tail;
continue;
}
break;
while (head != tail) {
head += 1;
if (head >= 256) {
head = 1;
}
// Read data
case 'R':
parallel_state(port, PARALLEL_STATE_HOST);
// Read byte at head
res = parallel_ecms_read(port, 0xF00 + head, data, 1);
if (res < 0)
goto err;
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0) goto err;
set_address = false;
// Print read byte
serial_write(data, 1);
}
}
// Read data from parallel
res = parallel_read(port, data, length);
if (res < 0) goto err;
break;
// Write data to serial
res = serial_write(data, length);
if (res < 0) goto err;
// Read data
case 'R':
parallel_state(port, PARALLEL_STATE_HOST);
break;
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0)
goto err;
set_address = false;
}
// Accelerated program function
case 'P':
parallel_state(port, PARALLEL_STATE_HOST);
// Read data from parallel
res = parallel_read(port, data, length);
if (res < 0)
goto err;
// Read data from serial
res = serial_read(data, length);
if (res < 0) goto err;
// Write data to serial
res = serial_write(data, length);
if (res < 0)
goto err;
// Run accelerated programming function
res = parallel_spi_program(port, data, length, program_aai);
if (res < 0) goto err;
program_aai = true;
break;
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0) goto err;
// Accelerated program function
case 'P':
parallel_state(port, PARALLEL_STATE_HOST);
break;
// Read data from serial
res = serial_read(data, length);
if (res < 0)
goto err;
// Write data
case 'W':
parallel_state(port, PARALLEL_STATE_HOST);
// Run accelerated programming function
res = parallel_spi_program(port, data, length, program_aai);
if (res < 0)
goto err;
program_aai = true;
// Read data from serial
res = serial_read(data, length);
if (res < 0) goto err;
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0)
goto err;
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0) goto err;
set_address = false;
}
break;
// Write data to parallel
res = parallel_write(port, data, length);
if (res < 0) goto err;
// Write data
case 'W':
parallel_state(port, PARALLEL_STATE_HOST);
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0) goto err;
// Read data from serial
res = serial_read(data, length);
if (res < 0)
goto err;
break;
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0)
goto err;
set_address = false;
}
// Write data to parallel
res = parallel_write(port, data, length);
if (res < 0)
goto err;
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0)
goto err;
break;
}
}

View File

@@ -1,6 +1,9 @@
# SPDX-License-Identifier: GPL-3.0-only
EC=atmega32u4
board-y += main.c
EC=atmega
EC_VARIANT=atmega32u4
PORT=$(wildcard /dev/ttyACM*)
CONSOLE_BAUD=1000000
@@ -10,4 +13,4 @@ console:
sudo tio -b $(CONSOLE_BAUD) $(PORT)
flash: $(BUILD)/ec.ihx
sudo avrdude -v -v -p $(EC) -c avr109 -P $(PORT) -b 115200 -D -U flash:w:$<:i
sudo avrdude -v -v -p $(EC_VARIANT) -c avr109 -P $(PORT) -b 115200 -D -U flash:w:$<:i

View File

@@ -4,7 +4,7 @@
#include <common/i2c.h>
int16_t smbus_read(uint8_t address, uint8_t command, uint16_t * data) {
int16_t smbus_read(uint8_t address, uint8_t command, uint16_t *data) {
return i2c_get(NULL, address, command, (uint8_t *)data, 2);
}
@@ -16,7 +16,8 @@ void battery_debug(void) {
uint16_t data = 0;
int16_t res = 0;
#define command(N, A, V) { \
#define command(N, A, V) \
{ \
printf(#N ": "); \
res = smbus_read(A, V, &data); \
if (res < 0) { \
@@ -45,5 +46,5 @@ void battery_debug(void) {
command(ProchotOption1, 0x09, 0x3D);
command(ProchotStatus, 0x09, 0x3A);
#undef command
#undef command
}

View File

@@ -1,6 +1,12 @@
# SPDX-License-Identifier: GPL-3.0-only
EC=atmega328p
board-y += battery.c
board-y += i2c.c
board-y += main.c
board-y += parallel.c
EC=atmega
EC_VARIANT=atmega328p
PORT=$(wildcard /dev/ttyACM*)
CONSOLE_BAUD=1000000
@@ -10,4 +16,4 @@ console:
sudo tio -b $(CONSOLE_BAUD) $(PORT)
flash: $(BUILD)/ec.ihx
sudo avrdude -v -v -p $(EC) -c arduino -P $(PORT) -b 115200 -D -U flash:w:$<:i
sudo avrdude -v -v -p $(EC_VARIANT) -c arduino -P $(PORT) -b 115200 -D -U flash:w:$<:i

View File

@@ -7,6 +7,6 @@
void i2c_init(uint32_t baud) {
TWAR = 0;
TWBR = (uint8_t)(((F_CPU / baud) - 16 ) / 2);
TWBR = (uint8_t)(((F_CPU / baud) - 16) / 2);
TWCR = 0;
}

View File

@@ -11,7 +11,6 @@
#include <arch/gpio.h>
#include <arch/uart.h>
// clang-format off
// Mapping of 24-pin ribbon cable to parallel pins. See schematic
#define PINS \
/* Data (KSO0 - KSO7) - bi-directional */ \
@@ -65,50 +64,54 @@ static struct Gpio GPIOS[13] = {
GPIO(C, 1),
GPIO(C, 0),
};
// clang-format on
// Parallel struct definition
// See http://efplus.com/techref/io/parallel/1284/eppmode.htm
struct Parallel {
#define PIN(N, P) struct Gpio * N;
#define PIN(N, P) struct Gpio *N;
PINS
#undef PIN
#undef PIN
};
// Parallel struct instance
static struct Parallel PORT = {
#define PIN(N, P) .N = &GPIOS[P - 1],
#define PIN(N, P) .N = &GPIOS[P - 1],
PINS
#undef PIN
#undef PIN
};
// Set port to all high-impedance inputs
void parallel_hiz(struct Parallel * port) {
#define PIN(N, P) \
gpio_set_dir(port->N, false); \
gpio_set(port->N, false);
void parallel_hiz(struct Parallel *const port) {
#define PIN(N, P) \
gpio_set_dir(port->N, false); \
gpio_set(port->N, false);
PINS
#undef PIN
#undef PIN
}
// Place all data lines in high or low impendance state
void parallel_data_dir(struct Parallel * port, bool dir) {
#define DATA_BIT(B) gpio_set_dir(port->d ## B, dir);
void parallel_data_dir(struct Parallel *const port, bool dir) {
#define DATA_BIT(B) gpio_set_dir(port->d##B, dir);
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
}
#define parallel_data_forward(P) parallel_data_dir(P, true)
#define parallel_data_reverse(P) parallel_data_dir(P, false)
void parallel_data_set_high(struct Parallel * port, uint8_t byte) {
void parallel_data_set_high(struct Parallel *const port, uint8_t byte) {
// By convention all lines are high, so only set the ones needed
#define DATA_BIT(B) if (!(byte & (1 << B))) gpio_set(port->d ## B, true);
#define DATA_BIT(B) \
if (!(byte & (1 << B))) { \
gpio_set(port->d##B, true); \
}
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
}
// Set port to initial state required before being able to perform cycles
void parallel_reset(struct Parallel * port, bool host) {
void parallel_reset(struct Parallel *const port, bool host) {
parallel_hiz(port);
// nRESET: output on host, input on peripherals
@@ -133,9 +136,9 @@ void parallel_reset(struct Parallel * port, bool host) {
gpio_set_dir(port->wait_n, !host);
// Pull up data lines on host, leave floating on peripherals
#define DATA_BIT(B) gpio_set(port->d ## B, host);
#define DATA_BIT(B) gpio_set(port->d##B, host);
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
//TODO: something with straps
@@ -147,23 +150,37 @@ void parallel_reset(struct Parallel * port, bool host) {
}
}
uint8_t parallel_read_data(struct Parallel * port) {
uint8_t parallel_read_data(struct Parallel *const port) {
uint8_t byte = 0;
#define DATA_BIT(B) if (gpio_get(port->d ## B)) byte |= (1 << B);
#define DATA_BIT(B) \
if (gpio_get(port->d##B)) { \
byte |= (1 << B); \
}
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
return byte;
}
void parallel_write_data(struct Parallel * port, uint8_t byte) {
void parallel_write_data(struct Parallel *const port, uint8_t byte) {
// By convention all lines are high, so only set the ones needed
#define DATA_BIT(B) if (!(byte & (1 << B))) gpio_set(port->d ## B, false);
#define DATA_BIT(B) \
if (!(byte & (1 << B))) { \
gpio_set(port->d##B, false); \
}
DATA_BITS
#undef DATA_BIT
#undef DATA_BIT
}
//TODO: timeout
int16_t parallel_transaction(struct Parallel * port, uint8_t * data, int16_t length, bool read, bool addr) {
int16_t parallel_transaction(
struct Parallel *const port,
uint8_t *const data,
int16_t length,
bool read,
bool addr
) {
if (!read) {
// Set write line low
gpio_set(port->write_n, false);
@@ -234,7 +251,12 @@ int16_t parallel_transaction(struct Parallel * port, uint8_t * data, int16_t len
// host write -> peripheral read
// host read -> peripheral write
bool parallel_peripheral_cycle(struct Parallel * port, uint8_t * data, bool * read, bool * addr) {
bool parallel_peripheral_cycle(
struct Parallel *const port,
uint8_t *const data,
bool *const read,
bool *const addr
) {
if (!gpio_get(port->reset_n)) {
// XXX: Give host some time to get ready
_delay_ms(1);
@@ -279,33 +301,44 @@ static uint8_t SPI_ENABLE = 0xFE;
static uint8_t SPI_DATA = 0xFD;
// Disable chip
int16_t parallel_spi_reset(struct Parallel *port) {
int16_t parallel_spi_reset(struct Parallel *const port) {
int16_t res;
res = parallel_set_address(port, &ADDRESS_INDAR1, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_write(port, &SPI_ENABLE, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_set_address(port, &ADDRESS_INDDR, 1);
if (res < 0) return res;
if (res < 0)
return res;
return parallel_write(port, &ZERO, 1);
}
// Enable chip and read or write data
int16_t parallel_spi_transaction(struct Parallel *port, uint8_t * data, int16_t length, bool read) {
int16_t parallel_spi_transaction(
struct Parallel *const port,
uint8_t *const data,
int16_t length,
bool read
) {
int16_t res;
res = parallel_set_address(port, &ADDRESS_INDAR1, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_write(port, &SPI_DATA, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_set_address(port, &ADDRESS_INDDR, 1);
if (res < 0) return res;
if (res < 0)
return res;
return parallel_transaction(port, data, length, read, false);
}
@@ -314,16 +347,22 @@ int16_t parallel_spi_transaction(struct Parallel *port, uint8_t * data, int16_t
#define parallel_spi_write(P, D, L) parallel_spi_transaction(P, D, L, false)
// "Hardware" accelerated SPI programming, requires ECINDARs to be set
int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t length, bool initialized) {
int16_t parallel_spi_program(
struct Parallel *const port,
const uint8_t *const data,
int16_t length,
bool initialized
) {
static uint8_t aai[6] = { 0xAD, 0, 0, 0, 0, 0 };
int16_t res;
int16_t i;
uint8_t status;
for(i = 0; (i + 1) < length; i+=2) {
for (i = 0; (i + 1) < length; i += 2) {
// Disable chip to begin command
res = parallel_spi_reset(port);
if (res < 0) return res;
if (res < 0)
return res;
if (!initialized) {
// If not initialized, the start address must be sent
@@ -335,7 +374,8 @@ int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t len
aai[5] = data[i + 1];
res = parallel_spi_write(port, aai, 6);
if (res < 0) return res;
if (res < 0)
return res;
initialized = true;
} else {
@@ -343,30 +383,35 @@ int16_t parallel_spi_program(struct Parallel * port, uint8_t * data, int16_t len
aai[2] = data[i + 1];
res = parallel_spi_write(port, aai, 3);
if (res < 0) return res;
if (res < 0)
return res;
}
// Wait for SPI busy flag to clear
for (;;) {
// Disable chip to begin command
res = parallel_spi_reset(port);
if (res < 0) return res;
if (res < 0)
return res;
status = 0x05;
res = parallel_spi_write(port, &status, 1);
if (res < 0) return res;
if (res < 0)
return res;
res = parallel_spi_read(port, &status, 1);
if (res < 0) return res;
if (res < 0)
return res;
if (!(status & 1)) break;
if (!(status & 1))
break;
}
}
return i;
}
int16_t serial_transaction(uint8_t * data, int16_t length, bool read) {
int16_t serial_transaction(uint8_t *const data, int16_t length, bool read) {
int16_t i;
for (i = 0; i < length; i++) {
if (read) {
@@ -385,7 +430,7 @@ int16_t serial_transaction(uint8_t * data, int16_t length, bool read) {
int16_t parallel_main(void) {
int16_t res = 0;
struct Parallel * port = &PORT;
struct Parallel *port = &PORT;
parallel_reset(port, true);
static uint8_t data[128];
@@ -401,7 +446,8 @@ int16_t parallel_main(void) {
for (;;) {
// Read command and length
res = serial_read(data, 2);
if (res < 0) goto err;
if (res < 0)
goto err;
// Command is a character
command = (char)data[0];
@@ -419,118 +465,133 @@ int16_t parallel_main(void) {
// Length is received data + 1
length = ((int16_t)data[1]) + 1;
// Truncate length to size of data
if (length > sizeof(data)) length = sizeof(data);
if (length > sizeof(data))
length = sizeof(data);
switch (command) {
// Buffer size
case 'B':
// Fill buffer size - 1
for (i = 0; i < length; i++) {
if (i == 0) {
data[i] = (uint8_t)(sizeof(data) - 1);
} else {
data[i] = 0;
}
// Buffer size
case 'B':
// Fill buffer size - 1
for (i = 0; i < length; i++) {
if (i == 0) {
data[i] = (uint8_t)(sizeof(data) - 1);
} else {
data[i] = 0;
}
}
// Write data to serial
res = serial_write(data, length);
if (res < 0) goto err;
// Write data to serial
res = serial_write(data, length);
if (res < 0)
goto err;
break;
break;
// Debug console
case 'C':
serial_write(console_msg, sizeof(console_msg));
// Debug console
case 'C':
serial_write(console_msg, sizeof(console_msg));
// Reconfigure as a peripheral
parallel_reset(port, false);
// Reconfigure as a peripheral
parallel_reset(port, false);
for (;;) {
bool read = false;
bool addr = false;
bool ret = parallel_peripheral_cycle(port, data, &read, &addr);
for (;;) {
bool read = false;
bool addr = false;
bool ret = parallel_peripheral_cycle(port, data, &read, &addr);
if (ret && !read && !addr) {
res = serial_write(data, 1);
if (res < 0) goto err;
}
if (ret && !read && !addr) {
res = serial_write(data, 1);
if (res < 0)
goto err;
}
}
break;
break;
// Echo
case 'E':
// Read data from serial
res = serial_read(data, length);
if (res < 0) goto err;
// Echo
case 'E':
// Read data from serial
res = serial_read(data, length);
if (res < 0)
goto err;
// Write data to serial
res = serial_write(data, length);
if (res < 0) goto err;
// Write data to serial
res = serial_write(data, length);
if (res < 0)
goto err;
break;
break;
// Read data
case 'R':
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0) goto err;
set_address = false;
}
// Read data
case 'R':
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0)
goto err;
set_address = false;
}
// Read data from parallel
res = parallel_read(port, data, length);
if (res < 0) goto err;
// Read data from parallel
res = parallel_read(port, data, length);
if (res < 0)
goto err;
// Write data to serial
res = serial_write(data, length);
if (res < 0) goto err;
// Write data to serial
res = serial_write(data, length);
if (res < 0)
goto err;
break;
break;
// Accelerated program function
case 'P':
// Read data from serial
res = serial_read(data, length);
if (res < 0) goto err;
// Accelerated program function
case 'P':
// Read data from serial
res = serial_read(data, length);
if (res < 0)
goto err;
// Run accelerated programming function
res = parallel_spi_program(port, data, length, program_aai);
if (res < 0) goto err;
program_aai = true;
// Run accelerated programming function
res = parallel_spi_program(port, data, length, program_aai);
if (res < 0)
goto err;
program_aai = true;
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0) goto err;
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0)
goto err;
break;
break;
// Write data
case 'W':
// Read data from serial
res = serial_read(data, length);
if (res < 0) goto err;
// Write data
case 'W':
// Read data from serial
res = serial_read(data, length);
if (res < 0)
goto err;
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0) goto err;
set_address = false;
}
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0)
goto err;
set_address = false;
}
// Write data to parallel
res = parallel_write(port, data, length);
if (res < 0) goto err;
// Write data to parallel
res = parallel_write(port, data, length);
if (res < 0)
goto err;
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0) goto err;
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0)
goto err;
break;
break;
}
}

View File

@@ -3,7 +3,6 @@
#include <board/board.h>
#include <board/gpio.h>
#include <board/kbc.h>
#include <board/power.h>
#include <common/debug.h>
extern uint8_t main_cycle;
@@ -15,10 +14,6 @@ void board_init(void) {
gpio_set(&BKL_EN, true);
// Enable camera
gpio_set(&CCD_EN, true);
// Enable wireless
gpio_set(&BT_EN, true);
gpio_set(&WLAN_EN, true);
gpio_set(&WLAN_PWR_EN, true);
// Enable right USB port
gpio_set(&USB_PWR_EN_N, false);
// Assert SMI#, SCI#, and SWI#
@@ -28,8 +23,6 @@ void board_init(void) {
}
void board_event(void) {
power_set_limit();
if (main_cycle == 0) {
// Set keyboard LEDs
static uint8_t last_kbc_leds = 0;

View File

@@ -1,16 +1,22 @@
# SPDX-License-Identifier: GPL-3.0-only
EC=it8587e
board-y += board.c
board-y += gpio.c
EC=ite
CONFIG_EC_ITE_IT8587E=y
CONFIG_EC_FLASH_SIZE_128K = y
# Intel-based host
CONFIG_PLATFORM_INTEL = y
# Include keyboard
KEYBOARD=15in_102
# Set keyboard LED mechanism
CONFIG_HAVE_KBLED = y
KBLED=rgb_pwm
# Set discrete GPU I2C bus
CFLAGS+=-DI2C_DGPU=I2C_1
# Set battery I2C bus
CFLAGS+=-DI2C_SMBUS=I2C_0
@@ -19,32 +25,38 @@ CFLAGS+=-DPS2_TOUCHPAD=PS2_3
# Set smart charger parameters
CFLAGS+=\
-DCHARGER_CHARGE_CURRENT=1536 \
-DCHARGER_ADAPTER_RSENSE=5 \
-DCHARGER_BATTERY_RSENSE=10 \
-DCHARGER_CHARGE_CURRENT=3072 \
-DCHARGER_CHARGE_VOLTAGE=12600 \
-DCHARGER_INPUT_CURRENT=11800
# Set CPU power limits in watts
CFLAGS+=\
-DPOWER_LIMIT_AC=180 \
-DPOWER_LIMIT_DC=28
-DPOWER_LIMIT_DC=45
# Custom fan curve
CFLAGS+=-DBOARD_FAN_POINTS="\
# Enable dGPU support
CONFIG_HAVE_DGPU = y
CFLAGS += -DI2C_DGPU=I2C_1
# Fan configs
CFLAGS += -DFAN1_PWM=DCR2
CFLAGS += -DBOARD_FAN1_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100) \
FAN_POINT(80, 100), \
"
# Enable DGPU support
CFLAGS+=-DHAVE_DGPU=1
CFLAGS+=-DBOARD_DGPU_FAN_POINTS="\
CFLAGS += -DFAN2_PWM=DCR4
CFLAGS += -DBOARD_FAN2_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100) \
FAN_POINT(80, 100), \
"
# Add system76 common code

View File

@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/gpio.h>
#include <common/debug.h>
#include <common/macro.h>
// clang-format off
// uncrustify:off
struct Gpio __code ACIN_N = GPIO(B, 6);
struct Gpio __code AC_PRESENT = GPIO(E, 7);
struct Gpio __code ALL_SYS_PWRGD = GPIO(C, 0);
@@ -26,10 +26,12 @@ struct Gpio __code LED_NUM_N = GPIO(J, 4);
struct Gpio __code LED_PWR = GPIO(H, 5);
struct Gpio __code LED_SCROLL_N = GPIO(J, 3);
struct Gpio __code LID_SW_N = GPIO(D, 1);
struct Gpio __code ME_WE = GPIO(I, 2);
struct Gpio __code PM_CLKRUN_N = GPIO(H, 0); // renamed to ECCLKRUN#
struct Gpio __code PM_PWROK = GPIO(C, 6);
struct Gpio __code PWR_BTN_N = GPIO(D, 5);
struct Gpio __code PWR_SW_N = GPIO(D, 0);
struct Gpio __code RGBKB_DET_N = GPIO(E, 2);
struct Gpio __code SB_KBCRST_N = GPIO(E, 6);
struct Gpio __code SCI_N = GPIO(D, 4);
struct Gpio __code SMI_N = GPIO(D, 3);
@@ -40,9 +42,9 @@ struct Gpio __code USB_PWR_EN_N = GPIO(F, 7);
struct Gpio __code VA_EC_EN = GPIO(J, 0); // renamed to SLP_SUS_EC#
struct Gpio __code WLAN_EN = GPIO(J, 2);
struct Gpio __code WLAN_PWR_EN = GPIO(B, 0);
// clang-format on
// uncrustify:on
void gpio_init() {
void gpio_init(void) {
// Enable LPC reset on GPD2
GCR = 0x04;
@@ -103,11 +105,11 @@ void gpio_init() {
// SMD_VGA_THERM
GPCRC2 = GPIO_OUT;
// KB-SO16
GPCRC3 = GPIO_IN | GPIO_UP;
GPCRC3 = GPIO_ALT | GPIO_UP;
// CNVI_DET#_EC
GPCRC4 = GPIO_IN | GPIO_UP;
// KB-SO17
GPCRC5 = GPIO_IN | GPIO_UP;
GPCRC5 = GPIO_ALT | GPIO_UP;
// PM_PWROK
GPCRC6 = GPIO_OUT;
// LED_ACIN
@@ -190,8 +192,6 @@ void gpio_init() {
GPCRH5 = GPIO_OUT | GPIO_UP;
// SUSB#_PCH
GPCRH6 = GPIO_IN;
// TODO
GPCRH7 = GPIO_IN;
// BAT_DET
GPCRI0 = GPIO_ALT;
// BAT_VOLT
@@ -239,40 +239,3 @@ void gpio_init() {
// SERIRQ
GPCRM6 = GPIO_ALT;
}
#if GPIO_DEBUG
void gpio_debug_bank(
char * bank,
uint8_t data,
uint8_t mirror,
uint8_t pot,
volatile uint8_t * control
) {
for(char i = 0; i < 8; i++) {
DEBUG(
"%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n",
bank,
i,
(data >> i) & 1,
(mirror >> i) & 1,
(pot >> i) & 1,
*(control + i)
);
}
}
void gpio_debug(void) {
#define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0)
bank(A);
bank(B);
bank(C);
bank(D);
bank(E);
bank(F);
bank(G);
bank(H);
bank(I);
bank(J);
#undef bank
}
#endif

View File

@@ -6,9 +6,7 @@
#include <ec/gpio.h>
void gpio_init(void);
void gpio_debug(void);
// clang-format off
extern struct Gpio __code ACIN_N;
extern struct Gpio __code AC_PRESENT;
extern struct Gpio __code ALL_SYS_PWRGD;
@@ -31,12 +29,14 @@ extern struct Gpio __code LED_NUM_N;
extern struct Gpio __code LED_PWR;
extern struct Gpio __code LED_SCROLL_N;
extern struct Gpio __code LID_SW_N;
extern struct Gpio __code ME_WE;
#define HAVE_PCH_DPWROK_EC 0
#define HAVE_PCH_PWROK_EC 0
extern struct Gpio __code PM_CLKRUN_N;
extern struct Gpio __code PM_PWROK;
extern struct Gpio __code PWR_BTN_N;
extern struct Gpio __code PWR_SW_N;
extern struct Gpio __code RGBKB_DET_N;
extern struct Gpio __code SB_KBCRST_N;
extern struct Gpio __code SCI_N;
#define HAVE_SLP_SUS_N 0
@@ -52,6 +52,5 @@ extern struct Gpio __code VA_EC_EN;
extern struct Gpio __code WLAN_EN;
extern struct Gpio __code WLAN_PWR_EN;
#define HAVE_XLP_OUT 0
// clang-format on
#endif // _BOARD_GPIO_H

View File

@@ -4,7 +4,6 @@
#include <board/gctrl.h>
#include <board/gpio.h>
#include <board/kbc.h>
#include <board/power.h>
#include <common/debug.h>
#include <ec/ec.h>
@@ -15,9 +14,6 @@ void board_init(void) {
gpio_set(&BKL_EN, true);
// Enable camera
gpio_set(&CCD_EN, true);
// Enable wireless
gpio_set(&WLAN_EN, true);
gpio_set(&WLAN_PWR_EN, true);
// Assert SMI#, SCI#, and SWI#
gpio_set(&SCI_N, true);
gpio_set(&SMI_N, true);
@@ -25,8 +21,6 @@ void board_init(void) {
}
void board_event(void) {
power_set_limit();
ec_read_post_codes();
if (main_cycle == 0) {

View File

@@ -1,16 +1,22 @@
# SPDX-License-Identifier: GPL-3.0-only
EC=it5570e
board-y += board.c
board-y += gpio.c
EC=ite
CONFIG_EC_ITE_IT5570E=y
CONFIG_EC_FLASH_SIZE_128K = y
# Intel-based host
CONFIG_PLATFORM_INTEL = y
# Include keyboard
KEYBOARD=15in_102
# Set keyboard LED mechanism
CONFIG_HAVE_KBLED = y
KBLED=rgb_pwm
# Set discrete GPU I2C bus
CFLAGS+=-DI2C_DGPU=I2C_1
# Set battery I2C bus
CFLAGS+=-DI2C_SMBUS=I2C_4
@@ -19,32 +25,38 @@ CFLAGS+=-DPS2_TOUCHPAD=PS2_3
# Set smart charger parameters
CFLAGS+=\
-DCHARGER_CHARGE_CURRENT=1536 \
-DCHARGER_ADAPTER_RSENSE=5 \
-DCHARGER_BATTERY_RSENSE=10 \
-DCHARGER_CHARGE_CURRENT=3072 \
-DCHARGER_CHARGE_VOLTAGE=12600 \
-DCHARGER_INPUT_CURRENT=11800
# Set CPU power limits in watts
CFLAGS+=\
-DPOWER_LIMIT_AC=180 \
-DPOWER_LIMIT_DC=28
-DPOWER_LIMIT_DC=45
# Custom fan curve
CFLAGS+=-DBOARD_FAN_POINTS="\
# Enable dGPU support
CONFIG_HAVE_DGPU = y
CFLAGS += -DI2C_DGPU=I2C_1
# Fan configs
CFLAGS += -DFAN1_PWM=DCR2
CFLAGS += -DBOARD_FAN1_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100) \
FAN_POINT(80, 100), \
"
# Enable DGPU support
CFLAGS+=-DHAVE_DGPU=1
CFLAGS+=-DBOARD_DGPU_FAN_POINTS="\
CFLAGS += -DFAN2_PWM=DCR4
CFLAGS += -DBOARD_FAN2_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100) \
FAN_POINT(80, 100), \
"
# Add system76 common code

View File

@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/gpio.h>
#include <common/debug.h>
#include <common/macro.h>
// clang-format off
// uncrustify:off
struct Gpio __code ACIN_N = GPIO(B, 0);
struct Gpio __code AC_PRESENT = GPIO(E, 1);
struct Gpio __code ALL_SYS_PWRGD = GPIO(C, 0);
@@ -25,10 +25,12 @@ struct Gpio __code LED_NUM_N = GPIO(G, 0);
struct Gpio __code LED_PWR = GPIO(D, 0);
struct Gpio __code LED_SCROLL_N = GPIO(J, 3);
struct Gpio __code LID_SW_N = GPIO(B, 1);
struct Gpio __code ME_WE = GPIO(I, 2);
struct Gpio __code PM_CLKRUN_N = GPIO(H, 0); // renamed to ECCLKRUN#
struct Gpio __code PM_PWROK = GPIO(C, 6);
struct Gpio __code PWR_BTN_N = GPIO(D, 5);
struct Gpio __code PWR_SW_N = GPIO(B, 3);
struct Gpio __code RGBKB_DET_N = GPIO(I, 5);
struct Gpio __code SCI_N = GPIO(D, 3);
struct Gpio __code SMI_N = GPIO(D, 4);
struct Gpio __code SUSB_N_PCH = GPIO(H, 6);
@@ -38,9 +40,14 @@ struct Gpio __code VA_EC_EN = GPIO(J, 4);
struct Gpio __code WLAN_EN = GPIO(G, 1);
struct Gpio __code WLAN_PWR_EN = GPIO(J, 7);
struct Gpio __code XLP_OUT = GPIO(B, 4);
// clang-format on
// uncrustify:on
void gpio_init(void) {
// PWRSW WDT 2 Enable 2
GCR9 = BIT(5);
// PWRSW WDT 2 Enable 1
GCR8 = BIT(4);
void gpio_init() {
// Enable LPC reset on GPD2
GCR = 0x04;
// Enable SMBus channel 4
@@ -98,8 +105,6 @@ void gpio_init() {
GPCRB5 = GPIO_OUT | GPIO_UP;
// SUSBC_EN
GPCRB6 = GPIO_OUT | GPIO_UP;
//
GPCRB7 = GPIO_IN;
// ALL_SYS_PWRGD
GPCRC0 = GPIO_IN;
// SMC_VGA_THERM
@@ -107,11 +112,11 @@ void gpio_init() {
// SMD_VGA_THERM
GPCRC2 = GPIO_ALT;
// KB-SO16
GPCRC3 = GPIO_IN;
GPCRC3 = GPIO_ALT | GPIO_UP;
// CNVI_DET#_EC
GPCRC4 = GPIO_IN | GPIO_UP;
// KB-SO17
GPCRC5 = GPIO_IN;
GPCRC5 = GPIO_ALT | GPIO_UP;
// PM_PWROK
GPCRC6 = GPIO_OUT;
// LED_ACIN
@@ -243,40 +248,3 @@ void gpio_init() {
// SERIRQ
GPCRM6 = GPIO_ALT;
}
#if GPIO_DEBUG
void gpio_debug_bank(
char * bank,
uint8_t data,
uint8_t mirror,
uint8_t pot,
volatile uint8_t * control
) {
for(char i = 0; i < 8; i++) {
DEBUG(
"%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n",
bank,
i,
(data >> i) & 1,
(mirror >> i) & 1,
(pot >> i) & 1,
*(control + i)
);
}
}
void gpio_debug(void) {
#define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0)
bank(A);
bank(B);
bank(C);
bank(D);
bank(E);
bank(F);
bank(G);
bank(H);
bank(I);
bank(J);
#undef bank
}
#endif

View File

@@ -6,13 +6,12 @@
#include <ec/gpio.h>
void gpio_init(void);
void gpio_debug(void);
// clang-format off
extern struct Gpio __code ACIN_N;
extern struct Gpio __code AC_PRESENT;
extern struct Gpio __code ALL_SYS_PWRGD;
extern struct Gpio __code BKL_EN;
#define HAVE_BT_EN 0
extern struct Gpio __code BUF_PLT_RST_N;
extern struct Gpio __code CCD_EN;
extern struct Gpio __code DD_ON;
@@ -30,12 +29,14 @@ extern struct Gpio __code LED_NUM_N;
extern struct Gpio __code LED_PWR;
extern struct Gpio __code LED_SCROLL_N;
extern struct Gpio __code LID_SW_N;
extern struct Gpio __code ME_WE;
#define HAVE_PCH_DPWROK_EC 0
#define HAVE_PCH_PWROK_EC 0
extern struct Gpio __code PM_CLKRUN_N; // renamed to ECCLKRUN#
extern struct Gpio __code PM_PWROK;
extern struct Gpio __code PWR_BTN_N;
extern struct Gpio __code PWR_SW_N;
extern struct Gpio __code RGBKB_DET_N;
extern struct Gpio __code SCI_N;
#define HAVE_SLP_SUS_N 0
extern struct Gpio __code SMI_N;
@@ -48,6 +49,5 @@ extern struct Gpio __code VA_EC_EN;
extern struct Gpio __code WLAN_EN;
extern struct Gpio __code WLAN_PWR_EN;
extern struct Gpio __code XLP_OUT;
// clang-format on
#endif // _BOARD_GPIO_H

View File

@@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/battery.h>
#include <board/board.h>
#include <board/espi.h>
#include <board/gctrl.h>
#include <board/gpio.h>
#include <common/debug.h>
#include <ec/ec.h>
void board_init(void) {
espi_init();
// Make sure charger is in off state, also enables PSYS
battery_charger_disable();
// Allow backlight to be turned on
gpio_set(&BKL_EN, true);
// Enable camera
gpio_set(&CCD_EN, true);
}
void board_event(void) {
espi_event();
ec_read_post_codes();
}

View File

@@ -0,0 +1,74 @@
# SPDX-License-Identifier: GPL-3.0-only
board-y += board.c
board-y += gpio.c
EC=ite
CONFIG_EC_ITE_IT5570E=y
CONFIG_EC_FLASH_SIZE_128K = y
# Intel-based host
CONFIG_PLATFORM_INTEL = y
CONFIG_BUS_ESPI=y
# Enable firmware security
CONFIG_SECURITY=y
# Include keyboard
KEYBOARD=15in_102
# Set keyboard LED mechanism
CONFIG_HAVE_KBLED = y
KBLED=rgb_pwm
# Set battery I2C bus
CFLAGS+=-DI2C_SMBUS=I2C_4
# Set touchpad PS2 bus
CFLAGS+=-DPS2_TOUCHPAD=PS2_3
# Set smart charger parameters
# TODO: actually bq24800
# FIXME: Verify parts and values.
CHARGER=bq24780s
CFLAGS+=\
-DCHARGER_ADAPTER_RSENSE=5 \
-DCHARGER_BATTERY_RSENSE=10 \
-DCHARGER_CHARGE_CURRENT=1536 \
-DCHARGER_CHARGE_VOLTAGE=17600 \
-DCHARGER_INPUT_CURRENT=14000
# Set CPU power limits in watts
CFLAGS+=\
-DPOWER_LIMIT_AC=280 \
-DPOWER_LIMIT_DC=55
# Enable dGPU support
CONFIG_HAVE_DGPU = y
CFLAGS += -DI2C_DGPU=I2C_1
# Fan configs
CFLAGS += -DFAN1_PWM=DCR2
CFLAGS += -DBOARD_FAN1_HEATUP=5
CFLAGS += -DBOARD_FAN1_COOLDOWN=20
CFLAGS += -DBOARD_FAN1_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100), \
"
CFLAGS += -DFAN2_PWM=DCR4
CFLAGS += -DBOARD_FAN2_HEATUP=5
CFLAGS += -DBOARD_FAN2_COOLDOWN=20
CFLAGS += -DBOARD_FAN2_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100), \
"
# Add system76 common code
include src/board/system76/common/common.mk

View File

@@ -0,0 +1,272 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/gpio.h>
#include <common/macro.h>
// uncrustify:off
struct Gpio __code ACIN_N = GPIO(B, 0);
struct Gpio __code AC_PRESENT = GPIO(E, 1);
struct Gpio __code ALL_SYS_PWRGD = GPIO(C, 0);
struct Gpio __code BKL_EN = GPIO(C, 7);
struct Gpio __code BUF_PLT_RST_N = GPIO(D, 2); // renamed to ESPI_RESET_N
struct Gpio __code CCD_EN = GPIO(D, 1);
struct Gpio __code DD_ON = GPIO(E, 4);
struct Gpio __code DGPU_PWR_EN = GPIO(J, 2);
struct Gpio __code EC_EN = GPIO(B, 6); // renamed to SUSBC_EN#
struct Gpio __code EC_RSMRST_N = GPIO(E, 5);
struct Gpio __code GC6_FB_EN = GPIO(J, 3);
struct Gpio __code LAN_WAKEUP_N = GPIO(B, 2);
struct Gpio __code LED_ACIN = GPIO(H, 2);
struct Gpio __code LED_BAT_CHG = GPIO(H, 5);
struct Gpio __code LED_BAT_FULL = GPIO(J, 0);
struct Gpio __code LED_PWR = GPIO(D, 0);
struct Gpio __code LID_SW_N = GPIO(B, 1);
struct Gpio __code ME_WE = GPIO(H, 0);
struct Gpio __code PCH_DPWROK_EC = GPIO(F, 3);
struct Gpio __code PM_PWROK = GPIO(C, 6);
struct Gpio __code PWR_BTN_N = GPIO(D, 5);
struct Gpio __code PWR_SW_N = GPIO(B, 3);
struct Gpio __code RGBKB_DET_N = GPIO(E, 2);
struct Gpio __code SLP_SUS_N = GPIO(H, 7);
struct Gpio __code VA_EC_EN = GPIO(J, 4);
struct Gpio __code WLAN_EN = GPIO(G, 1);
struct Gpio __code WLAN_PWR_EN = GPIO(D, 3);
struct Gpio __code XLP_OUT = GPIO(B, 4);
// uncrustify:on
void gpio_init(void) {
// PWRSW WDT 2 Enable 2
GCR9 = BIT(5);
// PWRSW WDT 2 Enable 1
GCR8 = BIT(4);
// Enable LPC reset on GPD2
GCR = 0x04;
// Disable UARTs
GCR6 = 0;
// Enable SMBus channel 4
GCR15 = BIT(4);
// Set GPD2 to 1.8V
GCR19 = BIT(0);
// Set GPF2 and GPF3 to 3.3V
GCR20 = 0;
//TODO: what do these do?
GCR1 = 0;
GCR2 = 0;
GCR10 = 0x02;
GCR21 = 0;
GCR22 = 0x80;
GCR22 = 0x80;
GCR23 = 0x01;
// Set GPIO data
GPDRA = 0;
// BL_PWM_EN_EC, XLP_OUT
GPDRB = BIT(5) | BIT(4);
GPDRC = 0;
// PLVDD_RST_EC
GPDRD = BIT(4);
// USB_PWR_EN
GPDRE = BIT(3);
// PCH_DPWROK_EC
GPDRF = BIT(3);
// H_PROCHOT_EC
GPDRG = BIT(6);
GPDRH = 0;
GPDRI = 0;
// CC_EN
GPDRJ = BIT(7);
GPOTA = 0;
GPOTB = 0;
GPOTD = 0;
GPOTE = 0;
GPOTF = 0;
GPOTH = 0;
GPOTJ = 0;
// Set GPIO control
// EC_PWM_LEDKB_P
GPCRA0 = GPIO_ALT;
// KBC_BEEP
GPCRA1 = GPIO_ALT;
// CPU_FAN
GPCRA2 = GPIO_ALT;
// DDS_EC_PWM
GPCRA3 = GPIO_IN;
// VGA_FAN
GPCRA4 = GPIO_ALT;
// EC_PWM_LEDKB_R
GPCRA5 = GPIO_ALT;
// EC_PWM_LEDKB_G
GPCRA6 = GPIO_ALT;
// EC_PWM_LEDKB_B
GPCRA7 = GPIO_ALT;
// AC_IN#
GPCRB0 = GPIO_IN | GPIO_UP;
// LID_SW#
GPCRB1 = GPIO_IN | GPIO_UP;
// LAN_WAKEUP#
GPCRB2 = GPIO_IN;
// PWR_SW#
GPCRB3 = GPIO_IN;
// XLP_OUT
GPCRB4 = GPIO_OUT;
// BL_PWM_EN_EC
GPCRB5 = GPIO_OUT;
// SUSBC_EC#
GPCRB6 = GPIO_OUT | GPIO_UP;
// ALL_SYS_PWRGD
GPCRC0 = GPIO_IN;
// SMC_VGA_THERM
GPCRC1 = GPIO_ALT | GPIO_UP;
// SMD_VGA_THERM
GPCRC2 = GPIO_ALT | GPIO_UP;
// KB_SO16
GPCRC3 = GPIO_ALT | GPIO_UP;
// CNVI_DET#
GPCRC4 = GPIO_IN | GPIO_UP;
// KB_SO17
GPCRC5 = GPIO_ALT | GPIO_UP;
// PM_PWROK
GPCRC6 = GPIO_OUT;
// BKL_EN
GPCRC7 = GPIO_OUT | GPIO_UP;
// LED_PWR
GPCRD0 = GPIO_OUT | GPIO_UP;
// CCD_EN
GPCRD1 = GPIO_OUT;
// ESPI_RESET#
GPCRD2 = GPIO_ALT;
// WLAN_PWR_EN
GPCRD3 = GPIO_OUT;
// PLVDD_RST_EC
GPCRD4 = GPIO_OUT;
// PWR_BTN#
GPCRD5 = GPIO_OUT | GPIO_UP;
// CPU_FANSEN
GPCRD6 = GPIO_ALT;
// VGA_FANSEN
GPCRD7 = GPIO_ALT;
// SMC_BAT
GPCRE0 = GPIO_ALT | GPIO_UP;
// AC_PRESENT
GPCRE1 = GPIO_OUT | GPIO_UP;
// RGBKB-DET#
GPCRE2 = GPIO_IN | GPIO_UP;
// USB_PWR_EN
GPCRE3 = GPIO_OUT;
// DD_ON
GPCRE4 = GPIO_OUT | GPIO_DOWN;
// EC_RSMRST#
GPCRE5 = GPIO_OUT;
// SB_KBCRST#
GPCRE6 = GPIO_IN;
// SMD_BAT
GPCRE7 = GPIO_ALT | GPIO_UP;
// 80CLK
GPCRF0 = GPIO_IN;
// USB_CHARGE_EN
GPCRF1 = GPIO_OUT | GPIO_UP;
// 3IN1
GPCRF2 = GPIO_IN | GPIO_UP;
// PCH_DPWROK_EC
GPCRF3 = GPIO_OUT;
// TP_CLK
GPCRF4 = GPIO_ALT | GPIO_UP;
// TP_DATA
GPCRF5 = GPIO_ALT | GPIO_UP;
// H_PECI
GPCRF6 = GPIO_ALT;
// SINK_CTRL
GPCRF7 = GPIO_IN;
// EC_GPG0
GPCRG0 = GPIO_IN;
// WLAN_EN
GPCRG1 = GPIO_OUT;
// AUTO_LOAD_PWR
GPCRG2 = GPIO_IN;
// ALSPI_CE#
GPCRG3 = GPIO_ALT;
// ALSPI_MSI
GPCRG4 = GPIO_ALT;
// ALSPI_MSO
GPCRG5 = GPIO_ALT;
// H_PROCHOT_EC
GPCRG6 = GPIO_OUT | GPIO_UP;
// ALSPI_SCLK
GPCRG7 = GPIO_ALT;
// ME_WE
GPCRH0 = GPIO_OUT;
// SUSC#_PCH
GPCRH1 = GPIO_IN;
// LED_ACIN
GPCRH2 = GPIO_OUT | GPIO_UP;
// MUX_CTRL_BIOS
GPCRH3 = GPIO_OUT;
// ACE_I2C_IRQ2Z_EC
GPCRH4 = GPIO_IN;
// LED_BAT_CHG
GPCRH5 = GPIO_OUT | GPIO_UP;
// SUSB#_PCH
GPCRH6 = GPIO_IN;
// SLP_SUS#
GPCRH7 = GPIO_IN;
// BAT_DET
GPCRI0 = GPIO_ALT;
// BAT_VOLT
GPCRI1 = GPIO_ALT;
// THERM_VOLT2
GPCRI2 = GPIO_ALT;
// THERM_VOLT
GPCRI3 = GPIO_ALT;
// TOTAL_CUR
GPCRI4 = GPIO_ALT;
// CC1_DET
GPCRI5 = GPIO_IN;
// CC2_DET
GPCRI6 = GPIO_IN;
// MODEL_ID
GPCRI7 = GPIO_IN;
// LED_BAT_FULL
GPCRJ0 = GPIO_OUT | GPIO_UP;
// KBC_MUTE#
GPCRJ1 = GPIO_IN;
// DGPU_PWR_EN
GPCRJ2 = GPIO_IN;
// GC6_FB_EN_PCH
GPCRJ3 = GPIO_IN;
// VA_EC_EN
GPCRJ4 = GPIO_OUT;
// VBATT_BOOST#
GPCRJ5 = GPIO_IN;
// EC_GPIO
GPCRJ6 = GPIO_IN;
// CC_EN
GPCRJ7 = GPIO_OUT;
// ESPI_IO0_EC
GPCRM0 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_IO1_EC
GPCRM1 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_IO2_EC
GPCRM2 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_IO3_EC
GPCRM3 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_CLK_EC
GPCRM4 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_CS_EC#
GPCRM5 = GPIO_ALT;
// SERIRQ_ESPI_ALERT0
GPCRM6 = GPIO_IN | GPIO_UP | GPIO_DOWN;
}

View File

@@ -0,0 +1,43 @@
// SPDX-License-Identifier: GPL-3.0-only
#ifndef _BOARD_GPIO_H
#define _BOARD_GPIO_H
#include <ec/gpio.h>
void gpio_init(void);
extern struct Gpio __code ACIN_N;
extern struct Gpio __code AC_PRESENT;
extern struct Gpio __code ALL_SYS_PWRGD;
extern struct Gpio __code BKL_EN;
#define HAVE_BT_EN 0
extern struct Gpio __code BUF_PLT_RST_N;
extern struct Gpio __code CCD_EN;
extern struct Gpio __code DD_ON;
extern struct Gpio __code DGPU_PWR_EN;
extern struct Gpio __code EC_EN;
extern struct Gpio __code EC_RSMRST_N;
extern struct Gpio __code GC6_FB_EN;
extern struct Gpio __code LAN_WAKEUP_N;
extern struct Gpio __code LED_ACIN;
#define HAVE_LED_AIRPLANE_N 0
extern struct Gpio __code LED_BAT_CHG;
extern struct Gpio __code LED_BAT_FULL;
extern struct Gpio __code LED_PWR;
extern struct Gpio __code LID_SW_N;
extern struct Gpio __code ME_WE;
extern struct Gpio __code PCH_DPWROK_EC;
#define HAVE_PCH_PWROK_EC 0
extern struct Gpio __code PM_PWROK;
extern struct Gpio __code PWR_BTN_N;
extern struct Gpio __code PWR_SW_N;
extern struct Gpio __code RGBKB_DET_N;
extern struct Gpio __code SLP_SUS_N;
#define HAVE_SUS_PWR_ACK 0
extern struct Gpio __code VA_EC_EN;
extern struct Gpio __code WLAN_EN;
extern struct Gpio __code WLAN_PWR_EN;
extern struct Gpio __code XLP_OUT;
#endif // _BOARD_GPIO_H

View File

@@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/battery.h>
#include <board/board.h>
#include <board/espi.h>
#include <board/gctrl.h>
#include <board/gpio.h>
#include <common/debug.h>
#include <ec/ec.h>
void board_init(void) {
espi_init();
// Make sure charger is in off state, also enables PSYS
battery_charger_disable();
// Allow backlight to be turned on
gpio_set(&BKL_EN, true);
// Enable camera
gpio_set(&CCD_EN, true);
}
void board_event(void) {
espi_event();
ec_read_post_codes();
}

View File

@@ -0,0 +1,74 @@
# SPDX-License-Identifier: GPL-3.0-only
board-y += board.c
board-y += gpio.c
EC = ite
CONFIG_EC_ITE_IT5570E = y
CONFIG_EC_FLASH_SIZE_256K = y
# Intel-based host
CONFIG_PLATFORM_INTEL = y
CONFIG_BUS_ESPI = y
CONFIG_PECI_OVER_ESPI = y
# Enable firmware security
CONFIG_SECURITY = y
# Set keyboard configs
KEYBOARD = 18H9LHA04
CONFIG_HAVE_KBLED = y
KBLED = rgb_pwm
# Set touchpad PS2 bus
CFLAGS += -DPS2_TOUCHPAD=PS2_3
# Set smart charger parameters
CHARGER = oz26786
CFLAGS += -DI2C_SMBUS=I2C_4
CFLAGS += \
-DCHARGER_ADAPTER_RSENSE=5 \
-DCHARGER_BATTERY_RSENSE=10 \
-DCHARGER_CHARGE_CURRENT=3072 \
-DCHARGER_CHARGE_VOLTAGE=17400 \
-DCHARGER_INPUT_CURRENT=11500
# Set CPU power limits in watts
CFLAGS += \
-DPOWER_LIMIT_AC=230 \
-DPOWER_LIMIT_DC=45
# Enable DGPU support
CONFIG_HAVE_DGPU = y
CFLAGS += -DI2C_DGPU=I2C_1
# Fan configs
CFLAGS += -DFAN1_PWM=DCR2
CFLAGS += -DBOARD_FAN1_HEATUP=5
CFLAGS += -DBOARD_FAN1_COOLDOWN=20
CFLAGS += -DBOARD_FAN1_POINTS="\
FAN_POINT(60, 28), \
FAN_POINT(65, 28), \
FAN_POINT(70, 40), \
FAN_POINT(75, 60), \
FAN_POINT(80, 75), \
FAN_POINT(85, 90), \
FAN_POINT(90, 100), \
"
CFLAGS += -DFAN2_PWM=DCR4
CFLAGS += -DBOARD_FAN2_HEATUP=5
CFLAGS += -DBOARD_FAN2_COOLDOWN=20
CFLAGS += -DBOARD_FAN2_POINTS="\
FAN_POINT(60, 28), \
FAN_POINT(65, 28), \
FAN_POINT(70, 40), \
FAN_POINT(75, 60), \
FAN_POINT(80, 75), \
FAN_POINT(85, 90), \
FAN_POINT(90, 100), \
"
# Add system76 common code
include src/board/system76/common/common.mk

View File

@@ -0,0 +1,259 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/gpio.h>
#include <common/macro.h>
// uncrustify:off
struct Gpio __code ACIN_N = GPIO(B, 0);
struct Gpio __code AC_PRESENT = GPIO(E, 1);
struct Gpio __code ALL_SYS_PWRGD = GPIO(C, 0);
struct Gpio __code BKL_EN = GPIO(C, 7);
struct Gpio __code BUF_PLT_RST_N = GPIO(D, 2); // renamed to ESPI_RESET_N
struct Gpio __code CCD_EN = GPIO(D, 1);
struct Gpio __code DD_ON = GPIO(E, 4);
struct Gpio __code DGPU_PWR_EN = GPIO(H, 6);
struct Gpio __code EC_EN = GPIO(B, 6); // renamed to SUSBC_EN#
struct Gpio __code EC_RSMRST_N = GPIO(E, 5);
struct Gpio __code GC6_FB_EN = GPIO(B, 5);
struct Gpio __code LAN_WAKEUP_N = GPIO(B, 2);
struct Gpio __code LED_ACIN = GPIO(H, 2);
struct Gpio __code LED_BAT_CHG = GPIO(H, 5);
struct Gpio __code LED_BAT_FULL = GPIO(J, 0);
struct Gpio __code LED_PWR = GPIO(D, 0);
struct Gpio __code LID_SW_N = GPIO(B, 1);
struct Gpio __code ME_WE = GPIO(I, 2);
struct Gpio __code PCH_DPWROK_EC = GPIO(F, 3);
struct Gpio __code PM_PWROK = GPIO(C, 6);
struct Gpio __code PWR_BTN_N = GPIO(D, 5);
struct Gpio __code PWR_SW_N = GPIO(B, 3);
struct Gpio __code RGBKB_DET_N = GPIO(E, 2);
struct Gpio __code SLP_SUS_N = GPIO(H, 7);
struct Gpio __code VA_EC_EN = GPIO(J, 4);
//struct Gpio __code WLAN_EN = GPIO(G, 1);
struct Gpio __code WLAN_PWR_EN = GPIO(H, 3);
struct Gpio __code XLP_OUT = GPIO(B, 4);
// uncrustify:on
void gpio_init(void) {
// PWRSW WDT 2 Enable 2
GCR9 = BIT(5);
// PWRSW WDT 2 Enable 1
GCR8 = BIT(4);
// Enable LPC reset on GPD2
GCR = 0x04;
// Disable UARTs
GCR6 = 0;
// Enable SMBus channel 4
GCR15 = BIT(4);
// Set GPD2 to 1.8V
GCR19 = BIT(0);
// Set GPF2 and GPF3 to 3.3V
GCR20 = 0;
// Set GPM6 power domain to VCC
GCR23 = BIT(0);
// Set GPIO data
// DDS_EC_PWM
GPDRA = BIT(3);
// XLP_OUT, PWR_SW#
GPDRB = BIT(4) | BIT(3);
GPDRC = 0;
// VGA_HEATSINK_SW
GPDRD = BIT(3);
// USB_PWR_EN#
GPDRE = BIT(3);
GPDRF = 0;
// H_PROCHOT_EC, BL_PWM_EN_EC
GPDRG = BIT(6) | BIT(0);
GPDRH = 0;
GPDRI = 0;
// PLVDD_RST_EC, KBC_MUTE#
GPDRJ = BIT(7) | BIT(1);
// Set GPIO control
// EC_PWM_LEDKB_P
GPCRA0 = GPIO_ALT;
// KBC_BEEP
GPCRA1 = GPIO_ALT;
// CPU_FAN_PWM
GPCRA2 = GPIO_ALT;
// DDS_EC_PWM
GPCRA3 = GPIO_IN;
// VGA_FAN_PWM
GPCRA4 = GPIO_ALT;
// EC_PWM_LEDKB_R
GPCRA5 = GPIO_ALT;
// EC_PWM_LEDKB_G
GPCRA6 = GPIO_ALT;
// EC_PWM_LEDKB_B
GPCRA7 = GPIO_ALT;
// AC_IN#
GPCRB0 = GPIO_IN | GPIO_UP;
// LID_SW#
GPCRB1 = GPIO_IN | GPIO_UP;
// EC_LAN_WAKEUP#
GPCRB2 = GPIO_IN;
// PWR_SW#
GPCRB3 = GPIO_IN;
// XLP_OUT
GPCRB4 = GPIO_OUT;
// GC6_FB_EN_PCH
GPCRB5 = GPIO_IN;
// SUSBC_EC#
GPCRB6 = GPIO_OUT | GPIO_UP;
// ALL_SYS_PWRGD
GPCRC0 = GPIO_IN;
// SMC_VGA_THERM
GPCRC1 = GPIO_ALT | GPIO_UP;
// SMD_VGA_THERM
GPCRC2 = GPIO_ALT | GPIO_UP;
// KB-SO16
GPCRC3 = GPIO_ALT | GPIO_UP;
// CNVI_DET#
GPCRC4 = GPIO_IN | GPIO_UP;
// KB-SO17
GPCRC5 = GPIO_ALT | GPIO_UP;
// PM_PWROK
GPCRC6 = GPIO_OUT;
// BKL_EN
GPCRC7 = GPIO_OUT | GPIO_UP;
// LED_PWR
GPCRD0 = GPIO_OUT | GPIO_UP;
// CCD_EN
GPCRD1 = GPIO_OUT;
// ESPI_RESET#
GPCRD2 = GPIO_ALT;
// VGA_HEATSINK_SW
GPCRD3 = GPIO_OUT;
// 7411_SINK_CTRL
GPCRD4 = GPIO_IN;
// PWR_BTN#
GPCRD5 = GPIO_OUT | GPIO_UP;
// CPU_FANSEN
GPCRD6 = GPIO_ALT;
// VGA_HEATSINK_FANSEN
GPCRD7 = GPIO_ALT;
// SMC_BAT
GPCRE0 = GPIO_ALT | GPIO_UP;
// AC_PRESENT
GPCRE1 = GPIO_OUT | GPIO_UP;
// RGBKB-DET#
GPCRE2 = GPIO_IN | GPIO_UP;
// USB_PWR_EN# (XXX: Active high, despite pin name)
GPCRE3 = GPIO_OUT;
// DD_ON
GPCRE4 = GPIO_OUT | GPIO_DOWN;
// EC_RSMRST#
GPCRE5 = GPIO_OUT;
// JACK_IN#_EC
GPCRE6 = GPIO_IN;
// SMD_BAT
GPCRE7 = GPIO_ALT | GPIO_UP;
// 80CLK
GPCRF0 = GPIO_IN;
// USB_CHARGE_EN
GPCRF1 = GPIO_OUT | GPIO_UP;
// 3IN1
GPCRF2 = GPIO_IN | GPIO_UP;
// PCH_DPWROK_EC
GPCRF3 = GPIO_OUT;
// TP_CLK
GPCRF4 = GPIO_ALT | GPIO_UP;
// TP_DATA
GPCRF5 = GPIO_ALT | GPIO_UP;
// EC_SMD_EN#
GPCRF6 = GPIO_IN;
// MUX_CTRL_BIOS
GPCRF7 = GPIO_OUT;
// BL_PWM_EN_EC
GPCRG0 = GPIO_OUT;
// EC_WLAN_EN (NC)
GPCRG1 = GPIO_IN;
// AUTO_LOAD_PWR
GPCRG2 = GPIO_IN;
// ALSPI_CE#
GPCRG3 = GPIO_ALT;
// ALSPI_MSI
GPCRG4 = GPIO_ALT;
// ALSPI_MSO
GPCRG5 = GPIO_ALT;
// H_PROCHOT_EC
GPCRG6 = GPIO_OUT | GPIO_UP;
// ALSPI_SCLK
GPCRG7 = GPIO_ALT;
// PM_SLP_S0_CS_N
GPCRH0 = GPIO_IN;
// EC_TEST_R_2
GPCRH1 = GPIO_IN;
// LED_ACIN
GPCRH2 = GPIO_OUT | GPIO_UP;
// WLAN_PWR_EN
GPCRH3 = GPIO_OUT;
// OVERT#_EC
GPCRH4 = GPIO_IN | GPIO_UP;
// LED_BAT_CHG
GPCRH5 = GPIO_OUT | GPIO_UP;
// DGPU_PWR_EN
GPCRH6 = GPIO_IN;
// SLP_SUS#
GPCRH7 = GPIO_IN;
// BAT_DET
GPCRI0 = GPIO_ALT;
// BAT_VOLT
GPCRI1 = GPIO_ALT;
// ME_WE
GPCRI2 = GPIO_OUT;
// THERM_VOLT_CPU
GPCRI3 = GPIO_ALT;
// TOTAL_CUR
GPCRI4 = GPIO_ALT;
// THERM_VOLT_GPU
GPCRI5 = GPIO_ALT;
// THERM_VOLT_HEATSINK
GPCRI6 = GPIO_ALT;
// MODEL_ID
GPCRI7 = GPIO_IN;
// LED_BAT_FULL
GPCRJ0 = GPIO_OUT | GPIO_UP;
// KBC_MUTE# / USB charger detection
GPCRJ1 = GPIO_IN;
// PCH_FAN
GPCRJ2 = GPIO_ALT;
// HEATSINK_FANSEN_R
GPCRJ3 = GPIO_IN;
// VA_EC_EN
GPCRJ4 = GPIO_OUT;
// VBATT_BOOST#
GPCRJ5 = GPIO_IN;
// EC_GPIO
GPCRJ6 = GPIO_IN;
// PLVDD_RST_EC
GPCRJ7 = GPIO_OUT;
// ESPI_IO0_EC
GPCRM0 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_IO1_EC
GPCRM1 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_IO2_EC
GPCRM2 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_IO3_EC
GPCRM3 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_CLK_EC
GPCRM4 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_CS_EC#
GPCRM5 = GPIO_ALT;
// ESPI_ALRT0#
GPCRM6 = GPIO_IN | GPIO_UP | GPIO_DOWN;
}

View File

@@ -0,0 +1,43 @@
// SPDX-License-Identifier: GPL-3.0-only
#ifndef _BOARD_GPIO_H
#define _BOARD_GPIO_H
#include <ec/gpio.h>
void gpio_init(void);
extern struct Gpio __code ACIN_N;
extern struct Gpio __code AC_PRESENT;
extern struct Gpio __code ALL_SYS_PWRGD;
extern struct Gpio __code BKL_EN;
#define HAVE_BT_EN 0
extern struct Gpio __code BUF_PLT_RST_N;
extern struct Gpio __code CCD_EN;
extern struct Gpio __code DD_ON;
extern struct Gpio __code DGPU_PWR_EN;
extern struct Gpio __code EC_EN;
extern struct Gpio __code EC_RSMRST_N;
extern struct Gpio __code GC6_FB_EN;
extern struct Gpio __code LAN_WAKEUP_N;
extern struct Gpio __code LED_ACIN;
#define HAVE_LED_AIRPLANE_N 0
extern struct Gpio __code LED_BAT_CHG;
extern struct Gpio __code LED_BAT_FULL;
extern struct Gpio __code LED_PWR;
extern struct Gpio __code LID_SW_N;
extern struct Gpio __code ME_WE;
extern struct Gpio __code PCH_DPWROK_EC;
#define HAVE_PCH_PWROK_EC 0
extern struct Gpio __code PM_PWROK;
extern struct Gpio __code PWR_BTN_N;
extern struct Gpio __code PWR_SW_N;
extern struct Gpio __code RGBKB_DET_N;
extern struct Gpio __code SLP_SUS_N;
#define HAVE_SUS_PWR_ACK 0
extern struct Gpio __code VA_EC_EN;
#define HAVE_WLAN_EN 0
extern struct Gpio __code WLAN_PWR_EN;
extern struct Gpio __code XLP_OUT;
#endif // _BOARD_GPIO_H

View File

@@ -3,7 +3,6 @@
#include <board/board.h>
#include <board/gctrl.h>
#include <board/gpio.h>
#include <board/power.h>
#include <common/debug.h>
#include <ec/ec.h>
@@ -14,10 +13,6 @@ void board_init(void) {
gpio_set(&BKL_EN, true);
// Enable camera
gpio_set(&CCD_EN, true);
// Enable wireless
gpio_set(&BT_EN, true);
gpio_set(&WLAN_EN, true);
gpio_set(&WLAN_PWR_EN, true);
// Enable USB port power?
gpio_set(&USB_PWR_EN_N, false);
// Assert SMI#, SCI#, and SWI#
@@ -27,7 +22,5 @@ void board_init(void) {
}
void board_event(void) {
power_set_limit();
ec_read_post_codes();
}

View File

@@ -1,16 +1,22 @@
# SPDX-License-Identifier: GPL-3.0-only
EC=it5570e
board-y += board.c
board-y += gpio.c
EC=ite
CONFIG_EC_ITE_IT5570E=y
CONFIG_EC_FLASH_SIZE_128K = y
# Intel-based host
CONFIG_PLATFORM_INTEL = y
# Include keyboard
KEYBOARD=15in_102_nkey
# Set keyboard LED mechanism
CONFIG_HAVE_KBLED = y
KBLED=bonw14
# Set discrete GPU I2C bus
CFLAGS+=-DI2C_DGPU=I2C_1
# Set battery I2C bus
CFLAGS+=-DI2C_SMBUS=I2C_4
@@ -19,32 +25,38 @@ CFLAGS+=-DPS2_TOUCHPAD=PS2_3
# Set smart charger parameters
CFLAGS+=\
-DCHARGER_CHARGE_CURRENT=1536 \
-DCHARGER_ADAPTER_RSENSE=5 \
-DCHARGER_BATTERY_RSENSE=10 \
-DCHARGER_CHARGE_CURRENT=3072 \
-DCHARGER_CHARGE_VOLTAGE=16800 \
-DCHARGER_INPUT_CURRENT=14000
# Set CPU power limits in watts
CFLAGS+=\
-DPOWER_LIMIT_AC=180 \
-DPOWER_LIMIT_DC=28
-DPOWER_LIMIT_DC=45
# Custom fan curve
CFLAGS+=-DBOARD_FAN_POINTS="\
# Enable dGPU support
CONFIG_HAVE_DGPU = y
CFLAGS += -DI2C_DGPU=I2C_1
# Fan configs
CFLAGS += -DFAN1_PWM=DCR2
CFLAGS += -DBOARD_FAN1_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100) \
FAN_POINT(80, 100), \
"
# Enable DGPU support
CFLAGS+=-DHAVE_DGPU=1
CFLAGS+=-DBOARD_DGPU_FAN_POINTS="\
CFLAGS += -DFAN2_PWM=DCR4
CFLAGS += -DBOARD_FAN2_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100) \
FAN_POINT(80, 100), \
"
# Add system76 common code

View File

@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/gpio.h>
#include <common/debug.h>
#include <common/macro.h>
// clang-format off
// uncrustify:off
struct Gpio __code ACIN_N = GPIO(B, 0);
struct Gpio __code AC_PRESENT = GPIO(E, 1);
struct Gpio __code AC_V1_EC = GPIO(J, 7);
@@ -39,9 +39,14 @@ struct Gpio __code VA_EC_EN = GPIO(J, 4); // renamed to SLP_SUS#
struct Gpio __code WLAN_EN = GPIO(G, 1);
struct Gpio __code WLAN_PWR_EN = GPIO(A, 3);
struct Gpio __code XLP_OUT = GPIO(B, 4); // renamed to EN_3V
// clang-format on
// uncrustify:on
void gpio_init(void) {
// PWRSW WDT 2 Enable 2
GCR9 = BIT(5);
// PWRSW WDT 2 Enable 1
GCR8 = BIT(4);
void gpio_init() {
// Enable LPC reset on GPD2
GCR = 0x04;
// Enable SMBus channel 4
@@ -92,8 +97,6 @@ void gpio_init() {
GPCRB5 = GPIO_OUT | GPIO_UP;
// EC_EN
GPCRB6 = GPIO_OUT | GPIO_UP;
// NO PIN
GPCRB7 = GPIO_IN;
// ALL_SYS_PWRGD
GPCRC0 = GPIO_IN;
// KBC_SMBus_CLK1
@@ -101,11 +104,11 @@ void gpio_init() {
// KBC_SMBus_DAT1
GPCRC2 = GPIO_ALT;
// KB-SO16
GPCRC3 = GPIO_IN;
GPCRC3 = GPIO_ALT | GPIO_UP;
// CNVI_DET#
GPCRC4 = GPIO_IN | GPIO_UP;
// KB-SO17
GPCRC5 = GPIO_IN;
GPCRC5 = GPIO_ALT | GPIO_UP;
// PM_PWROK
GPCRC6 = GPIO_OUT;
// LED_ACIN
@@ -237,40 +240,3 @@ void gpio_init() {
// SERIRQ
GPCRM6 = GPIO_ALT;
}
#if GPIO_DEBUG
void gpio_debug_bank(
char * bank,
uint8_t data,
uint8_t mirror,
uint8_t pot,
volatile uint8_t * control
) {
for(char i = 0; i < 8; i++) {
DEBUG(
"%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n",
bank,
i,
(data >> i) & 1,
(mirror >> i) & 1,
(pot >> i) & 1,
*(control + i)
);
}
}
void gpio_debug(void) {
#define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0)
bank(A);
bank(B);
bank(C);
bank(D);
bank(E);
bank(F);
bank(G);
bank(H);
bank(I);
bank(J);
#undef bank
}
#endif

View File

@@ -6,9 +6,7 @@
#include <ec/gpio.h>
void gpio_init(void);
void gpio_debug(void);
// clang-format off
extern struct Gpio __code ACIN_N;
extern struct Gpio __code AC_PRESENT;
extern struct Gpio __code AC_V1_EC;
@@ -49,6 +47,5 @@ extern struct Gpio __code VA_EC_EN;
extern struct Gpio __code WLAN_EN;
extern struct Gpio __code WLAN_PWR_EN;
extern struct Gpio __code XLP_OUT;
// clang-format on
#endif // _BOARD_GPIO_H

View File

@@ -0,0 +1,81 @@
# SPDX-License-Identifier: GPL-3.0-only
board-y += ../bonw15/board.c
board-y += ../bonw15/gpio.c
# FIXME: Handle this better
CFLAGS += -I$(BOARD_DIR)/../bonw15/include
EC = ite
CONFIG_EC_ITE_IT5570E = y
CONFIG_EC_FLASH_SIZE_256K = y
# Intel-based host
CONFIG_PLATFORM_INTEL = y
CONFIG_BUS_ESPI = y
# Enable firmware security
CONFIG_SECURITY = y
# Include keyboard
KEYBOARD = 15in_102
# Set keyboard LED mechanism
CONFIG_HAVE_KBLED = y
KBLED = bonw14
# Set battery I2C bus
CFLAGS += -DI2C_SMBUS=I2C_4
# Set touchpad PS2 bus
CFLAGS += -DPS2_TOUCHPAD=PS2_3
# Set smart charger parameters
# XXX: PRS1 and PRS2 are in parallel for adapter Rsense?
CHARGER = oz26786
CFLAGS += \
-DCHARGER_ADAPTER_RSENSE=5 \
-DCHARGER_BATTERY_RSENSE=5 \
-DCHARGER_CHARGE_CURRENT=3072 \
-DCHARGER_CHARGE_VOLTAGE=17400 \
-DCHARGER_INPUT_CURRENT=16920
# Set USB-PD parameters
CONFIG_HAVE_USBPD = y
CONFIG_USBPD_TPS65987 = y
CFLAGS += -DI2C_USBPD=I2C_1
# Set CPU power limits in watts
CFLAGS += \
-DPOWER_LIMIT_AC=330 \
-DPOWER_LIMIT_DC=55
# Enable dGPU support
CONFIG_HAVE_DGPU = y
CFLAGS += -DI2C_DGPU=I2C_1
# Fan configs
CFLAGS += -DFAN1_PWM=DCR2
CFLAGS += -DBOARD_FAN1_HEATUP=5
CFLAGS += -DBOARD_FAN1_COOLDOWN=20
CFLAGS += -DBOARD_FAN1_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100), \
"
CFLAGS += -DFAN2_PWM=DCR4
CFLAGS += -DBOARD_FAN2_HEATUP=5
CFLAGS += -DBOARD_FAN2_COOLDOWN=20
CFLAGS += -DBOARD_FAN2_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100), \
"
# Add system76 common code
include src/board/system76/common/common.mk

View File

@@ -0,0 +1,25 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/battery.h>
#include <board/board.h>
#include <board/espi.h>
#include <board/gpio.h>
#include <ec/ec.h>
void board_init(void) {
espi_init();
// Make sure charger is in off state, also enables PSYS
battery_charger_disable();
// Allow backlight to be turned on
gpio_set(&BKL_EN, true);
// Enable camera
gpio_set(&CCD_EN, true);
}
void board_event(void) {
espi_event();
ec_read_post_codes();
}

View File

@@ -0,0 +1,79 @@
# SPDX-License-Identifier: GPL-3.0-only
board-y += board.c
board-y += gpio.c
EC=ite
CONFIG_EC_ITE_IT5570E=y
CONFIG_EC_FLASH_SIZE_128K = y
# Intel-based host
CONFIG_PLATFORM_INTEL = y
CONFIG_BUS_ESPI = y
# Enable firmware security
CONFIG_SECURITY=y
# Include keyboard
KEYBOARD=15in_102
# Set keyboard LED mechanism
CONFIG_HAVE_KBLED = y
KBLED=bonw14
# Set battery I2C bus
CFLAGS+=-DI2C_SMBUS=I2C_4
# Set touchpad PS2 bus
CFLAGS+=-DPS2_TOUCHPAD=PS2_3
# Set smart charger parameters
# XXX: PRS1 and PRS2 are in parallel for adapter Rsense?
CHARGER=oz26786
CFLAGS+=\
-DCHARGER_ADAPTER_RSENSE=5 \
-DCHARGER_BATTERY_RSENSE=5 \
-DCHARGER_CHARGE_CURRENT=3072 \
-DCHARGER_CHARGE_VOLTAGE=17400 \
-DCHARGER_INPUT_CURRENT=16920
# Set USB-PD parameters
CONFIG_HAVE_USBPD = y
CONFIG_USBPD_TPS65987 = y
CFLAGS += -DI2C_USBPD=I2C_1
# Set CPU power limits in watts
CFLAGS+=\
-DPOWER_LIMIT_AC=330 \
-DPOWER_LIMIT_DC=55
# Enable dGPU support
CONFIG_HAVE_DGPU = y
CFLAGS += -DI2C_DGPU=I2C_1
# Fan configs
CFLAGS += -DFAN1_PWM=DCR2
CFLAGS += -DBOARD_FAN1_HEATUP=5
CFLAGS += -DBOARD_FAN1_COOLDOWN=20
CFLAGS += -DBOARD_FAN1_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100), \
"
CFLAGS += -DFAN2_PWM=DCR4
CFLAGS += -DBOARD_FAN2_HEATUP=5
CFLAGS += -DBOARD_FAN2_COOLDOWN=20
CFLAGS += -DBOARD_FAN2_POINTS="\
FAN_POINT(60, 40), \
FAN_POINT(65, 60), \
FAN_POINT(70, 75), \
FAN_POINT(75, 90), \
FAN_POINT(80, 100), \
"
# Add system76 common code
include src/board/system76/common/common.mk

View File

@@ -0,0 +1,275 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/gpio.h>
#include <common/macro.h>
// uncrustify:off
struct Gpio __code ACIN_N = GPIO(B, 0);
struct Gpio __code AC_PRESENT = GPIO(E, 1);
struct Gpio __code ALL_SYS_PWRGD = GPIO(C, 0);
struct Gpio __code BKL_EN = GPIO(C, 7);
struct Gpio __code BUF_PLT_RST_N = GPIO(D, 2); // renamed to ESPI_RESET_N
struct Gpio __code CCD_EN = GPIO(D, 1);
struct Gpio __code DD_ON = GPIO(E, 4);
struct Gpio __code DGPU_PWR_EN = GPIO(J, 2);
struct Gpio __code EC_EN = GPIO(B, 6); // renamed to SUSBC_EC#
struct Gpio __code EC_RSMRST_N = GPIO(E, 5);
struct Gpio __code GC6_FB_EN = GPIO(J, 3);
struct Gpio __code JACK_IN_N = GPIO(E, 6);
struct Gpio __code LAN_WAKEUP_N = GPIO(B, 2);
struct Gpio __code LED_ACIN = GPIO(H, 2);
struct Gpio __code LED_BAT_CHG = GPIO(H, 5);
struct Gpio __code LED_BAT_FULL = GPIO(J, 0);
struct Gpio __code LED_PWR = GPIO(D, 0);
struct Gpio __code LID_SW_N = GPIO(B, 1);
struct Gpio __code ME_WE = GPIO(I, 2);
struct Gpio __code PCH_DPWROK_EC = GPIO(F, 3);
struct Gpio __code PCH_PWROK_EC = GPIO(I, 5); // renamed to SYS_PWROK_EC
struct Gpio __code PWR_BTN_N = GPIO(D, 5);
struct Gpio __code PWR_SW_N = GPIO(B, 3);
struct Gpio __code RGBKB_DET_N = GPIO(E, 2);
struct Gpio __code SINK_CTRL = GPIO(H, 0);
struct Gpio __code SLP_SUS_N = GPIO(H, 7);
struct Gpio __code VA_EC_EN = GPIO(J, 4);
struct Gpio __code WLAN_EN = GPIO(G, 1);
struct Gpio __code WLAN_PWR_EN = GPIO(B, 5);
struct Gpio __code XLP_OUT = GPIO(B, 4);
// uncrustify:on
void gpio_init(void) {
// PWRSW WDT 2 Enable 2
GCR9 = BIT(5);
// PWRSW WDT 2 Enable 1
GCR8 = BIT(4);
// Enable LPC reset on GPD2
GCR = 0x04;
// Disable UARTs
GCR6 = 0;
// Enable SMBus channel 4
GCR15 = BIT(4);
// Set GPD2 to 1.8V
GCR19 = BIT(0);
// Set GPF2 and GPF3 to 3.3V
GCR20 = 0;
//TODO: what do these do?
GCR1 = 0;
GCR2 = 0;
GCR10 = 0x02;
GCR21 = 0;
GCR22 = 0x80;
GCR23 = 0x01;
// Set GPIO data
GPDRA = 0;
// XLP_OUT, PWR_SW#
GPDRB = BIT(4) | BIT(3);
// PLVDD_RST_EC
GPDRC = BIT(6);
// BL_PWM_EN_EC
GPDRD = BIT(3);
// USB_PWR_EN# (inverted)
GPDRE = BIT(3);
// PCH_DPWROK_EC
GPDRF = BIT(3);
// H_PROCHOT#_EC
GPDRG = BIT(6);
// EC_AMP_EN
GPDRH = BIT(6);
GPDRI = 0;
GPDRJ = 0;
GPOTA = 0;
GPOTB = 0;
GPOTD = 0;
GPOTE = 0;
GPOTF = 0;
GPOTH = 0;
GPOTJ = 0;
// Set GPIO control
// EC_PWM_LEDKB_P
GPCRA0 = GPIO_ALT;
// KBC_BEEP
GPCRA1 = GPIO_ALT;
// CPU_FAN
GPCRA2 = GPIO_ALT;
// DDS_EC_PWM
GPCRA3 = GPIO_IN;
// VGA_FAN
GPCRA4 = GPIO_ALT;
// EC_PWM_LEDKB_R
GPCRA5 = GPIO_ALT;
// EC_PWM_LEDKB_G
GPCRA6 = GPIO_ALT;
// EC_PWM_LEDKB_B
GPCRA7 = GPIO_ALT;
// AC_IN#
GPCRB0 = GPIO_IN | GPIO_UP;
// LID_SW#
GPCRB1 = GPIO_IN | GPIO_UP;
// EC_LAN_WAKEUP#
GPCRB2 = GPIO_IN | GPIO_UP;
// PWR_SW#
GPCRB3 = GPIO_IN;
// XLP_OUT
GPCRB4 = GPIO_OUT;
// WLAN_PWR_EN
GPCRB5 = GPIO_OUT;
// SUSBC_EC#
GPCRB6 = GPIO_OUT | GPIO_UP;
// ALL_SYS_PWRGD
GPCRC0 = GPIO_IN;
// SMC_VGA_THERM
GPCRC1 = GPIO_ALT | GPIO_UP;
// SMD_VGA_THERM
GPCRC2 = GPIO_ALT | GPIO_UP;
// KB-SO16
GPCRC3 = GPIO_ALT | GPIO_UP;
// CNVI_DET#
GPCRC4 = GPIO_IN | GPIO_UP;
// KB-SO17
GPCRC5 = GPIO_ALT | GPIO_UP;
// PLVDD_RST_EC
GPCRC6 = GPIO_OUT;
// BKL_EN
GPCRC7 = GPIO_OUT | GPIO_UP;
// LED_PWR
GPCRD0 = GPIO_OUT;
// CCD_EN
GPCRD1 = GPIO_OUT;
// ESPI_RESET_N
GPCRD2 = GPIO_ALT;
// BL_PWM_EN_EC
GPCRD3 = GPIO_OUT;
// MUX_CTRL_BIOS
GPCRD4 = GPIO_OUT;
// PWR_BTN#
GPCRD5 = GPIO_OUT | GPIO_UP;
// CPU_FANSEN
GPCRD6 = GPIO_ALT;
// VGA_FANSEN
GPCRD7 = GPIO_ALT;
// SMC_BAT
GPCRE0 = GPIO_ALT | GPIO_UP;
// AC_PRESENT
GPCRE1 = GPIO_OUT | GPIO_UP;
// RGBKB_DET#
GPCRE2 = GPIO_IN | GPIO_UP;
// USB_PWR_EN#
GPCRE3 = GPIO_OUT;
// DD_ON
GPCRE4 = GPIO_OUT | GPIO_DOWN;
// EC_RSMRST#
GPCRE5 = GPIO_OUT;
// JACK_IN#_EC
GPCRE6 = GPIO_IN;
// SMD_BAT
GPCRE7 = GPIO_ALT | GPIO_UP;
// 80CLK
GPCRF0 = GPIO_IN;
// USB_CHARGE_EN
GPCRF1 = GPIO_OUT | GPIO_UP;
// 3IN1
GPCRF2 = GPIO_IN | GPIO_UP;
// PCH_DPWROK_EC
GPCRF3 = GPIO_OUT;
// TP_CLK
GPCRF4 = GPIO_ALT | GPIO_UP;
// TP_DATA
GPCRF5 = GPIO_ALT | GPIO_UP;
// H_PECI
GPCRF6 = GPIO_ALT;
// CPU_C10_GATE#
GPCRF7 = GPIO_IN;
// dGPU_OVERT_EC
GPCRG0 = GPIO_IN;
// WLAN_EN
GPCRG1 = GPIO_OUT;
// 100k pull up to VDD3
GPCRG2 = GPIO_IN;
// ALSPI_CE#
GPCRG3 = GPIO_ALT;
// ALSPI_MSI
GPCRG4 = GPIO_ALT;
// ALSPI_MSO
GPCRG5 = GPIO_ALT;
// H_PROCHOT#_EC
GPCRG6 = GPIO_OUT | GPIO_UP;
// ALSPI_SCLK
GPCRG7 = GPIO_ALT;
// SINK_CTRL
GPCRH0 = GPIO_IN;
// SUSC#_PCH
GPCRH1 = GPIO_IN;
// LED_ACIN
GPCRH2 = GPIO_OUT | GPIO_UP;
// TBT_I2C_IRQ2Z
GPCRH3 = GPIO_IN;
// BOARD_ID0
GPCRH4 = GPIO_IN;
// LED_BAT_CHG
GPCRH5 = GPIO_OUT | GPIO_UP;
// EC_AMP_EN
GPCRH6 = GPIO_OUT;
// SLP_SUS#
GPCRH7 = GPIO_IN;
// BAT_DET
GPCRI0 = GPIO_ALT;
// BAT_VOLT
GPCRI1 = GPIO_ALT;
// ME_WE
GPCRI2 = GPIO_OUT;
// THERM_VOLT_CPU
GPCRI3 = GPIO_ALT;
// TOTAL_CUR
GPCRI4 = GPIO_ALT;
// SYS_PWROK_EC
GPCRI5 = GPIO_OUT;
// THERM_VOLT_CPU
GPCRI6 = GPIO_ALT;
// BOARD_ID1
GPCRI7 = GPIO_IN;
// LED_BAT_FULL
GPCRJ0 = GPIO_OUT | GPIO_UP;
// KBC_MUTE#
GPCRJ1 = GPIO_IN;
// DGPU_PWR_EN
GPCRJ2 = GPIO_IN;
// GC6_FB_EN_PCH
GPCRJ3 = GPIO_IN;
// VA_EC_EN
GPCRJ4 = GPIO_OUT;
// VBATT_BOOST#
GPCRJ5 = GPIO_IN;
// EC_GPIO
GPCRJ6 = GPIO_IN | GPIO_DOWN;
// PERKB_DET#
GPCRJ7 = GPIO_IN | GPIO_UP;
// ESPI_IO0_EC
GPCRM0 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_IO1_EC
GPCRM1 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_IO2_EC
GPCRM2 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_IO3_EC
GPCRM3 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_CLK_EC
GPCRM4 = GPIO_ALT | GPIO_UP | GPIO_DOWN;
// ESPI_CS_EC#
GPCRM5 = GPIO_ALT;
// ESPI_ALERT0#
GPCRM6 = GPIO_IN | GPIO_UP | GPIO_DOWN;
}

View File

@@ -0,0 +1,46 @@
// SPDX-License-Identifier: GPL-3.0-only
#ifndef _BOARD_GPIO_H
#define _BOARD_GPIO_H
#include <ec/gpio.h>
void gpio_init(void);
extern struct Gpio __code ACIN_N;
extern struct Gpio __code AC_PRESENT;
extern struct Gpio __code ALL_SYS_PWRGD;
extern struct Gpio __code BKL_EN;
#define HAVE_BT_EN 0
extern struct Gpio __code BUF_PLT_RST_N;
extern struct Gpio __code CCD_EN;
extern struct Gpio __code CPU_C10_GATE_N;
extern struct Gpio __code DD_ON;
extern struct Gpio __code DGPU_PWR_EN;
extern struct Gpio __code EC_EN;
extern struct Gpio __code EC_RSMRST_N;
extern struct Gpio __code GC6_FB_EN;
extern struct Gpio __code JACK_IN_N;
extern struct Gpio __code LAN_WAKEUP_N;
extern struct Gpio __code LED_ACIN;
#define HAVE_LED_AIRPLANE_N 0
extern struct Gpio __code LED_BAT_CHG;
extern struct Gpio __code LED_BAT_FULL;
extern struct Gpio __code LED_PWR;
extern struct Gpio __code LID_SW_N;
extern struct Gpio __code ME_WE;
extern struct Gpio __code PCH_DPWROK_EC;
extern struct Gpio __code PCH_PWROK_EC;
#define HAVE_PM_PWROK 0
extern struct Gpio __code PWR_BTN_N;
extern struct Gpio __code PWR_SW_N;
extern struct Gpio __code RGBKB_DET_N;
extern struct Gpio __code SINK_CTRL;
extern struct Gpio __code SLP_SUS_N;
#define HAVE_SUS_PWR_ACK 0
extern struct Gpio __code VA_EC_EN;
extern struct Gpio __code WLAN_EN;
extern struct Gpio __code WLAN_PWR_EN;
extern struct Gpio __code XLP_OUT;
#endif // _BOARD_GPIO_H

View File

@@ -3,13 +3,17 @@
#include <board/acpi.h>
#include <board/battery.h>
#include <board/dgpu.h>
#include <board/fan.h>
#include <board/gpio.h>
#include <board/kbled.h>
#include <board/lid.h>
#include <board/peci.h>
#include <common/macro.h>
#include <board/pwm.h>
#include <common/debug.h>
#include <ec/pwm.h>
#include <common/macro.h>
#if CONFIG_PLATFORM_INTEL
#include <board/peci.h>
#endif
#ifndef HAVE_LED_AIRPLANE_N
#define HAVE_LED_AIRPLANE_N 1
@@ -25,31 +29,48 @@ static uint8_t fbuf[4] = { 0, 0, 0, 0 };
void fcommand(void) {
switch (fcmd) {
// Keyboard backlight
case 0xCA:
switch (fdat) {
// Set white LED brightness
case 0x00:
kbled_set(fbuf[0]);
break;
// Get white LED brightness
case 0x01:
fbuf[0] = kbled_get();
break;
// Set LED color
case 0x03:
kbled_set_color(
((uint32_t)fbuf[0]) |
((uint32_t)fbuf[1] << 16) |
((uint32_t)fbuf[2] << 8)
);
break;
// Set LED brightness
case 0x06:
kbled_set(fbuf[0]);
break;
}
#if CONFIG_HAVE_KBLED
// Keyboard backlight
case 0xCA:
switch (fdat) {
// Set brightness
case 0:
kbled_set(fbuf[0]);
break;
// Get brightness
case 1:
fbuf[0] = kbled_get();
break;
// Get type
case 2:
fbuf[0] = kbled_kind;
break;
// Set color
case 3:
kbled_set_color(
((uint32_t)fbuf[0]) |
((uint32_t)fbuf[1] << 16) |
((uint32_t)fbuf[2] << 8)
);
break;
// Get color
case 4:
// uncrustify:off
{
uint32_t color = kbled_get_color();
fbuf[0] = color & 0xFF;
fbuf[1] = (color >> 16) & 0xFF;
fbuf[2] = (color >> 8) & 0xFF;
}
// uncrustify:on
break;
// DUPLICATE: Set brightness
case 6:
kbled_set(fbuf[0]);
break;
}
break;
#endif // CONFIG_HAVE_KBLED
}
}
@@ -66,7 +87,7 @@ void acpi_reset(void) {
#endif
}
// clang-format off
// uncrustify:off
uint8_t acpi_read(uint8_t addr) {
uint8_t data = 0;
@@ -95,7 +116,9 @@ uint8_t acpi_read(uint8_t addr) {
}
break;
#if CONFIG_PLATFORM_INTEL
ACPI_8(0x07, peci_temp);
#endif
// Handle AC adapter and battery present
case 0x10:
@@ -130,7 +153,9 @@ uint8_t acpi_read(uint8_t addr) {
ACPI_16(0x42, battery_info.cycle_count);
ACPI_8(0x68, acpi_ecos);
case 0x68:
data = acpi_ecos;
break;
case 0xBC:
data = battery_get_start_threshold();
@@ -142,15 +167,15 @@ uint8_t acpi_read(uint8_t addr) {
ACPI_8(0xCC, sci_extra);
ACPI_8(0xCE, DCR2);
ACPI_8(0xD0, F1TLRR);
ACPI_8(0xD1, F1TMRR);
#if HAVE_DGPU
ACPI_8(0xCE, fan1_pwm_actual);
ACPI_16(0xD0, fan1_rpm);
#if CONFIG_HAVE_DGPU
ACPI_8(0xCD, dgpu_temp);
ACPI_8(0xCF, DCR4);
ACPI_8(0xD2, F2TLRR);
ACPI_8(0xD3, F2TMRR);
#endif // HAVE_DGPU
#endif // CONFIG_HAVE_DGPU
#ifdef FAN2_PWM
ACPI_8(0xCF, fan2_pwm_actual);
ACPI_16(0xD2, fan2_rpm);
#endif // FAN2_PWM
#if HAVE_LED_AIRPLANE_N
// Airplane mode LED
@@ -162,67 +187,67 @@ uint8_t acpi_read(uint8_t addr) {
#endif // HAVE_LED_AIRPLANE_N
// Set size of flash (from old firmware)
ACPI_8 (0xE5, 0x80);
ACPI_8(0xE5, 0x80);
ACPI_8 (0xF8, fcmd);
ACPI_8 (0xF9, fdat);
ACPI_8 (0xFA, fbuf[0]);
ACPI_8 (0xFB, fbuf[1]);
ACPI_8 (0xFC, fbuf[2]);
ACPI_8 (0xFD, fbuf[3]);
ACPI_8(0xF8, fcmd);
ACPI_8(0xF9, fdat);
ACPI_8(0xFA, fbuf[0]);
ACPI_8(0xFB, fbuf[1]);
ACPI_8(0xFC, fbuf[2]);
ACPI_8(0xFD, fbuf[3]);
}
TRACE("acpi_read %02X = %02X\n", addr, data);
return data;
}
// clang-format on
// uncrustify:on
void acpi_write(uint8_t addr, uint8_t data) {
TRACE("acpi_write %02X = %02X\n", addr, data);
switch (addr) {
// Lid state and other flags
case 0x03:
lid_wake = (bool)(data & BIT(2));
break;
// Lid state and other flags
case 0x03:
lid_wake = (bool)(data & BIT(2));
break;
case 0x68:
acpi_ecos = (enum EcOs)data;
break;
case 0x68:
acpi_ecos = (enum EcOs)data;
break;
case 0xBC:
battery_set_start_threshold(data);
break;
case 0xBC:
battery_set_start_threshold(data);
break;
case 0xBD:
battery_set_end_threshold(data);
break;
case 0xBD:
battery_set_end_threshold(data);
break;
#if HAVE_LED_AIRPLANE_N
// Airplane mode LED
case 0xD9:
gpio_set(&LED_AIRPLANE_N, !(bool)(data & BIT(6)));
break;
// Airplane mode LED
case 0xD9:
gpio_set(&LED_AIRPLANE_N, !(bool)(data & BIT(6)));
break;
#endif
case 0xF8:
fcmd = data;
fcommand();
break;
case 0xF9:
fdat = data;
break;
case 0xFA:
fbuf[0] = data;
break;
case 0xFB:
fbuf[1] = data;
break;
case 0xFC:
fbuf[2] = data;
break;
case 0xFD:
fbuf[3] = data;
break;
case 0xF8:
fcmd = data;
fcommand();
break;
case 0xF9:
fdat = data;
break;
case 0xFA:
fbuf[0] = data;
break;
case 0xFB:
fbuf[1] = data;
break;
case 0xFC:
fbuf[2] = data;
break;
case 0xFD:
fbuf[3] = data;
break;
}
}

View File

@@ -1,14 +1,17 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/battery.h>
#include <board/gpio.h>
#include <board/smbus.h>
#include <common/debug.h>
struct battery_info battery_info = { 0 };
uint16_t battery_charger_input_current = CHARGER_INPUT_CURRENT;
// Default values to disable battery charging thresholds
#define BATTERY_START_DEFAULT 0
#define BATTERY_END_DEFAULT 100
#define BATTERY_START_DEFAULT 0
#define BATTERY_END_DEFAULT 100
// Represents a battery percentage level, below which charging will begin.
// Valid values are [0, 100]
@@ -53,20 +56,20 @@ bool battery_set_end_threshold(uint8_t value) {
*/
int16_t battery_charger_configure(void) {
static bool should_charge = true;
bool ac_present = !gpio_get(&ACIN_N);
if (battery_get_end_threshold() == BATTERY_END_DEFAULT) {
// Stop threshold not configured: Always charge on AC.
should_charge = true;
}
else if (battery_info.charge >= battery_get_end_threshold()) {
if (!ac_present || (battery_info.status & BATTERY_FULLY_CHARGED)) {
// Always disable charger if:
// - AC is not plugged in, or
// - Battery is fully charged
should_charge = false;
} else if (battery_info.charge > battery_get_end_threshold()) {
// Stop threshold configured: Stop charging at threshold.
should_charge = false;
}
else if (battery_get_start_threshold() == BATTERY_START_DEFAULT) {
} else if (battery_get_start_threshold() == BATTERY_START_DEFAULT) {
// Start threshold not configured: Always charge up to stop threshold.
should_charge = true;
}
else if (battery_info.charge <= battery_get_start_threshold()) {
} else if (battery_info.charge < battery_get_start_threshold()) {
// Start threshold configured: Start charging at threshold.
should_charge = true;
}
@@ -79,7 +82,8 @@ int16_t battery_charger_configure(void) {
void battery_event(void) {
int16_t res = 0;
#define command(N, V) { \
#define command(N, V) \
{ \
res = smbus_read(BATTERY_ADDRESS, V, &N); \
if (res < 0) { \
N = 0; \
@@ -97,7 +101,7 @@ void battery_event(void) {
command(battery_info.design_capacity, 0x18);
command(battery_info.design_voltage, 0x19);
#undef command
#undef command
TRACE("BAT %d mV %d mA\n", battery_info.voltage, battery_info.current);

View File

@@ -8,6 +8,18 @@
#include <common/macro.h>
#include <common/debug.h>
// uncrustify:off
// Registers
#define REG_CHARGE_CURRENT 0x14
#define REG_CHARGE_VOLTAGE 0x15
#define REG_DISCHARGE_CURRENT 0x39
#define REG_INPUT_CURRENT 0x3F
#define REG_CHARGE_OPTION_0 0x12
#define REG_CHARGE_OPTION_1 0x3B
#define REG_CHARGE_OPTION_2 0x38
#define REG_CHARGE_OPTION_3 0x37
// ChargeOption0 flags
// Low Power Mode Enable
#define SBC_EN_LWPWR ((uint16_t)(BIT(15)))
@@ -18,35 +30,94 @@
// IDCHG Amplifier Gain
#define SBC_IDCHC_GAIN ((uint16_t)(BIT(3)))
// ChargeOption1 flags
// Independent Comparator Deglitch
#define SBC_CMP_DEG_1US (0b01 << 4)
// PMON Gain
#define SBC_PMON_RATIO BIT(9)
// Adapter:Battery RSENSE ratio
#define SBC_RSENSE_RATIO_1_1 (0b00 << 12)
#define SBC_RSENSE_RATIO_2_1 (0b01 << 12)
#define SBC_RSENSE_RATIO_1_2 (0b10 << 12)
// Battery depletion threshold
#define SBC_BAT_DEPL_VTH (0b11 << 14)
// Bits 0-5 are ignored. Bits 13-15 must be 0.
#define CHARGE_CURRENT_MASK 0x1FC0
#if CHARGER_BATTERY_RSENSE == 5
#define CHARGE_CURRENT (MIN((CHARGER_CHARGE_CURRENT >> 1), CHARGE_CURRENT_MASK) & CHARGE_CURRENT_MASK)
#elif CHARGER_BATTERY_RSENSE == 10
#define CHARGE_CURRENT (MIN(CHARGER_CHARGE_CURRENT, CHARGE_CURRENT_MASK) & CHARGE_CURRENT_MASK)
#elif CHARGER_BATTERY_RSENSE == 20
#define CHARGE_CURRENT (MIN((CHARGER_CHARGE_CURRENT << 1), CHARGE_CURRENT_MASK) & CHARGE_CURRENT_MASK)
#else
#error Invalid battery RSENSE value
#endif
// Bits 0-3, 15 are ignored.
#define CHARGE_VOLTAGE_MASK 0x7FF0
#define CHARGE_VOLTAGE (MIN(CHARGER_CHARGE_VOLTAGE, CHARGE_VOLTAGE_MASK) & CHARGE_VOLTAGE_MASK)
// Bits 0-6 are ignored. Bits 13-15 must be 0.
#define INPUT_CURRENT_MASK 0x1F80
#if CHARGER_ADAPTER_RSENSE == 5
#define INPUT_CURRENT(X) (MIN(((X) >> 1), INPUT_CURRENT_MASK) & INPUT_CURRENT_MASK)
#elif CHARGER_ADAPTER_RSENSE == 10
#define INPUT_CURRENT(X) (MIN((X), INPUT_CURRENT_MASK) & INPUT_CURRENT_MASK)
#elif CHARGER_ADAPTER_RSENSE == 20
#define INPUT_CURRENT(X) (MIN(((X) << 1), INPUT_CURRENT_MASK) & INPUT_CURRENT_MASK)
#else
#error Invalid adapter RSENSE value
#endif
#if (CHARGER_ADAPTER_RSENSE == 5 && CHARGER_BATTERY_RSENSE == 5) || \
(CHARGER_ADAPTER_RSENSE == 10 && CHARGER_BATTERY_RSENSE == 10) || \
(CHARGER_ADAPTER_RSENSE == 20 && CHARGER_BATTERY_RSENSE == 20)
#define RSENSE_RATIO SBC_RSENSE_RATIO_1_1
#elif (CHARGER_ADAPTER_RSENSE == 10 && CHARGER_BATTERY_RSENSE == 5) || \
(CHARGER_ADAPTER_RSENSE == 20 && CHARGER_BATTERY_RSENSE == 10)
#define RSENSE_RATIO SBC_RSENSE_RATIO_2_1
#elif (CHARGER_ADAPTER_RSENSE == 5 && CHARGER_BATTERY_RSENSE == 10) || \
(CHARGER_ADAPTER_RSENSE == 10 && CHARGER_BATTERY_RSENSE == 20)
#define RSENSE_RATIO SBC_RSENSE_RATIO_1_2
#else
#error Invalid adapter:battery RSENSE ratio
#endif
// uncrustify:on
// XXX: Assumption: ac_last is initialized high.
static bool charger_enabled = false;
int16_t battery_charger_disable(void) {
int16_t res = 0;
if (!charger_enabled) return 0;
if (!charger_enabled)
return 0;
// Set charge option 0 with 175s watchdog
res = smbus_write(
CHARGER_ADDRESS,
0x12,
SBC_EN_LWPWR |
SBC_WDTMR_ADJ_175S |
SBC_PWM_FREQ_800KHZ |
SBC_IDCHC_GAIN
REG_CHARGE_OPTION_0,
SBC_EN_LWPWR | SBC_WDTMR_ADJ_175S | SBC_PWM_FREQ_800KHZ | SBC_IDCHC_GAIN
);
// Disable charge current
res = smbus_write(CHARGER_ADDRESS, 0x14, 0);
if (res < 0) return res;
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_CURRENT, 0);
if (res < 0)
return res;
// Disable charge voltage
res = smbus_write(CHARGER_ADDRESS, 0x15, 0);
if (res < 0) return res;
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, 0);
if (res < 0)
return res;
// Disable input current
res = smbus_write(CHARGER_ADDRESS, 0x3F, 0);
if (res < 0) return res;
res = smbus_write(CHARGER_ADDRESS, REG_INPUT_CURRENT, 0);
if (res < 0)
return res;
DEBUG("Charger disabled\n");
charger_enabled = false;
@@ -56,30 +127,44 @@ int16_t battery_charger_disable(void) {
int16_t battery_charger_enable(void) {
int16_t res = 0;
if (charger_enabled) return 0;
if (charger_enabled)
return 0;
res = battery_charger_disable();
if (res < 0) return res;
if (res < 0)
return res;
// Set charge current in mA
res = smbus_write(CHARGER_ADDRESS, 0x14, CHARGER_CHARGE_CURRENT);
if (res < 0) return res;
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_CURRENT, CHARGE_CURRENT);
if (res < 0)
return res;
// Set charge voltage in mV
res = smbus_write(CHARGER_ADDRESS, 0x15, CHARGER_CHARGE_VOLTAGE);
if (res < 0) return res;
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, CHARGE_VOLTAGE);
if (res < 0)
return res;
// Set input current in mA
res = smbus_write(CHARGER_ADDRESS, 0x3F, CHARGER_INPUT_CURRENT);
if (res < 0) return res;
res = smbus_write(
CHARGER_ADDRESS,
REG_INPUT_CURRENT,
INPUT_CURRENT(battery_charger_input_current)
);
if (res < 0)
return res;
// Set charge option 0 with watchdog disabled
res = smbus_write(
CHARGER_ADDRESS,
0x12,
SBC_EN_LWPWR |
SBC_PWM_FREQ_800KHZ |
SBC_IDCHC_GAIN
REG_CHARGE_OPTION_0,
SBC_EN_LWPWR | SBC_PWM_FREQ_800KHZ | SBC_IDCHC_GAIN
);
// Set the RSENSE ratio
res = smbus_write(
CHARGER_ADDRESS,
REG_CHARGE_OPTION_1,
SBC_CMP_DEG_1US | SBC_PMON_RATIO | RSENSE_RATIO | SBC_BAT_DEPL_VTH
);
DEBUG("Charger enabled\n");
@@ -95,7 +180,8 @@ void battery_debug(void) {
uint16_t data = 0;
int16_t res = 0;
#define command(N, A, V) { \
#define command(N, A, V) \
{ \
DEBUG(" " #N ": "); \
res = smbus_read(A, V, &data); \
if (res < 0) { \
@@ -113,17 +199,17 @@ void battery_debug(void) {
command(Status, BATTERY_ADDRESS, 0x16);
DEBUG("Charger (bq24780s):\n");
command(ChargeOption0, CHARGER_ADDRESS, 0x12);
command(ChargeOption1, CHARGER_ADDRESS, 0x3B);
command(ChargeOption2, CHARGER_ADDRESS, 0x38);
command(ChargeOption3, CHARGER_ADDRESS, 0x37);
command(ChargeCurrent, CHARGER_ADDRESS, 0x14);
command(ChargeVoltage, CHARGER_ADDRESS, 0x15);
command(DishargeCurrent, CHARGER_ADDRESS, 0x39);
command(InputCurrent, CHARGER_ADDRESS, 0x3F);
command(ChargeOption0, CHARGER_ADDRESS, REG_CHARGE_OPTION_0);
command(ChargeOption1, CHARGER_ADDRESS, REG_CHARGE_OPTION_1);
command(ChargeOption2, CHARGER_ADDRESS, REG_CHARGE_OPTION_2);
command(ChargeOption3, CHARGER_ADDRESS, REG_CHARGE_OPTION_3);
command(ChargeCurrent, CHARGER_ADDRESS, REG_CHARGE_CURRENT);
command(ChargeVoltage, CHARGER_ADDRESS, REG_CHARGE_VOLTAGE);
command(DishargeCurrent, CHARGER_ADDRESS, REG_DISCHARGE_CURRENT);
command(InputCurrent, CHARGER_ADDRESS, REG_INPUT_CURRENT);
command(ProchotOption0, CHARGER_ADDRESS, 0x3C);
command(ProchotOption1, CHARGER_ADDRESS, 0x3D);
command(ProchotStatus, CHARGER_ADDRESS, 0x3A);
#undef command
#undef command
}

View File

@@ -8,6 +8,8 @@
#include <common/debug.h>
#include <common/macro.h>
// uncrustify:off
// Registers
#define REG_CHARGE_CURRENT 0x14
#define REG_CHARGE_VOLTAGE 0x15
@@ -17,44 +19,111 @@
#define CHARGE_OPTION_2_PSYS_EN BIT(11)
#define REG_ADAPTER_CURRENT 0x3F
// Bits 0-5, 13-15 are ignored.
#define CHARGE_CURRENT_MASK 0x1FC0
#if CHARGER_BATTERY_RSENSE == 5
#define CHARGE_CURRENT (MIN((CHARGER_CHARGE_CURRENT >> 1), CHARGE_CURRENT_MASK) & CHARGE_CURRENT_MASK)
// XXX: According to the datasheet, only 10 and 20 are valid.
#define BATTERY_RSENSE (RSENSE_10 << 8)
#elif CHARGER_BATTERY_RSENSE == 10
#define CHARGE_CURRENT (MIN(CHARGER_CHARGE_CURRENT, CHARGE_CURRENT_MASK) & CHARGE_CURRENT_MASK)
#define BATTERY_RSENSE (RSENSE_10 << 8)
#elif CHARGER_BATTERY_RSENSE == 20
#define CHARGE_CURRENT (MIN((CHARGER_CHARGE_CURRENT << 1), CHARGE_CURRENT_MASK) & CHARGE_CURRENT_MASK)
#define BATTERY_RSENSE (RSENSE_20 << 8)
#else
#error Invalid battery RSENSE value
#endif
// Bits 0-3, 15 are ignored.
#define CHARGE_VOLTAGE_MASK 0x7FF0
#define CHARGE_VOLTAGE (MIN(CHARGER_CHARGE_VOLTAGE, CHARGE_VOLTAGE_MASK) & CHARGE_VOLTAGE_MASK)
// Bits 0-6 are ignored. Bits 12-15 must be 0.
#define INPUT_CURRENT_MASK 0x0F80
#if CHARGER_ADAPTER_RSENSE == 5
#define INPUT_CURRENT(X) (MIN(((X) >> 2), INPUT_CURRENT_MASK) & INPUT_CURRENT_MASK)
#define ADAPTER_RSENSE RSENSE_5
#elif CHARGER_ADAPTER_RSENSE == 10
#define INPUT_CURRENT(X) (MIN(((X) >> 1), INPUT_CURRENT_MASK) & INPUT_CURRENT_MASK)
#define ADAPTER_RSENSE RSENSE_10
#elif CHARGER_ADAPTER_RSENSE == 20
#define INPUT_CURRENT(X) (MIN((X), INPUT_CURRENT_MASK) & INPUT_CURRENT_MASK)
#define ADAPTER_RSENSE RSENSE_20
#else
#error Invalid adapter RSENSE value
#endif
// PSYS gain in nA/W
#ifndef CHARGER_PSYS_GAIN
#define CHARGER_PSYS_GAIN 1000
#endif
#if CHARGER_PSYS_GAIN == 1000
#define CHARGE_OPTION_2_PSYS_GAIN (0 << 8)
#elif CHARGER_PSYS_GAIN == 500
#define CHARGE_OPTION_2_PSYS_GAIN (1 << 8)
#elif CHARGER_PSYS_GAIN == 250
#define CHARGE_OPTION_2_PSYS_GAIN (2 << 8)
#elif CHARGER_PSYS_GAIN == 2000
#define CHARGE_OPTION_2_PSYS_GAIN (3 << 8)
#else
#error Invalid CHARGER_PSYS_GAIN value
#endif
// uncrustify:on
// Sense resistor values in milliohms.
enum sense_resistor {
RSENSE_10 = 0,
RSENSE_20 = 1,
RSENSE_5 = 2,
};
// XXX: Assumption: ac_last is initialized high.
static bool charger_enabled = false;
int16_t battery_charger_disable(void) {
int16_t res = 0;
if (!charger_enabled) return 0;
if (!charger_enabled)
return 0;
// Set charge option 1 to converter frequency 600 KHz
//TODO: needed when charging disabled?
res = smbus_write(
CHARGER_ADDRESS,
REG_CHARGE_OPTION_1,
CHARGE_OPTION_1_600KHZ
CHARGE_OPTION_1_600KHZ | ADAPTER_RSENSE | BATTERY_RSENSE
);
if (res < 0) return res;
if (res < 0)
return res;
// Set charge option 2 to PSYS enable
//TODO: needed when charging disabled?
res = smbus_write(
CHARGER_ADDRESS,
REG_CHARGE_OPTION_2,
CHARGE_OPTION_2_PSYS_EN
CHARGE_OPTION_2_PSYS_EN | CHARGE_OPTION_2_PSYS_GAIN
);
if (res < 0) return res;
if (res < 0)
return res;
// Disable charge current
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_CURRENT, 0);
if (res < 0) return res;
if (res < 0)
return res;
// Disable charge voltage
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, 0);
if (res < 0) return res;
if (res < 0)
return res;
// Set input current in mA
//TODO: needed when charging disabled?
res = smbus_write(CHARGER_ADDRESS, REG_ADAPTER_CURRENT, CHARGER_INPUT_CURRENT);
if (res < 0) return res;
// Disable input current
res = smbus_write(CHARGER_ADDRESS, REG_ADAPTER_CURRENT, 0);
if (res < 0)
return res;
DEBUG("Charger disabled\n");
charger_enabled = false;
@@ -64,38 +133,49 @@ int16_t battery_charger_disable(void) {
int16_t battery_charger_enable(void) {
int16_t res = 0;
if (charger_enabled) return 0;
if (charger_enabled)
return 0;
res = battery_charger_disable();
if (res < 0) return res;
if (res < 0)
return res;
// Set charge option 1 to converter frequency 600 KHz
res = smbus_write(
CHARGER_ADDRESS,
REG_CHARGE_OPTION_1,
CHARGE_OPTION_1_600KHZ
CHARGE_OPTION_1_600KHZ | ADAPTER_RSENSE | BATTERY_RSENSE
);
if (res < 0) return res;
if (res < 0)
return res;
// Set charge option 2 to PSYS enable
res = smbus_write(
CHARGER_ADDRESS,
REG_CHARGE_OPTION_2,
CHARGE_OPTION_2_PSYS_EN
CHARGE_OPTION_2_PSYS_EN | CHARGE_OPTION_2_PSYS_GAIN
);
if (res < 0) return res;
if (res < 0)
return res;
// Set charge current in mA
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_CURRENT, CHARGER_CHARGE_CURRENT);
if (res < 0) return res;
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_CURRENT, CHARGE_CURRENT);
if (res < 0)
return res;
// Set charge voltage in mV
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, CHARGER_CHARGE_VOLTAGE);
if (res < 0) return res;
res = smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, CHARGE_VOLTAGE);
if (res < 0)
return res;
// Set input current in mA
res = smbus_write(CHARGER_ADDRESS, REG_ADAPTER_CURRENT, CHARGER_INPUT_CURRENT);
if (res < 0) return res;
res = smbus_write(
CHARGER_ADDRESS,
REG_ADAPTER_CURRENT,
INPUT_CURRENT(battery_charger_input_current)
);
if (res < 0)
return res;
DEBUG("Charger enabled\n");
charger_enabled = true;
@@ -106,7 +186,7 @@ void battery_charger_event(void) {
// Avoid watchdog timeout
if (charger_enabled) {
// Set charge voltage in mV
smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, CHARGER_CHARGE_VOLTAGE);
smbus_write(CHARGER_ADDRESS, REG_CHARGE_VOLTAGE, CHARGE_VOLTAGE);
}
}
@@ -114,7 +194,8 @@ void battery_debug(void) {
uint16_t data = 0;
int16_t res = 0;
#define command(N, A, V) { \
#define command(N, A, V) \
{ \
DEBUG(" " #N ": "); \
res = smbus_read(A, V, &data); \
if (res < 0) { \
@@ -138,5 +219,5 @@ void battery_debug(void) {
command(ChargeOption_2, CHARGER_ADDRESS, REG_CHARGE_OPTION_2);
command(AdapterCurrent, CHARGER_ADDRESS, REG_ADAPTER_CURRENT);
#undef command
#undef command
}

View File

@@ -1,5 +1,30 @@
# SPDX-License-Identifier: GPL-3.0-only
board-common-y += acpi.c
board-common-y += battery.c
board-common-y += config.c
board-common-$(CONFIG_HAVE_DGPU) += dgpu.c
board-common-y += ecpm.c
board-common-$(CONFIG_BUS_ESPI) += espi.c
board-common-y += fan.c
board-common-y += gctrl.c
board-common-y += kbc.c
board-common-y += kbscan.c
board-common-y += keymap.c
board-common-y += lid.c
board-common-y += main.c
board-common-y += parallel.c
board-common-y += pmc.c
board-common-y += pnp.c
board-common-y += ps2.c
board-common-y += pwm.c
board-common-y += scratch.c
board-common-$(CONFIG_SECURITY) += security.c
board-common-y += smbus.c
board-common-y += smfi.c
board-common-y += stdio.c
board-common-y += wireless.c
# Set log level
# 0 - NONE
# 1 - ERROR
@@ -15,17 +40,44 @@ CFLAGS+=-DLEVEL=4
# Uncomment to enable I2C debug on 0x76
#CFLAGS+=-DI2C_DEBUGGER=0x76
ifeq ($(CONFIG_PLATFORM_INTEL),y)
board-common-y += peci.c
board-common-y += power/intel.c
CFLAGS += -DCONFIG_PLATFORM_INTEL=1
else ifeq ($(CONFIG_PLATFORM_AMD),y)
board-common-y += power/amd.c
CFLAGS += -DCONFIG_PLATFORM_AMD=1
else
$(error PLATFORM not specified)
endif
ifeq ($(CONFIG_SECURITY),y)
CFLAGS+=-DCONFIG_SECURITY=1
endif
# Set external programmer
PROGRAMMER=$(wildcard /dev/serial/by-id/usb-Arduino*)
ifeq ($(CONFIG_BUS_ESPI),y)
CFLAGS += -DCONFIG_BUS_ESPI=1
# TODO: Use PECI over eSPI on all boards using eSPI
ifeq ($(CONFIG_PECI_OVER_ESPI),y)
CFLAGS += -DCONFIG_PECI_OVER_ESPI=1
endif
endif
ifeq ($(CONFIG_HAVE_DGPU),y)
CFLAGS += -DCONFIG_HAVE_DGPU=1
endif
# Include system76 common source
SYSTEM76_COMMON_DIR=src/board/system76/common
SRC+=$(wildcard $(SYSTEM76_COMMON_DIR)/*.c)
INCLUDE+=$(wildcard $(SYSTEM76_COMMON_DIR)/include/board/*.h) $(SYSTEM76_COMMON_DIR)/common.mk
INCLUDE += $(SYSTEM76_COMMON_DIR)/common.mk
CFLAGS+=-I$(SYSTEM76_COMMON_DIR)/include
# Set battery charging thresholds
BATTERY_START_THRESHOLD?=0
BATTERY_START_THRESHOLD?=90
BATTERY_END_THRESHOLD?=100
CFLAGS+=\
@@ -34,7 +86,13 @@ CFLAGS+=\
# Add charger
CHARGER?=bq24780s
SRC+=$(SYSTEM76_COMMON_DIR)/charger/$(CHARGER).c
board-common-y += charger/$(CHARGER).c
# Add USB-PD
ifeq ($(CONFIG_HAVE_USBPD),y)
CFLAGS += -DCONFIG_HAVE_USBPD=1
board-common-$(CONFIG_USBPD_TPS65987) += usbpd/tps65987.c
endif
# Add keyboard
ifndef KEYBOARD
@@ -44,14 +102,18 @@ KEYBOARD_DIR=src/keyboard/system76/$(KEYBOARD)
include $(KEYBOARD_DIR)/keyboard.mk
# Add kbled
KBLED?=none
SRC+=$(SYSTEM76_COMMON_DIR)/kbled/$(KBLED).c
ifeq ($(CONFIG_HAVE_KBLED),y)
CFLAGS += -DCONFIG_HAVE_KBLED=1
board-common-y += kbled/common.c
board-common-y += kbled/$(KBLED).c
endif
# Add scratch ROM
include $(SYSTEM76_COMMON_DIR)/scratch/scratch.mk
# Add scratch ROM for flash access
include $(SYSTEM76_COMMON_DIR)/flash/flash.mk
board-common-y += flash/wrapper.c
console_internal:
cargo build --manifest-path tool/Cargo.toml --release

View File

@@ -1,106 +1,43 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/dgpu.h>
#include <board/fan.h>
#if HAVE_DGPU
#include <board/gpio.h>
#include <board/peci.h>
#include <board/power.h>
#include <common/debug.h>
#include <common/macro.h>
#include <ec/i2c.h>
#include <ec/pwm.h>
// Fan speed is the lowest requested over HEATUP seconds
#ifndef BOARD_DGPU_HEATUP
#define BOARD_DGPU_HEATUP 4
#endif
static uint8_t FAN_HEATUP[BOARD_DGPU_HEATUP] = { 0 };
// Fan speed is the highest HEATUP speed over COOLDOWN seconds
#ifndef BOARD_DGPU_COOLDOWN
#define BOARD_DGPU_COOLDOWN 10
#endif
static uint8_t FAN_COOLDOWN[BOARD_DGPU_COOLDOWN] = { 0 };
int16_t dgpu_temp = 0;
#define DGPU_TEMP(X) ((int16_t)(X))
#define FAN_POINT(T, D) { .temp = DGPU_TEMP(T), .duty = PWM_DUTY(D) }
// Fan curve with temperature in degrees C, duty cycle in percent
static struct FanPoint __code FAN_POINTS[] = {
#ifdef BOARD_DGPU_FAN_POINTS
BOARD_DGPU_FAN_POINTS
#else
FAN_POINT(70, 40),
FAN_POINT(75, 50),
FAN_POINT(80, 60),
FAN_POINT(85, 65),
FAN_POINT(90, 65)
#endif
};
static struct Fan __code FAN = {
.points = FAN_POINTS,
.points_size = ARRAY_SIZE(FAN_POINTS),
.heatup = FAN_HEATUP,
.heatup_size = ARRAY_SIZE(FAN_HEATUP),
.cooldown = FAN_COOLDOWN,
.cooldown_size = ARRAY_SIZE(FAN_COOLDOWN),
.interpolate = SMOOTH_FANS != 0,
};
void dgpu_init(void) {
// Set up for i2c usage
i2c_reset(&I2C_DGPU, true);
}
uint8_t dgpu_get_fan_duty(void) {
uint8_t duty;
if (power_state == POWER_STATE_S0 && gpio_get(&DGPU_PWR_EN) && !gpio_get(&GC6_FB_EN)) {
// Use I2CS if in S0 state
bool dgpu_get_temp(int16_t *const data) {
if (gpio_get(&DGPU_PWR_EN) && !gpio_get(&GC6_FB_EN)) {
int8_t rlts;
int16_t res = i2c_get(&I2C_DGPU, 0x4F, 0x00, &rlts, 1);
if (res == 1) {
dgpu_temp = (int16_t)rlts;
duty = fan_duty(&FAN, dgpu_temp);
*data = (int16_t)rlts;
return true;
} else {
DEBUG("DGPU temp error: %d\n", res);
// Default to 50% if there is an error
dgpu_temp = 0;
duty = PWM_DUTY(50);
*data = 0;
return false;
}
} else {
// Turn fan off if not in S0 state or GPU power not on
dgpu_temp = 0;
duty = PWM_DUTY(0);
}
if (peci_on && fan_max) {
// Override duty if fans are manually set to maximum
duty = PWM_DUTY(100);
} else {
// Apply heatup and cooldown filters to duty
duty = fan_heatup(&FAN, duty);
duty = fan_cooldown(&FAN, duty);
*data = 0;
return true;
}
void dgpu_read_temp(void) {
if (power_state == POWER_STATE_S0) {
if (dgpu_get_temp(&dgpu_temp)) {
return;
}
}
TRACE("DGPU temp=%d\n", dgpu_temp);
return duty;
dgpu_temp = 0;
}
#else
void dgpu_init(void) {}
uint8_t dgpu_get_fan_duty(void) {
return PWM_DUTY(0);
}
#endif // HAVE_DGPU

View File

@@ -2,8 +2,6 @@
#include <board/espi.h>
#if EC_ESPI
#include <arch/delay.h>
#include <board/power.h>
#include <common/debug.h>
@@ -15,36 +13,34 @@
#include <8051.h>
#include <stdint.h>
#define DEBUG_SET(REG, MASK, BITS) { \
DEBUG("%s: %X", #REG, REG); \
REG = ((REG) & ~(MASK)) | (BITS); \
DEBUG(" set to %X\n", REG); \
}
#define DEBUG_SET(REG, MASK, BITS) \
{ \
DEBUG("%s: %X", #REG, REG); \
REG = (REG & ~(MASK)) | (BITS); \
DEBUG(" set to %X\n", REG); \
}
#define DEBUG_ON(REG, BITS) \
DEBUG_SET(REG, BITS, BITS)
#define DEBUG_ON(REG, BITS) DEBUG_SET(REG, BITS, BITS)
#define DEBUG_OFF(REG, BITS) \
DEBUG_SET(REG, BITS, 0)
#define DEBUG_OFF(REG, BITS) DEBUG_SET(REG, BITS, 0)
#define DEBUG_CHANGED(REG) { \
static uint8_t last_ ## REG = 0; \
uint8_t new_ ## REG = REG; \
if (new_ ## REG != last_ ## REG) { \
DEBUG( \
"%S: %X changed to %X\n", \
#REG, \
last_ ## REG, \
new_ ## REG \
); \
last_ ## REG = new_ ## REG; \
} \
}
#define DEBUG_CHANGED(REG) \
{ \
static uint8_t last_##REG = 0; \
uint8_t new_##REG = REG; \
if (new_##REG != last_##REG) { \
DEBUG("%S: %X changed to %X\n", #REG, last_##REG, new_##REG); \
last_##REG = new_##REG; \
} \
}
#define VW_SET_DEBUG(W, V) { \
DEBUG("%s = %X\n", #W, V); \
vw_set(&W, V); \
}
#define VW_SET_DEBUG(W, V) \
{ \
DEBUG("%s = %X\n", #W, V); \
vw_set(&W, V); \
}
bool espi_host_reset = false;
void espi_init(void) {
if (PLLFREQ != 0b0111) {
@@ -115,29 +111,12 @@ void espi_event(void) {
DEBUG("ESGCTRL0 %X\n", value);
if (value & BIT(1)) {
DEBUG("VW EN\n");
// Set SUS_ACK# low
VW_SET_DEBUG(VW_SUS_ACK_N, VWS_LOW);
}
if (value & BIT(2)) {
DEBUG("OOB EN\n");
VW_SET_DEBUG(VW_OOB_RST_ACK, VWS_LOW);
}
if (value & BIT(3)) {
DEBUG("FLASH EN\n");
// Set boot load status and boot load done high
// Set boot load status and boot load done high, once VWs can be set
VW_SET_DEBUG(VW_BOOT_LOAD_STATUS, VWS_HIGH);
VW_SET_DEBUG(VW_BOOT_LOAD_DONE, VWS_HIGH);
}
}
// Detect PUT_PC
value = ESPCTRL0;
if (value & BIT(7)) {
ESPCTRL0 = BIT(7);
DEBUG("ESPCTRL0 %X\n", value);
}
// Detect updated virtual wires
value = VWCTRL1;
if (value) {
@@ -166,6 +145,9 @@ void espi_event(void) {
VW_SET_DEBUG(VW_SMI_N, VWS_HIGH);
VW_SET_DEBUG(VW_RCIN_N, VWS_HIGH);
// Host reset complete
espi_host_reset = false;
power_cpu_reset();
}
last_pltrst_n = wire;
@@ -177,6 +159,11 @@ void espi_event(void) {
// Set HOST_RST_ACK to HOST_RST_WARN
wire = vw_get(&VW_HOST_RST_WARN);
if (wire != vw_get(&VW_HOST_RST_ACK)) {
if (wire == VWS_HIGH) {
// Host reset started
espi_host_reset = true;
}
VW_SET_DEBUG(VW_HOST_RST_ACK, wire);
}
}
@@ -189,13 +176,17 @@ void espi_event(void) {
VW_SET_DEBUG(VW_SUS_ACK_N, wire);
}
}
if (value & BIT(4)) {
DEBUG("VWIDX42 %X\n", VWIDX42);
}
if (value & BIT(5)) {
DEBUG("VWIDX43 %X\n", VWIDX43);
}
if (value & BIT(6)) {
DEBUG("VWIDX44 %X\n", VWIDX44);
}
if (value & BIT(7)) {
DEBUG("VWIDX47 %X\n", VWIDX47);
}
}
// Detect when frequency changes
DEBUG_CHANGED(ESGCTRL2);
// Detect when I/O mode changes
DEBUG_CHANGED(ESGCTRL3);
}
#endif // EC_ESPI

View File

@@ -1,33 +1,123 @@
// SPDX-License-Identifier: GPL-3.0-only
#include <board/fan.h>
#include <board/dgpu.h>
#include <board/power.h>
#include <common/debug.h>
#include <common/macro.h>
#include <ec/pwm.h>
#if SMOOTH_FANS != 0
#define MAX_JUMP_UP ((MAX_FAN_SPEED - MIN_FAN_SPEED) / (uint8_t)SMOOTH_FANS_UP)
#define MAX_JUMP_DOWN ((MAX_FAN_SPEED - MIN_FAN_SPEED) / (uint8_t)SMOOTH_FANS_DOWN)
#else
#define MAX_JUMP_UP (MAX_FAN_SPEED - MIN_FAN_SPEED)
#define MAX_JUMP_DOWN (MAX_FAN_SPEED - MIN_FAN_SPEED)
#if CONFIG_PLATFORM_INTEL
#include <board/peci.h>
#endif
#define MIN_SPEED_TO_SMOOTH PWM_DUTY(SMOOTH_FANS_MIN)
bool fan_max = false;
uint8_t last_duty_dgpu = 0;
uint8_t last_duty_peci = 0;
uint8_t fan1_pwm_actual = 0;
uint8_t fan1_pwm_target = 0;
uint16_t fan1_rpm = 0;
uint8_t fan2_pwm_actual = 0;
uint8_t fan2_pwm_target = 0;
uint16_t fan2_rpm = 0;
#define TACH_FREQ (CONFIG_CLOCK_FREQ_KHZ * 1000UL)
// Fan Speed (RPM) = 60 / (1/fs sec * {FnTMRR, FnRLRR} * P)
// - n: 1 or 2
// - P: the numbers of square pulses per revolution
// - fs: sample rate (FreqEC / 128)
// - {FnTMRR, FnTLRR} = 0000h: Fan Speed is zero
#define TACH_TO_RPM(x) (60UL * TACH_FREQ / 128UL / 2UL / (x))
#define FAN_POINT(T, D) { .temp = (int16_t)(T), .duty = PWM_DUTY(D) }
#ifndef FAN1_PWM_MIN
#define FAN1_PWM_MIN 0
#endif
// Fan speed is the lowest requested over HEATUP seconds
#ifndef BOARD_FAN1_HEATUP
#define BOARD_FAN1_HEATUP 4
#endif
static uint8_t FAN1_HEATUP[BOARD_FAN1_HEATUP] = { 0 };
// Fan speed is the highest HEATUP speed over COOLDOWN seconds
#ifndef BOARD_FAN1_COOLDOWN
#define BOARD_FAN1_COOLDOWN 10
#endif
static uint8_t FAN1_COOLDOWN[BOARD_FAN1_COOLDOWN] = { 0 };
// Fan curve with temperature in degrees C, duty cycle in percent
static const struct FanPoint __code FAN1_POINTS[] = {
#ifndef BOARD_FAN1_POINTS
#error Board must declare fan points
#else
BOARD_FAN1_POINTS
#endif
};
static const struct Fan __code FAN1 = {
.points = FAN1_POINTS,
.points_size = ARRAY_SIZE(FAN1_POINTS),
.heatup = FAN1_HEATUP,
.heatup_size = ARRAY_SIZE(FAN1_HEATUP),
.cooldown = FAN1_COOLDOWN,
.cooldown_size = ARRAY_SIZE(FAN1_COOLDOWN),
.pwm_min = PWM_DUTY(FAN1_PWM_MIN),
};
#ifdef FAN2_PWM
#ifndef FAN2_PWM_MIN
#define FAN2_PWM_MIN 0
#endif
// Fan speed is the lowest requested over HEATUP seconds
#ifndef BOARD_FAN2_HEATUP
#define BOARD_FAN2_HEATUP 4
#endif
static uint8_t FAN2_HEATUP[BOARD_FAN2_HEATUP] = { 0 };
// Fan speed is the highest HEATUP speed over COOLDOWN seconds
#ifndef BOARD_FAN2_COOLDOWN
#define BOARD_FAN2_COOLDOWN 10
#endif
static uint8_t FAN2_COOLDOWN[BOARD_FAN2_COOLDOWN] = { 0 };
// Fan curve with temperature in degrees C, duty cycle in percent
static const struct FanPoint __code FAN2_POINTS[] = {
#ifndef BOARD_FAN2_POINTS
#error Board must declare fan points
#else
BOARD_FAN2_POINTS
#endif
};
static const struct Fan __code FAN2 = {
.points = FAN2_POINTS,
.points_size = ARRAY_SIZE(FAN2_POINTS),
.heatup = FAN2_HEATUP,
.heatup_size = ARRAY_SIZE(FAN2_HEATUP),
.cooldown = FAN2_COOLDOWN,
.cooldown_size = ARRAY_SIZE(FAN2_COOLDOWN),
.pwm_min = PWM_DUTY(FAN2_PWM_MIN),
};
#endif // FAN2_PWM
void fan_reset(void) {
// Do not manually set fans to maximum speed
fan_max = false;
}
// Get duty cycle based on temperature, adapted from
// https://github.com/pop-os/system76-power/blob/master/src/fan.rs
uint8_t fan_duty(const struct Fan * fan, int16_t temp) __reentrant {
static uint8_t fan_duty(const struct Fan *const fan, int16_t temp) {
for (uint8_t i = 0; i < fan->points_size; i++) {
const struct FanPoint * cur = &fan->points[i];
const struct FanPoint *cur = &fan->points[i];
// If exactly the current temp, return the current duty
if (temp == cur->temp) {
@@ -35,55 +125,19 @@ uint8_t fan_duty(const struct Fan * fan, int16_t temp) __reentrant {
} else if (temp < cur->temp) {
// If lower than first temp, return 0%
if (i == 0) {
return MIN_FAN_SPEED;
return 0;
} else {
const struct FanPoint * prev = &fan->points[i - 1];
if (fan->interpolate) {
// If in between current temp and previous temp, interpolate
if (temp > prev->temp) {
int16_t dtemp = (cur->temp - prev->temp);
int16_t dduty = ((int16_t)cur->duty) - ((int16_t)prev->duty);
return (uint8_t)(
((int16_t)prev->duty) +
((temp - prev->temp) * dduty) / dtemp
);
}
} else {
return prev->duty;
}
const struct FanPoint *prev = &fan->points[i - 1];
return prev->duty;
}
}
}
// If no point is found, return 100%
return MAX_FAN_SPEED;
return CTR0;
}
void fan_duty_set(uint8_t peci_fan_duty, uint8_t dgpu_fan_duty) __reentrant {
#if SYNC_FANS != 0
peci_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty;
dgpu_fan_duty = peci_fan_duty > dgpu_fan_duty ? peci_fan_duty : dgpu_fan_duty;
#endif
// set PECI fan duty
if (peci_fan_duty != DCR2) {
TRACE("PECI fan_duty_raw=%d\n", peci_fan_duty);
last_duty_peci = peci_fan_duty = fan_smooth(last_duty_peci, peci_fan_duty);
DCR2 = fan_max ? MAX_FAN_SPEED : peci_fan_duty;
TRACE("PECI fan_duty_smoothed=%d\n", peci_fan_duty);
}
// set dGPU fan duty
if (dgpu_fan_duty != DCR4) {
TRACE("DGPU fan_duty_raw=%d\n", dgpu_fan_duty);
last_duty_dgpu = dgpu_fan_duty = fan_smooth(last_duty_dgpu, dgpu_fan_duty);
DCR4 = fan_max ? MAX_FAN_SPEED : dgpu_fan_duty;
TRACE("DGPU fan_duty_smoothed=%d\n", dgpu_fan_duty);
}
}
uint8_t fan_heatup(const struct Fan * fan, uint8_t duty) __reentrant {
static uint8_t fan_heatup(const struct Fan *const fan, uint8_t duty) {
uint8_t lowest = duty;
uint8_t i;
@@ -99,7 +153,7 @@ uint8_t fan_heatup(const struct Fan * fan, uint8_t duty) __reentrant {
return lowest;
}
uint8_t fan_cooldown(const struct Fan * fan, uint8_t duty) __reentrant {
static uint8_t fan_cooldown(const struct Fan *const fan, uint8_t duty) {
uint8_t highest = duty;
uint8_t i;
@@ -115,34 +169,109 @@ uint8_t fan_cooldown(const struct Fan * fan, uint8_t duty) __reentrant {
return highest;
}
uint8_t fan_smooth(uint8_t last_duty, uint8_t duty) __reentrant {
uint8_t next_duty = duty;
static uint8_t fan_get_duty(const struct Fan *const fan, int16_t temp) {
uint8_t duty;
// ramping down
if (duty < last_duty) {
// out of bounds (lower) safeguard
uint8_t smoothed = last_duty < MIN_FAN_SPEED + MAX_JUMP_DOWN
? MIN_FAN_SPEED
: last_duty - MAX_JUMP_DOWN;
duty = fan_duty(fan, temp);
duty = fan_heatup(fan, duty);
duty = fan_cooldown(fan, duty);
// use smoothed value if above min and if smoothed is closer than raw
if (last_duty > MIN_SPEED_TO_SMOOTH && smoothed > duty) {
next_duty = smoothed;
}
}
// ramping up
if (duty > last_duty) {
// out of bounds (higher) safeguard
uint8_t smoothed = last_duty > MAX_FAN_SPEED - MAX_JUMP_UP
? MAX_FAN_SPEED
: last_duty + MAX_JUMP_UP;
// use smoothed value if above min and if smoothed is closer than raw
if (duty > MIN_SPEED_TO_SMOOTH && smoothed < duty) {
next_duty = smoothed;
}
}
return next_duty;
return duty;
}
static uint16_t fan_get_tach0_rpm(void) {
uint16_t rpm = (F1TMRR << 8) | F1TLRR;
if (rpm)
rpm = TACH_TO_RPM(rpm);
return rpm;
}
static uint16_t fan_get_tach1_rpm(void) {
uint16_t rpm = (F2TMRR << 8) | F2TLRR;
if (rpm)
rpm = TACH_TO_RPM(rpm);
return rpm;
}
void fan_event(void) {
#if CONFIG_PLATFORM_INTEL
#if CONFIG_HAVE_DGPU
int16_t sys_temp = MAX(peci_temp, dgpu_temp);
#else
int16_t sys_temp = peci_temp;
#endif
#elif CONFIG_PLATFORM_AMD
// TODO: AMD SB-TSI temp
int16_t sys_temp = 50;
#endif
// Fan update interval is 100ms (main.c). The event changes PWM duty
// by 1 every interval to give a smoothing effect.
// Enabling fan max toggle and exiting S0 will cause duty to immediately
// change instead of stepping to provide the desired effects.
// Set FAN1 duty
fan1_pwm_target = fan_get_duty(&FAN1, sys_temp);
if (fan_max) {
fan1_pwm_target = CTR0;
fan1_pwm_actual = CTR0;
} else if (power_state != POWER_STATE_S0) {
fan1_pwm_target = 0;
fan1_pwm_actual = 0;
} else {
if (fan1_pwm_actual < fan1_pwm_target) {
if (fan1_pwm_actual < CTR0) {
fan1_pwm_actual++;
if (fan1_pwm_actual < FAN1.pwm_min) {
fan1_pwm_actual = FAN1.pwm_min;
}
}
} else if (fan1_pwm_actual > fan1_pwm_target) {
if (fan1_pwm_actual > 0) {
fan1_pwm_actual--;
if (fan1_pwm_actual < FAN1.pwm_min) {
fan1_pwm_actual = 0;
}
}
}
}
TRACE("FAN1 duty=%d\n", fan1_pwm_actual);
FAN1_PWM = fan1_pwm_actual;
fan1_rpm = fan_get_tach0_rpm();
#ifdef FAN2_PWM
// set FAN2 duty
fan2_pwm_target = fan_get_duty(&FAN2, sys_temp);
if (fan_max) {
fan2_pwm_target = CTR0;
fan2_pwm_actual = CTR0;
} else if (power_state != POWER_STATE_S0) {
fan2_pwm_target = 0;
fan2_pwm_actual = 0;
} else {
if (fan2_pwm_actual < fan2_pwm_target) {
if (fan2_pwm_actual < CTR0) {
fan2_pwm_actual++;
if (fan2_pwm_actual < FAN2.pwm_min) {
fan2_pwm_actual = FAN2.pwm_min;
}
}
} else if (fan2_pwm_actual > fan2_pwm_target) {
if (fan2_pwm_actual > 0) {
fan2_pwm_actual--;
if (fan2_pwm_actual < FAN2.pwm_min) {
fan2_pwm_actual = 0;
}
}
}
}
TRACE("FAN2 duty=%d\n", fan2_pwm_actual);
FAN2_PWM = fan2_pwm_actual;
fan2_rpm = fan_get_tach1_rpm();
#endif
}

View File

@@ -1,5 +1,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later
flash-y += main.c
# Set flash ROM parameters
FLASH_OFFSET=2048
FLASH_SIZE=1024
@@ -12,15 +14,16 @@ FLASH_CFLAGS=$(CFLAGS)
# Include flash source.
FLASH_DIR=$(SYSTEM76_COMMON_DIR)/flash
# Note: main.c *must* be first to ensure that flash_start is at the correct address
FLASH_SRC=$(FLASH_DIR)/main.c
FLASH_INCLUDE+=$(wildcard $(FLASH_DIR)/include/flash/*.h) $(FLASH_DIR)/flash.mk
FLASH_INCLUDE += $(FLASH_DIR)/flash.mk
FLASH_CFLAGS+=-I$(FLASH_DIR)/include -D__FLASH__
FLASH_SRC += $(foreach src, $(flash-y), $(FLASH_DIR)/$(src))
FLASH_BUILD=$(BUILD)/flash
FLASH_OBJ=$(sort $(patsubst src/%.c,$(FLASH_BUILD)/%.rel,$(FLASH_SRC)))
FLASH_CC=\
sdcc \
-mmcs51 \
-MMD \
--model-large \
--opt-code-size \
--acall-ajmp \
@@ -30,26 +33,29 @@ FLASH_CC=\
# Convert from binary file to C header
$(BUILD)/include/flash.h: $(FLASH_BUILD)/flash.rom
@mkdir -p $(@D)
xxd -s $(FLASH_OFFSET) --include < $< > $@
@echo " XXD $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
xxd -include < $< > $@
# Convert from Intel Hex file to binary file
$(FLASH_BUILD)/flash.rom: $(FLASH_BUILD)/flash.ihx
@mkdir -p $(@D)
makebin -p < $< > $@
@echo " OBJCOPY $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
objcopy -I ihex -O binary $< $@
# Link object files into Intel Hex file
$(FLASH_BUILD)/flash.ihx: $(FLASH_OBJ)
@mkdir -p $(@D)
@echo " LINK $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
$(FLASH_CC) -o $@ $^
# Compile C files into object files
$(FLASH_OBJ): $(FLASH_BUILD)/%.rel: src/%.c $(FLASH_INCLUDE)
@mkdir -p $(@D)
@echo " CC $(subst $(BUILD)/,,$@)"
mkdir -p $(@D)
$(FLASH_CC) $(FLASH_CFLAGS) -o $@ -c $<
# Include flash header in main firmware
CFLAGS+=-I$(BUILD)/include
LDFLAGS+=-Wl -g_flash_entry=$(FLASH_OFFSET)
INCLUDE+=$(BUILD)/include/flash.h
SRC+=$(FLASH_DIR)/wrapper.c

View File

@@ -3,6 +3,6 @@
#ifndef _FLASH_ENTRY_H
#define _FLASH_ENTRY_H
void flash_entry(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command) __reentrant;
void flash_entry(uint32_t addr, uint8_t *data, uint32_t length, uint8_t command) __reentrant;
#endif // _FLASH_ENTRY_H

View File

@@ -46,11 +46,10 @@ void flash_write_enable(void);
* NOTE: __critical to ensure interrupts are disabled. This does mean that interrupt
* such as the timer will be block until flash acccess is complete
*/
void flash_entry(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command) __reentrant __critical {
void flash_entry(uint32_t addr, uint8_t *data, uint32_t length,
uint8_t command) __reentrant __critical {
// Only allow access from 64KB to 128KB.
if ((addr < 0x10000)
|| (length > 0x10000)
|| ((addr + length) > 0x20000))
if ((addr < 0x10000) || (length > 0x10000) || ((addr + length) > 0x20000))
return;
if (command == FLASH_COMMAND_READ) {
@@ -71,7 +70,8 @@ void flash_entry(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command
flash_enter_follow_mode();
while (length) {
// Note, this is the slow way to do it, but it's simple and all bytes are written properly.
// Note, this is the slow way to do it, but it's simple and all
// bytes are written properly.
flash_write_enable();
// Select the device
@@ -91,8 +91,7 @@ void flash_entry(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command
// Deselect
ECINDAR1 = SPI_CHIP_DESELECT;
ECINDDR = 0x00;
ECINDDR = 0x00;
// Wait WIP to be cleared
flash_wait();
@@ -115,7 +114,7 @@ void flash_entry(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command
// Deselect
ECINDAR1 = SPI_CHIP_DESELECT;
ECINDDR = 0x00;
ECINDDR = 0x00;
// Wait WIP to be cleared
flash_wait();
@@ -156,8 +155,8 @@ void flash_wait(void) {
// Deselect
ECINDAR1 = SPI_CHIP_DESELECT;
ECINDDR = 0x00;
} while(status & SPI_STATUS_WIP);
ECINDDR = 0x00;
} while (status & SPI_STATUS_WIP);
}
void flash_write_enable(void) {
@@ -169,5 +168,5 @@ void flash_write_enable(void) {
// Deselect
ECINDAR1 = SPI_CHIP_DESELECT;
ECINDDR = 0x00;
ECINDDR = 0x00;
}

View File

@@ -12,10 +12,10 @@
// Include flash ROM
uint8_t __code __at(FLASH_OFFSET) flash_rom[] = {
#include <flash.h>
#include <flash.h>
};
static void flash_api(uint32_t addr, uint8_t * data, uint32_t length, uint8_t command) {
static void flash_api(uint32_t addr, uint8_t *const data, uint32_t length, uint8_t command) {
// Use DMA mapping to copy flash ROM to scratch ROM
SCARH = 0x80;
SCARL = (uint8_t)(FLASH_OFFSET);
@@ -29,7 +29,7 @@ static void flash_api(uint32_t addr, uint8_t * data, uint32_t length, uint8_t co
SCARH = 0x07;
}
void flash_read(uint32_t addr, __xdata uint8_t * data, uint32_t length) {
void flash_read(uint32_t addr, __xdata uint8_t *const data, uint32_t length) {
flash_api(addr, data, length, FLASH_COMMAND_READ);
}
@@ -57,7 +57,7 @@ uint8_t flash_read_u8(uint32_t addr) {
return data;
}
void flash_write(uint32_t addr, __xdata uint8_t *data, uint32_t length) {
void flash_write(uint32_t addr, __xdata uint8_t *const data, uint32_t length) {
flash_api(addr, data, length, FLASH_COMMAND_WRITE);
}

View File

@@ -7,11 +7,11 @@
enum EcOs {
// No ACPI or driver support
EC_OS_NONE=0,
EC_OS_NONE = 0,
// ACPI, but no driver support
EC_OS_ACPI=1,
EC_OS_ACPI = 1,
// ACPI with driver, full support
EC_OS_FULL=2,
EC_OS_FULL = 2,
};
extern enum EcOs acpi_ecos;

View File

@@ -9,13 +9,16 @@
#include <stdint.h>
#ifndef BATTERY_ADDRESS
#define BATTERY_ADDRESS 0x0B
#define BATTERY_ADDRESS 0x0B
#endif
#ifndef CHARGER_ADDRESS
#define CHARGER_ADDRESS 0x09
#define CHARGER_ADDRESS 0x09
#endif
#define BATTERY_FULLY_DISCHARGED BIT(4)
#define BATTERY_FULLY_CHARGED BIT(5)
#define BATTERY_DISCHARGING BIT(6)
#define BATTERY_INITIALIZED BIT(7)
struct battery_info {
@@ -32,6 +35,8 @@ struct battery_info {
};
extern struct battery_info battery_info;
extern uint16_t battery_charger_input_current;
uint8_t battery_get_start_threshold(void);
bool battery_set_start_threshold(uint8_t value);

View File

@@ -3,17 +3,28 @@
#ifndef _BOARD_DGPU_H
#define _BOARD_DGPU_H
#include <stdbool.h>
#include <stdint.h>
#ifndef HAVE_DGPU
#define HAVE_DGPU 0
#endif
#if CONFIG_HAVE_DGPU
#if HAVE_DGPU
extern int16_t dgpu_temp;
#endif // HAVE_DGPU
extern int16_t dgpu_temp;
void dgpu_init(void);
uint8_t dgpu_get_fan_duty(void);
bool dgpu_get_temp(int16_t *const data);
void dgpu_read_temp(void);
#else
static inline void dgpu_init(void) {}
static inline bool dgpu_get_temp(int16_t *const data) {
*data = 0;
return true;
}
static inline void dgpu_read_temp(void) {}
#endif // CONFIG_HAVE_DGPU
#endif // _BOARD_DGPU_H

View File

@@ -3,8 +3,12 @@
#ifndef _BOARD_ESPI_H
#define _BOARD_ESPI_H
#include <stdbool.h>
#include <ec/espi.h>
extern bool espi_host_reset;
void espi_init(void);
void espi_reset(void);
void espi_event(void);

View File

@@ -7,29 +7,6 @@
#include <stdint.h>
#define PWM_DUTY(X) ((uint8_t)(((((uint16_t)(X)) * 255) + 99) / 100))
#define MAX_FAN_SPEED PWM_DUTY(100)
#define MIN_FAN_SPEED PWM_DUTY(0)
#ifndef SMOOTH_FANS
#define SMOOTH_FANS 1 // default to fan smoothing
#endif
#ifndef SYNC_FANS
#define SYNC_FANS 1 // default to syncing fan speeds
#endif
#if SMOOTH_FANS != 0
#ifndef SMOOTH_FANS_UP
#define SMOOTH_FANS_UP 45 // default to ~11 seconds for full ramp-up
#endif
#ifndef SMOOTH_FANS_DOWN
#define SMOOTH_FANS_DOWN 100 // default to ~25 seconds for full ramp-down
#endif
#endif
#ifndef SMOOTH_FANS_MIN
#define SMOOTH_FANS_MIN 0 // default to smoothing all fan speed changes
#endif
struct FanPoint {
int16_t temp;
@@ -37,23 +14,25 @@ struct FanPoint {
};
struct Fan {
const struct FanPoint * points;
const struct FanPoint *points;
uint8_t points_size;
uint8_t * heatup;
uint8_t *heatup;
uint8_t heatup_size;
uint8_t * cooldown;
uint8_t *cooldown;
uint8_t cooldown_size;
bool interpolate;
uint8_t pwm_min;
};
extern bool fan_max;
void fan_reset(void);
extern uint8_t fan1_pwm_actual;
extern uint8_t fan1_pwm_target;
extern uint16_t fan1_rpm;
extern uint8_t fan2_pwm_actual;
extern uint8_t fan2_pwm_target;
extern uint16_t fan2_rpm;
uint8_t fan_duty(const struct Fan * fan, int16_t temp) __reentrant;
void fan_duty_set(uint8_t peci_fan_duty, uint8_t dgpu_fan_duty) __reentrant;
uint8_t fan_heatup(const struct Fan * fan, uint8_t duty) __reentrant;
uint8_t fan_cooldown(const struct Fan * fan, uint8_t duty) __reentrant;
uint8_t fan_smooth(uint8_t last_duty, uint8_t duty) __reentrant;
void fan_reset(void);
void fan_event(void);
#endif // _BOARD_FAN_H

View File

@@ -24,7 +24,7 @@
* \param[out] data The memory area to copy to.
* \param[in] length The number of bytes to copy.
*/
void flash_read(uint32_t addr, __xdata uint8_t * data, uint32_t length);
void flash_read(uint32_t addr, __xdata uint8_t *const data, uint32_t length);
/**
* Read a single byte from flash.
@@ -60,7 +60,7 @@ uint32_t flash_read_u32(uint32_t addr);
* \param[in] data The memory area to copy from.
* \param[in] length The number of bytes to copy.
*/
void flash_write(uint32_t addr, __xdata uint8_t * data, uint32_t length);
void flash_write(uint32_t addr, __xdata uint8_t *const data, uint32_t length);
/**
* Write a single byte to flash.

View File

@@ -10,7 +10,8 @@
extern uint8_t kbc_leds;
void kbc_init(void);
void kbc_reset(void);
bool kbc_scancode(uint16_t key, bool pressed);
void kbc_event(struct Kbc * kbc);
void kbc_event(struct Kbc *const kbc);
#endif // _BOARD_KBC_H

View File

@@ -5,7 +5,16 @@
#include <stdint.h>
// Must be specified by board
#if CONFIG_HAVE_KBLED
enum KbledKind {
KBLED_NONE = 0,
KBLED_WHITE = 1,
KBLED_RGB = 2,
};
extern enum KbledKind kbled_kind;
// Must be specified per mechanism
void kbled_init(void);
void kbled_reset(void);
uint8_t kbled_get(void);
@@ -19,5 +28,39 @@ void kbled_hotkey_color(void);
void kbled_hotkey_down(void);
void kbled_hotkey_up(void);
void kbled_hotkey_toggle(void);
void kbled_hotkey_step(void);
#else // CONFIG_HAVE_KBLED
static inline void kbled_init(void) {}
static inline void kbled_reset(void) {}
static inline uint8_t kbled_get(void) {
return 0;
}
static inline uint8_t kbled_max(void) {
return 0;
}
static inline void kbled_set(uint8_t level) {
(void)level;
}
static inline uint32_t kbled_get_color(void) {
return 0;
}
static inline void kbled_set_color(uint32_t color) {
(void)color;
}
static inline void kbled_hotkey_color(void) {}
static inline void kbled_hotkey_down(void) {}
static inline void kbled_hotkey_up(void) {}
static inline void kbled_hotkey_toggle(void) {}
static inline void kbled_hotkey_step(void) {}
#endif // CONFIG_HAVE_KBLED
#endif // _BOARD_KBLED_H

View File

@@ -8,6 +8,6 @@
extern bool parallel_debug;
bool parallel_init(void);
int16_t parallel_write(uint8_t * data, uint16_t length);
int16_t parallel_write(const uint8_t *const data, uint16_t length);
#endif // _BOARD_PARALLEL_H

Some files were not shown because too many files have changed in this diff Show More