Skip to content

Conversation

@GTLin08
Copy link
Contributor

@GTLin08 GTLin08 commented Oct 4, 2024

This PR Implements the ITE IT8801 IO expander multi-function device driver. The IO expander provides GPIO, PWM, and keyboard functions via the I2C bus.

Copy link
Contributor

@keith-zephyr keith-zephyr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also consider running clang-format on all the files.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This driver supports multiple instances, but this this assumes that there is only one IT8801 defined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, use multiple instances.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function isn't available in this commit. Each commit should build on it's own. Add this support with the KBD driver commit.

You could have the child drivers register an alert callback. Then MFD driver doesn't need to know the type of each child.

If you wanted the alert callbacks to be configured at build time, you could define an iterable section per it8801 instance.

See INPUT_CALL_DEFINE for an example of creating an iterable section for a specific device instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to respective driver.

Because the KBD and GPIO devices of IT8801 share the gpio irq. Consider that if IT8801 is connected to the EC, the GPIO interrupt is enabled in the interrupt configuration using irq_connect_dynamic.
Repeated registration of gpio irq will cause Assert problem, so here we only register it once in mfd_ite_it8801.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nodename gpio0 is likely to conflict the the GPIO controller on the SoC.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes only one KBD driver installed. This should be calculated on each KBD instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, use multiple instances.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drivers should support multiple instances.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, use multiple instances.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a BUILD_ASSERT that the init priority is lower (higher number) than the MFD parent.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggested in a separate comment that this could all use the same priority, then the sub priority would take care of sequencing the init correctly, I think it's a better approach, less options kicking around. Build asserts should not be needed anymore since the build priorites are checked at build time btw.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anything I can refer to here? I'm encountering a build error when using CONFIG_MFD_INIT_PRIORITY + 1 in Kconfig or here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use CONFIG_MFD_INIT_PRIORITY on all the child devices.

Comment on lines 19 to 20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a BUILD_ASSERT to check the init priority.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use CONFIG_MFD_INIT_PRIORITY on all the child devices.

Copy link
Member

@fabiobaltieri fabiobaltieri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an quick initial, pass, noticed some comments of mine overlaps with Keith.

Hey is there a board where you could add this? I'm a bit confused by the dtsi file you have in one of the commits, would be nice to have build testing in CI as well.

Comment on lines 19 to 21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey can you try to initialize all the sub devices at CONFIG_MFD_INIT_PRIORITY? the sub-priority should take care of the sequencing, less priority options kicking around... you can check the output with west build -t initlevels

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anything I can refer to here? I'm encountering a build error when using CONFIG_MFD_INIT_PRIORITY + 1 here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah just use CONFIG_MFD_INIT_PRIORITY on all the child devices, then the effective initialization number is going to be a concatenation of CONFIG_MFD_INIT_PRIORITY and the ordinal that the device gets [1][2], and since the childs are under the parent the child ordinal is going to be higher than the parent which is going to result in the correct initialization sequence.

[1] https://github.com/zephyrproject-rtos/zephyr/blob/main/include/zephyr/device.h#L1112
[2] https://github.com/zephyrproject-rtos/zephyr/blob/main/include/zephyr/init.h#L150C43-L150C51

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the information, fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggested in a separate comment that this could all use the same priority, then the sub priority would take care of sequencing the init correctly, I think it's a better approach, less options kicking around. Build asserts should not be needed anymore since the build priorites are checked at build time btw.

@GTLin08 GTLin08 force-pushed the it8xxx2_mfd_driver branch 2 times, most recently from 2d60741 to 71000b0 Compare October 7, 2024 11:19
@GTLin08
Copy link
Contributor Author

GTLin08 commented Oct 7, 2024

Just an quick initial, pass, noticed some comments of mine overlaps with Keith.

Hey is there a board where you could add this? I'm a bit confused by the dtsi file you have in one of the commits, would be nice to have build testing in CI as well.

I have created a test program to connect with it8xxx2_evb as shown in the link

@GTLin08
Copy link
Contributor Author

GTLin08 commented Oct 7, 2024

Also consider running clang-format on all the files.

This is very strange. When using ./scripts/ci/check_compliance.py locally, there is a prompt such as:

You may want to run clang-format on this change

drivers/mfd/mfd_ite_it8801.c:133 
-		DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(inst, DEVICE_DT_GET, (,))};                  \
+		DT_INST_FOREACH_CHILD_STATUS_OKAY_SEP(inst, DEVICE_DT_GET, (, ))};                 \

But after I upload the program, I get the following error:

SPACING: space prohibited before that close parenthesis ')'
File:drivers/mfd/mfd_ite_it8801.c
Line:132

@GTLin08 GTLin08 force-pushed the it8xxx2_mfd_driver branch from f1393fc to 895308e Compare October 14, 2024 08:22
@GTLin08
Copy link
Contributor Author

GTLin08 commented Oct 14, 2024

Rebase and resolve conflicting files.

@GTLin08
Copy link
Contributor Author

GTLin08 commented Oct 17, 2024

Hi @fabiobaltieri, @keith-zephyr, If there’s any further feedback on the updates I made. Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node names should use dashes instead of underscores.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the relative path necessary? Does #include <ite/it8801-mfd-map.dtsi> work instead?

Copy link
Contributor Author

@GTLin08 GTLin08 Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed to #include <ite/it8801-mfd-map.dtsi>

Comment on lines 77 to 82
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option here. The children devices already have a reference to the parent mfd. The MFD driver could add an API to register an interrupt callback.

mfd_it8801_register_interrupt_callback(const struct device *mfd,
    const struct device *child,
    callback_function);

Then you could also drop sub_mfd_dev array, and you could drop the if (dev != data->gpio_dev) checks in the child drivers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion! It really helped simplify the code.

@GTLin08 GTLin08 force-pushed the it8xxx2_mfd_driver branch from 895308e to 4e9db70 Compare October 18, 2024 09:25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should check that mfd_cb has been assigned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 63 to 64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there always a 1:1 relationship from the MFD parent to the child that needs an interrupt callback?
Or does the MFD need to maintain a list of callbacks registered?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the MFD needs to maintain a list of registered callbacks, and I have made the modifications.

@GTLin08 GTLin08 force-pushed the it8xxx2_mfd_driver branch from 4e9db70 to 6023ee2 Compare October 25, 2024 09:53
Comment on lines 74 to 80
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still more complicated than needed. The MFD parent doesn't need to know if the child is a KBD, GPIO, or PWM.

You should create a structure that each child is responsible for allocating:

struct mfd_callback {
    it8801_callback_handler_t cb;
    const struct device *dev;
};

Then the mfd_it8801_register_interrupt_callback() routine needs to just add the mfd_callback allocated by the child to a linked list. You can use the the gpio_manage_callback() for creating the linked list.

Then when dispatching the interrupt in it8801_gpio_alert_worker, you only need to iterate over the linked list. No special checks for KBD vs GPIO are needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@GTLin08 GTLin08 force-pushed the it8xxx2_mfd_driver branch from 6023ee2 to b7af79e Compare November 4, 2024 07:41
Copy link
Member

@fabiobaltieri fabiobaltieri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool, few more comments, sorry for the delay this fell of my radar

@GTLin08
Copy link
Contributor Author

GTLin08 commented Nov 18, 2024

Rebased.

Copy link
Member

@fabiobaltieri fabiobaltieri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool, couple missing static qualifiers, rest is good, great job, Keith is out for the next couple of weeks I think it's fine to wait for him?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@GTLin08
Copy link
Contributor Author

GTLin08 commented Nov 21, 2024

cool, couple missing static qualifiers, rest is good, great job, Keith is out for the next couple of weeks I think it's fine to wait for him?

OKey, thank you for your feedback!

fabiobaltieri
fabiobaltieri previously approved these changes Nov 21, 2024
Comment on lines 312 to 316
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GPISR documentation in the IT8801 datasheet indicates:
"When GPIO Direction is 0, and the state of the corresponding pin matches the interrupt triggered condition, the corresponding bit will be set to 1."

The level_high_trig and level_low_trig fields don't seem necessary. Does the driver need to track level triggered interrupts separate from the IT8801?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IT8801 already supports level-triggered interrupts internally. Therefore, the level_high_trig and level_low_trig fields are redundant and have been removed.

The IT8801 is an I/O expander that provides GPIO, PWM, Keyboard
functions via the I2C bus.

Signed-off-by: Tim Lin <[email protected]>
IT8801 support GPIO alternate function switching.
Some GPIO pins can be switched as KSO or PWM function.

Signed-off-by: Tim Lin <[email protected]>
Add I2C-based keyboard matrix scan device driver.
IT8801 support 8 KSI pins and 19 KSO pins [22:11] [6:0].

Signed-off-by: Tim Lin <[email protected]>
Add I2C-based PWM device driver. Supports 7 open-drain/push-pull
outputs.

Signed-off-by: Tim Lin <[email protected]>
Add I2C-based GPIO device driver. Supports 16-port GPIO divided
into 3 groups.

Signed-off-by: Tim Lin <[email protected]>
Add build tests for the IT8801 MFD drivers, including GPIO,
Input and PWM functionalities.

GPIO, Input test: west build -p always -b native_sim
PWM test: west build -p always -b it82xx2_evb

Signed-off-by: Tim Lin <[email protected]>
@kartben kartben merged commit e7b7356 into zephyrproject-rtos:main Dec 3, 2024
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: GPIO area: Input Input Subsystem and Drivers area: MFD area: PWM Pulse Width Modulation area: RISCV RISCV Architecture (32-bit & 64-bit) platform: ITE ITE

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants