1 // SPDX-License-Identifier: GPL-2.0
3 * Core driver for Wilco Embedded Controller
5 * Copyright 2018 Google LLC
7 * This is the entry point for the drivers that control the Wilco EC.
10 #include <linux/acpi.h>
11 #include <linux/device.h>
12 #include <linux/ioport.h>
13 #include <linux/module.h>
14 #include <linux/platform_data/wilco-ec.h>
15 #include <linux/platform_device.h>
17 #include "../cros_ec_lpc_mec.h"
19 #define DRV_NAME "wilco-ec"
21 static struct resource
*wilco_get_resource(struct platform_device
*pdev
,
24 struct device
*dev
= &pdev
->dev
;
27 res
= platform_get_resource(pdev
, IORESOURCE_IO
, index
);
29 dev_dbg(dev
, "Couldn't find IO resource %d\n", index
);
33 return devm_request_region(dev
, res
->start
, resource_size(res
),
37 static int wilco_ec_probe(struct platform_device
*pdev
)
39 struct device
*dev
= &pdev
->dev
;
40 struct wilco_ec_device
*ec
;
43 ec
= devm_kzalloc(dev
, sizeof(*ec
), GFP_KERNEL
);
47 platform_set_drvdata(pdev
, ec
);
49 mutex_init(&ec
->mailbox_lock
);
51 ec
->data_size
= sizeof(struct wilco_ec_response
) + EC_MAILBOX_DATA_SIZE
;
52 ec
->data_buffer
= devm_kzalloc(dev
, ec
->data_size
, GFP_KERNEL
);
56 /* Prepare access to IO regions provided by ACPI */
57 ec
->io_data
= wilco_get_resource(pdev
, 0); /* Host Data */
58 ec
->io_command
= wilco_get_resource(pdev
, 1); /* Host Command */
59 ec
->io_packet
= wilco_get_resource(pdev
, 2); /* MEC EMI */
60 if (!ec
->io_data
|| !ec
->io_command
|| !ec
->io_packet
)
63 /* Initialize cros_ec register interface for communication */
64 cros_ec_lpc_mec_init(ec
->io_packet
->start
,
65 ec
->io_packet
->start
+ EC_MAILBOX_DATA_SIZE
);
68 * Register a child device that will be found by the debugfs driver.
71 ec
->debugfs_pdev
= platform_device_register_data(dev
,
76 /* Register a child device that will be found by the RTC driver. */
77 ec
->rtc_pdev
= platform_device_register_data(dev
, "rtc-wilco-ec",
80 if (IS_ERR(ec
->rtc_pdev
)) {
81 dev_err(dev
, "Failed to create RTC platform device\n");
82 ret
= PTR_ERR(ec
->rtc_pdev
);
83 goto unregister_debugfs
;
86 /* Set up the keyboard backlight LEDs. */
87 ret
= wilco_keyboard_leds_init(ec
);
90 "Failed to initialize keyboard LEDs: %d\n",
95 ret
= wilco_ec_add_sysfs(ec
);
97 dev_err(dev
, "Failed to create sysfs entries: %d\n", ret
);
101 /* Register child device to be found by charger config driver. */
102 ec
->charger_pdev
= platform_device_register_data(dev
, "wilco-charger",
105 if (IS_ERR(ec
->charger_pdev
)) {
106 dev_err(dev
, "Failed to create charger platform device\n");
107 ret
= PTR_ERR(ec
->charger_pdev
);
111 /* Register child device that will be found by the telemetry driver. */
112 ec
->telem_pdev
= platform_device_register_data(dev
, "wilco_telem",
115 if (IS_ERR(ec
->telem_pdev
)) {
116 dev_err(dev
, "Failed to create telemetry platform device\n");
117 ret
= PTR_ERR(ec
->telem_pdev
);
118 goto unregister_charge_config
;
123 unregister_charge_config
:
124 platform_device_unregister(ec
->charger_pdev
);
126 wilco_ec_remove_sysfs(ec
);
128 platform_device_unregister(ec
->rtc_pdev
);
130 if (ec
->debugfs_pdev
)
131 platform_device_unregister(ec
->debugfs_pdev
);
132 cros_ec_lpc_mec_destroy();
136 static int wilco_ec_remove(struct platform_device
*pdev
)
138 struct wilco_ec_device
*ec
= platform_get_drvdata(pdev
);
140 platform_device_unregister(ec
->telem_pdev
);
141 platform_device_unregister(ec
->charger_pdev
);
142 wilco_ec_remove_sysfs(ec
);
143 platform_device_unregister(ec
->rtc_pdev
);
144 if (ec
->debugfs_pdev
)
145 platform_device_unregister(ec
->debugfs_pdev
);
147 /* Teardown cros_ec interface */
148 cros_ec_lpc_mec_destroy();
153 static const struct acpi_device_id wilco_ec_acpi_device_ids
[] = {
157 MODULE_DEVICE_TABLE(acpi
, wilco_ec_acpi_device_ids
);
159 static struct platform_driver wilco_ec_driver
= {
162 .acpi_match_table
= wilco_ec_acpi_device_ids
,
164 .probe
= wilco_ec_probe
,
165 .remove
= wilco_ec_remove
,
168 module_platform_driver(wilco_ec_driver
);
170 MODULE_AUTHOR("Nick Crews <ncrews@chromium.org>");
171 MODULE_AUTHOR("Duncan Laurie <dlaurie@chromium.org>");
172 MODULE_LICENSE("GPL v2");
173 MODULE_DESCRIPTION("ChromeOS Wilco Embedded Controller driver");
174 MODULE_ALIAS("platform:" DRV_NAME
);