-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers/mfd: it8801: Implement ITE IT8801 mfd drivers #79416
base: main
Are you sure you want to change the base?
Conversation
eaac9c2
to
372ce90
Compare
There was a problem hiding this 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.
drivers/mfd/mfd_ite_it8801.c
Outdated
#include <zephyr/logging/log.h> | ||
LOG_MODULE_REGISTER(mfd_ite_it8801, CONFIG_MFD_LOG_LEVEL); | ||
|
||
static const struct device *kbd_dev = DEVICE_DT_GET_ANY(ite_it8801_kbd); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, use multiple instances.
drivers/mfd/mfd_ite_it8801.c
Outdated
for (i = 0; i < config->sub_mfd_node_num; i++) { | ||
if (config->sub_mfd_dev[i] != NULL) { | ||
if (config->sub_mfd_dev[i] == kbd_dev) { | ||
it8801_input_alert_handler(config->sub_mfd_dev[i]); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
dts/riscv/ite/it8801-mfd-gpiocr.dtsi
Outdated
|
||
/ { | ||
soc { | ||
gpio0: gpiocr@0a { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed.
drivers/input/input_ite_it8801_kbd.c
Outdated
#include <zephyr/logging/log.h> | ||
LOG_MODULE_REGISTER(input_ite_it8801_kbd, CONFIG_INPUT_LOG_LEVEL); | ||
|
||
#define IT8801_MFDCTRL_COUNT IT8801_DT_INST_MFDCTRL_LEN(0) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, use multiple instances.
drivers/input/input_ite_it8801_kbd.c
Outdated
|
||
static struct kbd_it8801_data kbd_it8801_data_0; | ||
|
||
PM_DEVICE_DT_INST_DEFINE(0, input_kbd_matrix_pm_action); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, use multiple instances.
drivers/pwm/pwm_ite_it8801.c
Outdated
static struct pwm_it8801_data pwm_it8801_data_##inst; \ | ||
DEVICE_DT_INST_DEFINE(inst, &pwm_it8801_init, NULL, &pwm_it8801_data_##inst, \ | ||
&pwm_it8801_cfg_##inst, POST_KERNEL, \ | ||
CONFIG_PWM_IT8801_INIT_PRIORITY, &pwm_it8801_api); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
IT8801 GPIO port device driver initialization priority. The priority | ||
must be lower than MFD_INIT_PRIORITY device. |
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
drivers/mfd/mfd_ite_it8801.c
Outdated
struct mfd_it8801_data *data = dev->data; | ||
int ret; | ||
|
||
if (!device_is_ready(config->i2c_dev.bus)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use i2c_is_ready_dt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
drivers/mfd/mfd_ite_it8801.c
Outdated
.i2c_dev = I2C_DT_SPEC_INST_GET(inst), \ | ||
.irq_gpios = GPIO_DT_SPEC_INST_GET(inst, irq_gpios), \ | ||
.sub_mfd_dev = sub_mfd_dev_##inst, \ | ||
.sub_mfd_node_num = DT_INST_CHILD_NUM(inst), \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering it would not be safer to use ARRAY_SIZE(sub_mfd_dev_##inst)
, just in case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
drivers/mfd/mfd_ite_it8801.c
Outdated
int i; | ||
|
||
for (i = 0; i < config->sub_mfd_node_num; i++) { | ||
if (config->sub_mfd_dev[i] != NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this happen? I think it would fail the build if there's no actual device here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant, removed.
config MFD_IT8801_ALTCTRL_INIT_PRIORITY | ||
int "IT8801 GPIO port init priority" | ||
default 81 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
dts/riscv/ite/it8801-mfd-gpiocr.dtsi
Outdated
*/ | ||
|
||
/ { | ||
soc { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not look quite right, how is this dtsi going to be used? the child nodes here should be child nodes of the mfd device, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is the child node that mfd will use. Renamed.
drivers/pwm/pwm_ite_it8801.c
Outdated
|
||
struct pwm_it8801_data { | ||
/* I2C device for the MFD parent */ | ||
const struct i2c_dt_spec *i2c_dev; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ite,it8801-pwm
is a child node of the mfd device right? Then can you get this with DEVICE_DT_GET(DT_PARENT(...))
at build time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's right, thanks for the tip, we can use this: I2C_DT_SPEC_GET(DT_INST_PARENT(inst))
drivers/pwm/pwm_ite_it8801.c
Outdated
static struct pwm_it8801_data pwm_it8801_data_##inst; \ | ||
DEVICE_DT_INST_DEFINE(inst, &pwm_it8801_init, NULL, &pwm_it8801_data_##inst, \ | ||
&pwm_it8801_cfg_##inst, POST_KERNEL, \ | ||
CONFIG_PWM_IT8801_INIT_PRIORITY, &pwm_it8801_api); |
There was a problem hiding this comment.
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.
372ce90
to
2d60741
Compare
The IT8801 is an I/O expander that provides GPIO, PWM, Keyboard functions via the I2C bus. Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
IT8801 support GPIO alternate function switching. Some GPIO pins can be switched as KSO or PWM function. Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
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 <tim2.lin@ite.corp-partner.google.com>
Add I2C-based PWM device driver. Supports 7 open-drain/push-pull outputs. Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
Add I2C-based GPIO device driver. Supports 16-port GPIO divided into 3 groups. Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
2d60741
to
71000b0
Compare
I have created a test program to connect with it8xxx2_evb as shown in the link |
This is very strange. When using ./scripts/ci/check_compliance.py locally, there is a prompt such as:
But after I upload the program, I get the following error:
|
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.