1 // SPDX-License-Identifier: GPL-2.0+
3 * CEC driver for ChromeOS Embedded Controller
5 * Copyright (c) 2018 BayLibre, SAS
6 * Author: Neil Armstrong <narmstrong@baylibre.com>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/platform_device.h>
13 #include <linux/dmi.h>
14 #include <linux/pci.h>
15 #include <linux/cec.h>
16 #include <linux/slab.h>
17 #include <linux/interrupt.h>
18 #include <linux/platform_data/cros_ec_commands.h>
19 #include <linux/platform_data/cros_ec_proto.h>
20 #include <media/cec.h>
21 #include <media/cec-notifier.h>
23 #define DRV_NAME "cros-ec-cec"
26 * struct cros_ec_cec_port - Driver data for a single EC CEC port
28 * @port_num: port number
30 * @notify: CEC notifier pointer
31 * @rx_msg: storage for a received message
32 * @cros_ec_cec: pointer to the parent struct
34 struct cros_ec_cec_port
{
36 struct cec_adapter
*adap
;
37 struct cec_notifier
*notify
;
38 struct cec_msg rx_msg
;
39 struct cros_ec_cec
*cros_ec_cec
;
43 * struct cros_ec_cec - Driver data for EC CEC
45 * @cros_ec: Pointer to EC device
46 * @notifier: Notifier info for responding to EC events
47 * @write_cmd_version: Highest supported version of EC_CMD_CEC_WRITE_MSG.
48 * @num_ports: Number of CEC ports
49 * @ports: Array of ports
52 struct cros_ec_device
*cros_ec
;
53 struct notifier_block notifier
;
54 int write_cmd_version
;
56 struct cros_ec_cec_port
*ports
[EC_CEC_MAX_PORTS
];
59 static void cros_ec_cec_received_message(struct cros_ec_cec_port
*port
,
60 uint8_t *msg
, uint8_t len
)
62 if (len
> CEC_MAX_MSG_SIZE
)
63 len
= CEC_MAX_MSG_SIZE
;
65 port
->rx_msg
.len
= len
;
66 memcpy(port
->rx_msg
.msg
, msg
, len
);
68 cec_received_msg(port
->adap
, &port
->rx_msg
);
71 static void handle_cec_message(struct cros_ec_cec
*cros_ec_cec
)
73 struct cros_ec_device
*cros_ec
= cros_ec_cec
->cros_ec
;
74 uint8_t *cec_message
= cros_ec
->event_data
.data
.cec_message
;
75 unsigned int len
= cros_ec
->event_size
;
76 struct cros_ec_cec_port
*port
;
78 * There are two ways of receiving CEC messages:
79 * 1. Old EC firmware which only supports one port sends the data in a
80 * cec_message MKBP event.
81 * 2. New EC firmware which supports multiple ports uses
82 * EC_MKBP_CEC_HAVE_DATA to notify that data is ready and
83 * EC_CMD_CEC_READ_MSG to read it.
84 * Check that the EC only has one CEC port, and then we can assume the
85 * message is from port 0.
87 if (cros_ec_cec
->num_ports
!= 1) {
89 "received cec_message on device with %d ports\n",
90 cros_ec_cec
->num_ports
);
93 port
= cros_ec_cec
->ports
[0];
95 cros_ec_cec_received_message(port
, cec_message
, len
);
98 static void cros_ec_cec_read_message(struct cros_ec_cec_port
*port
)
100 struct cros_ec_device
*cros_ec
= port
->cros_ec_cec
->cros_ec
;
101 struct ec_params_cec_read params
= {
102 .port
= port
->port_num
,
104 struct ec_response_cec_read response
;
107 ret
= cros_ec_cmd(cros_ec
, 0, EC_CMD_CEC_READ_MSG
, ¶ms
,
108 sizeof(params
), &response
, sizeof(response
));
110 dev_err(cros_ec
->dev
,
111 "error reading CEC message on EC: %d\n", ret
);
115 cros_ec_cec_received_message(port
, response
.msg
, response
.msg_len
);
118 static void handle_cec_event(struct cros_ec_cec
*cros_ec_cec
)
120 struct cros_ec_device
*cros_ec
= cros_ec_cec
->cros_ec
;
121 uint32_t cec_events
= cros_ec
->event_data
.data
.cec_events
;
122 uint32_t port_num
= EC_MKBP_EVENT_CEC_GET_PORT(cec_events
);
123 uint32_t events
= EC_MKBP_EVENT_CEC_GET_EVENTS(cec_events
);
124 struct cros_ec_cec_port
*port
;
126 if (port_num
>= cros_ec_cec
->num_ports
) {
127 dev_err(cros_ec
->dev
,
128 "received CEC event for invalid port %d\n", port_num
);
131 port
= cros_ec_cec
->ports
[port_num
];
133 if (events
& EC_MKBP_CEC_SEND_OK
)
134 cec_transmit_attempt_done(port
->adap
, CEC_TX_STATUS_OK
);
136 /* FW takes care of all retries, tell core to avoid more retries */
137 if (events
& EC_MKBP_CEC_SEND_FAILED
)
138 cec_transmit_attempt_done(port
->adap
,
139 CEC_TX_STATUS_MAX_RETRIES
|
142 if (events
& EC_MKBP_CEC_HAVE_DATA
)
143 cros_ec_cec_read_message(port
);
146 static int cros_ec_cec_event(struct notifier_block
*nb
,
147 unsigned long queued_during_suspend
,
150 struct cros_ec_cec
*cros_ec_cec
;
151 struct cros_ec_device
*cros_ec
;
153 cros_ec_cec
= container_of(nb
, struct cros_ec_cec
, notifier
);
154 cros_ec
= cros_ec_cec
->cros_ec
;
156 if (cros_ec
->event_data
.event_type
== EC_MKBP_EVENT_CEC_EVENT
) {
157 handle_cec_event(cros_ec_cec
);
161 if (cros_ec
->event_data
.event_type
== EC_MKBP_EVENT_CEC_MESSAGE
) {
162 handle_cec_message(cros_ec_cec
);
169 static int cros_ec_cec_set_log_addr(struct cec_adapter
*adap
, u8 logical_addr
)
171 struct cros_ec_cec_port
*port
= adap
->priv
;
172 struct cros_ec_cec
*cros_ec_cec
= port
->cros_ec_cec
;
173 struct cros_ec_device
*cros_ec
= cros_ec_cec
->cros_ec
;
174 struct ec_params_cec_set params
= {
175 .cmd
= CEC_CMD_LOGICAL_ADDRESS
,
176 .port
= port
->port_num
,
181 ret
= cros_ec_cmd(cros_ec
, 0, EC_CMD_CEC_SET
, ¶ms
, sizeof(params
),
184 dev_err(cros_ec
->dev
,
185 "error setting CEC logical address on EC: %d\n", ret
);
192 static int cros_ec_cec_transmit(struct cec_adapter
*adap
, u8 attempts
,
193 u32 signal_free_time
, struct cec_msg
*cec_msg
)
195 struct cros_ec_cec_port
*port
= adap
->priv
;
196 struct cros_ec_cec
*cros_ec_cec
= port
->cros_ec_cec
;
197 struct cros_ec_device
*cros_ec
= cros_ec_cec
->cros_ec
;
198 struct ec_params_cec_write params
;
199 struct ec_params_cec_write_v1 params_v1
;
202 if (cros_ec_cec
->write_cmd_version
== 0) {
203 memcpy(params
.msg
, cec_msg
->msg
, cec_msg
->len
);
204 ret
= cros_ec_cmd(cros_ec
, 0, EC_CMD_CEC_WRITE_MSG
, ¶ms
,
205 cec_msg
->len
, NULL
, 0);
207 params_v1
.port
= port
->port_num
;
208 params_v1
.msg_len
= cec_msg
->len
;
209 memcpy(params_v1
.msg
, cec_msg
->msg
, cec_msg
->len
);
210 ret
= cros_ec_cmd(cros_ec
, cros_ec_cec
->write_cmd_version
,
211 EC_CMD_CEC_WRITE_MSG
, ¶ms_v1
,
212 sizeof(params_v1
), NULL
, 0);
216 dev_err(cros_ec
->dev
,
217 "error writing CEC msg on EC: %d\n", ret
);
224 static int cros_ec_cec_adap_enable(struct cec_adapter
*adap
, bool enable
)
226 struct cros_ec_cec_port
*port
= adap
->priv
;
227 struct cros_ec_cec
*cros_ec_cec
= port
->cros_ec_cec
;
228 struct cros_ec_device
*cros_ec
= cros_ec_cec
->cros_ec
;
229 struct ec_params_cec_set params
= {
230 .cmd
= CEC_CMD_ENABLE
,
231 .port
= port
->port_num
,
236 ret
= cros_ec_cmd(cros_ec
, 0, EC_CMD_CEC_SET
, ¶ms
, sizeof(params
),
239 dev_err(cros_ec
->dev
,
240 "error %sabling CEC on EC: %d\n",
241 (enable
? "en" : "dis"), ret
);
248 static const struct cec_adap_ops cros_ec_cec_ops
= {
249 .adap_enable
= cros_ec_cec_adap_enable
,
250 .adap_log_addr
= cros_ec_cec_set_log_addr
,
251 .adap_transmit
= cros_ec_cec_transmit
,
254 #ifdef CONFIG_PM_SLEEP
255 static int cros_ec_cec_suspend(struct device
*dev
)
257 struct platform_device
*pdev
= to_platform_device(dev
);
258 struct cros_ec_cec
*cros_ec_cec
= dev_get_drvdata(&pdev
->dev
);
260 if (device_may_wakeup(dev
))
261 enable_irq_wake(cros_ec_cec
->cros_ec
->irq
);
266 static int cros_ec_cec_resume(struct device
*dev
)
268 struct platform_device
*pdev
= to_platform_device(dev
);
269 struct cros_ec_cec
*cros_ec_cec
= dev_get_drvdata(&pdev
->dev
);
271 if (device_may_wakeup(dev
))
272 disable_irq_wake(cros_ec_cec
->cros_ec
->irq
);
278 static SIMPLE_DEV_PM_OPS(cros_ec_cec_pm_ops
,
279 cros_ec_cec_suspend
, cros_ec_cec_resume
);
281 #if IS_ENABLED(CONFIG_PCI) && IS_ENABLED(CONFIG_DMI)
284 * Specify the DRM device name handling the HDMI output and the HDMI connector
285 * corresponding to each CEC port. The order of connectors must match the order
286 * in the EC (first connector is EC port 0, ...), and the number of connectors
287 * must match the number of ports in the EC (which can be queried using the
288 * EC_CMD_CEC_PORT_COUNT host command).
291 struct cec_dmi_match
{
292 const char *sys_vendor
;
293 const char *product_name
;
295 const char *const *conns
;
298 static const char *const port_b_conns
[] = { "Port B", NULL
};
299 static const char *const port_db_conns
[] = { "Port D", "Port B", NULL
};
300 static const char *const port_ba_conns
[] = { "Port B", "Port A", NULL
};
301 static const char *const port_d_conns
[] = { "Port D", NULL
};
303 static const struct cec_dmi_match cec_dmi_match_table
[] = {
305 { "Google", "Fizz", "0000:00:02.0", port_b_conns
},
307 { "Google", "Brask", "0000:00:02.0", port_b_conns
},
309 { "Google", "Moli", "0000:00:02.0", port_b_conns
},
311 { "Google", "Kinox", "0000:00:02.0", port_b_conns
},
313 { "Google", "Kuldax", "0000:00:02.0", port_b_conns
},
315 { "Google", "Aurash", "0000:00:02.0", port_b_conns
},
317 { "Google", "Gladios", "0000:00:02.0", port_b_conns
},
319 { "Google", "Lisbon", "0000:00:02.0", port_b_conns
},
321 { "Google", "Dibbi", "0000:00:02.0", port_db_conns
},
322 /* Google Constitution */
323 { "Google", "Constitution", "0000:00:02.0", port_ba_conns
},
325 { "Google", "Boxy", "0000:00:02.0", port_d_conns
},
327 { "Google", "Taranza", "0000:00:02.0", port_db_conns
},
329 { "Google", "Dexi", "0000:00:02.0", port_db_conns
},
331 { "Google", "Dita", "0000:00:02.0", port_db_conns
},
334 static struct device
*cros_ec_cec_find_hdmi_dev(struct device
*dev
,
335 const char * const **conns
)
339 for (i
= 0 ; i
< ARRAY_SIZE(cec_dmi_match_table
) ; ++i
) {
340 const struct cec_dmi_match
*m
= &cec_dmi_match_table
[i
];
342 if (dmi_match(DMI_SYS_VENDOR
, m
->sys_vendor
) &&
343 dmi_match(DMI_PRODUCT_NAME
, m
->product_name
)) {
346 /* Find the device, bail out if not yet registered */
347 d
= bus_find_device_by_name(&pci_bus_type
, NULL
,
350 return ERR_PTR(-EPROBE_DEFER
);
357 /* Hardware support must be added in the cec_dmi_match_table */
358 dev_warn(dev
, "CEC notifier not configured for this hardware\n");
360 return ERR_PTR(-ENODEV
);
365 static struct device
*cros_ec_cec_find_hdmi_dev(struct device
*dev
,
366 const char * const **conns
)
368 return ERR_PTR(-ENODEV
);
373 static int cros_ec_cec_get_num_ports(struct cros_ec_cec
*cros_ec_cec
)
375 struct ec_response_cec_port_count response
;
378 ret
= cros_ec_cmd(cros_ec_cec
->cros_ec
, 0, EC_CMD_CEC_PORT_COUNT
, NULL
,
379 0, &response
, sizeof(response
));
382 * Old EC firmware only supports one port and does not support
383 * the port count command, so fall back to assuming one port.
385 cros_ec_cec
->num_ports
= 1;
389 if (response
.port_count
== 0) {
390 dev_err(cros_ec_cec
->cros_ec
->dev
,
391 "EC reports 0 CEC ports\n");
395 if (response
.port_count
> EC_CEC_MAX_PORTS
) {
396 dev_err(cros_ec_cec
->cros_ec
->dev
,
397 "EC reports too many ports: %d\n", response
.port_count
);
401 cros_ec_cec
->num_ports
= response
.port_count
;
405 static int cros_ec_cec_get_write_cmd_version(struct cros_ec_cec
*cros_ec_cec
)
407 struct cros_ec_device
*cros_ec
= cros_ec_cec
->cros_ec
;
408 struct ec_params_get_cmd_versions_v1 params
= {
409 .cmd
= EC_CMD_CEC_WRITE_MSG
,
411 struct ec_response_get_cmd_versions response
;
414 ret
= cros_ec_cmd(cros_ec
, 1, EC_CMD_GET_CMD_VERSIONS
, ¶ms
,
415 sizeof(params
), &response
, sizeof(response
));
417 dev_err(cros_ec
->dev
,
418 "error getting CEC write command version: %d\n", ret
);
422 if (response
.version_mask
& EC_VER_MASK(1)) {
423 cros_ec_cec
->write_cmd_version
= 1;
425 if (cros_ec_cec
->num_ports
!= 1) {
426 dev_err(cros_ec
->dev
,
427 "v0 write command only supports 1 port, %d reported\n",
428 cros_ec_cec
->num_ports
);
431 cros_ec_cec
->write_cmd_version
= 0;
437 static int cros_ec_cec_init_port(struct device
*dev
,
438 struct cros_ec_cec
*cros_ec_cec
,
439 int port_num
, struct device
*hdmi_dev
,
440 const char * const *conns
)
442 struct cros_ec_cec_port
*port
;
445 port
= devm_kzalloc(dev
, sizeof(*port
), GFP_KERNEL
);
449 port
->cros_ec_cec
= cros_ec_cec
;
450 port
->port_num
= port_num
;
452 port
->adap
= cec_allocate_adapter(&cros_ec_cec_ops
, port
, DRV_NAME
,
454 CEC_CAP_CONNECTOR_INFO
, 1);
455 if (IS_ERR(port
->adap
))
456 return PTR_ERR(port
->adap
);
458 if (!conns
[port_num
]) {
459 dev_err(dev
, "no conn for port %d\n", port_num
);
461 goto out_probe_adapter
;
464 port
->notify
= cec_notifier_cec_adap_register(hdmi_dev
, conns
[port_num
],
468 goto out_probe_adapter
;
471 ret
= cec_register_adapter(port
->adap
, dev
);
473 goto out_probe_notify
;
475 cros_ec_cec
->ports
[port_num
] = port
;
480 cec_notifier_cec_adap_unregister(port
->notify
, port
->adap
);
482 cec_delete_adapter(port
->adap
);
486 static int cros_ec_cec_probe(struct platform_device
*pdev
)
488 struct cros_ec_dev
*ec_dev
= dev_get_drvdata(pdev
->dev
.parent
);
489 struct cros_ec_device
*cros_ec
= ec_dev
->ec_dev
;
490 struct cros_ec_cec
*cros_ec_cec
;
491 struct cros_ec_cec_port
*port
;
492 struct device
*hdmi_dev
;
493 const char * const *conns
= NULL
;
496 hdmi_dev
= cros_ec_cec_find_hdmi_dev(&pdev
->dev
, &conns
);
497 if (IS_ERR(hdmi_dev
))
498 return PTR_ERR(hdmi_dev
);
500 cros_ec_cec
= devm_kzalloc(&pdev
->dev
, sizeof(*cros_ec_cec
),
505 platform_set_drvdata(pdev
, cros_ec_cec
);
506 cros_ec_cec
->cros_ec
= cros_ec
;
508 device_init_wakeup(&pdev
->dev
, 1);
510 ret
= cros_ec_cec_get_num_ports(cros_ec_cec
);
514 ret
= cros_ec_cec_get_write_cmd_version(cros_ec_cec
);
518 for (int i
= 0; i
< cros_ec_cec
->num_ports
; i
++) {
519 ret
= cros_ec_cec_init_port(&pdev
->dev
, cros_ec_cec
, i
,
522 goto unregister_ports
;
525 /* Get CEC events from the EC. */
526 cros_ec_cec
->notifier
.notifier_call
= cros_ec_cec_event
;
527 ret
= blocking_notifier_chain_register(&cros_ec
->event_notifier
,
528 &cros_ec_cec
->notifier
);
530 dev_err(&pdev
->dev
, "failed to register notifier\n");
531 goto unregister_ports
;
538 * Unregister any adapters which have been registered. We don't add the
539 * port to the array until the adapter has been registered successfully,
540 * so any non-NULL ports must have been registered.
542 for (int i
= 0; i
< cros_ec_cec
->num_ports
; i
++) {
543 port
= cros_ec_cec
->ports
[i
];
546 cec_notifier_cec_adap_unregister(port
->notify
, port
->adap
);
547 cec_unregister_adapter(port
->adap
);
552 static void cros_ec_cec_remove(struct platform_device
*pdev
)
554 struct cros_ec_cec
*cros_ec_cec
= platform_get_drvdata(pdev
);
555 struct device
*dev
= &pdev
->dev
;
556 struct cros_ec_cec_port
*port
;
560 * blocking_notifier_chain_unregister() only fails if the notifier isn't
561 * in the list. We know it was added to it by .probe(), so there should
562 * be no need for error checking. Be cautious and still check.
564 ret
= blocking_notifier_chain_unregister(
565 &cros_ec_cec
->cros_ec
->event_notifier
,
566 &cros_ec_cec
->notifier
);
568 dev_err(dev
, "failed to unregister notifier\n");
570 for (int i
= 0; i
< cros_ec_cec
->num_ports
; i
++) {
571 port
= cros_ec_cec
->ports
[i
];
572 cec_notifier_cec_adap_unregister(port
->notify
, port
->adap
);
573 cec_unregister_adapter(port
->adap
);
577 static const struct platform_device_id cros_ec_cec_id
[] = {
581 MODULE_DEVICE_TABLE(platform
, cros_ec_cec_id
);
583 static struct platform_driver cros_ec_cec_driver
= {
584 .probe
= cros_ec_cec_probe
,
585 .remove
= cros_ec_cec_remove
,
588 .pm
= &cros_ec_cec_pm_ops
,
590 .id_table
= cros_ec_cec_id
,
593 module_platform_driver(cros_ec_cec_driver
);
595 MODULE_DESCRIPTION("CEC driver for ChromeOS ECs");
596 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
597 MODULE_LICENSE("GPL");