diff --git a/MAINTAINERS b/MAINTAINERS index 5695690cbc13..5b7a13f706fa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4468,14 +4468,12 @@ F: drivers/input/touchscreen/chipone_icn8505.c CHROME HARDWARE PLATFORM SUPPORT M: Benson Leung -M: Enric Balletbo i Serra S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git F: drivers/platform/chrome/ CHROMEOS EC CODEC DRIVER M: Cheng-Yi Chiang -R: Enric Balletbo i Serra R: Guenter Roeck S: Maintained F: Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml @@ -4483,13 +4481,23 @@ F: sound/soc/codecs/cros_ec_codec.* CHROMEOS EC SUBDRIVERS M: Benson Leung -M: Enric Balletbo i Serra R: Guenter Roeck S: Maintained F: drivers/power/supply/cros_usbpd-charger.c N: cros_ec N: cros-ec +CHROMEOS EC USB TYPE-C DRIVER +M: Prashant Malani +S: Maintained +F: drivers/platform/chrome/cros_ec_typec.c + +CHROMEOS EC USB PD NOTIFY DRIVER +M: Prashant Malani +S: Maintained +F: drivers/platform/chrome/cros_usbpd_notify.c +F: include/linux/platform_data/cros_usbpd_notify.h + CHRONTEL CH7322 CEC DRIVER M: Joe Tessler L: linux-media@vger.kernel.org diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c index 28bde13003b7..b2725c6adc7f 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c @@ -831,8 +831,7 @@ EXPORT_SYMBOL_GPL(cros_ec_sensors_core_write); static int __maybe_unused cros_ec_sensors_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct iio_dev *indio_dev = dev_get_drvdata(dev); struct cros_ec_sensors_core_state *st = iio_priv(indio_dev); int ret = 0; diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 81cee1a5daa6..546feef851ab 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -146,8 +146,8 @@ static int ec_device_probe(struct platform_device *pdev) ec->ec_dev = dev_get_drvdata(dev->parent); ec->dev = dev; ec->cmd_offset = ec_platform->cmd_offset; - ec->features[0] = -1U; /* Not cached yet */ - ec->features[1] = -1U; /* Not cached yet */ + ec->features.flags[0] = -1U; /* Not cached yet */ + ec->features.flags[1] = -1U; /* Not cached yet */ device_initialize(&ec->class_dev); for (i = 0; i < ARRAY_SIZE(cros_mcu_devices); i++) { diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 1f7861944044..d6306d2a096f 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -156,7 +156,7 @@ static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec, cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_CMD, 1, &sum); if (ec_response_timed_out()) { - dev_warn(ec->dev, "EC responsed timed out\n"); + dev_warn(ec->dev, "EC response timed out\n"); ret = -EIO; goto done; } @@ -238,7 +238,7 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, cros_ec_lpc_ops.write(EC_LPC_ADDR_HOST_CMD, 1, &sum); if (ec_response_timed_out()) { - dev_warn(ec->dev, "EC responsed timed out\n"); + dev_warn(ec->dev, "EC response timed out\n"); ret = -EIO; goto done; } diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index a7404d69b2d3..c4caf2e2de82 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -808,38 +808,27 @@ EXPORT_SYMBOL(cros_ec_get_host_event); * * Call this function to test whether the ChromeOS EC supports a feature. * - * Return: 1 if supported, 0 if not + * Return: true if supported, false if not (or if an error was encountered). */ -int cros_ec_check_features(struct cros_ec_dev *ec, int feature) +bool cros_ec_check_features(struct cros_ec_dev *ec, int feature) { - struct cros_ec_command *msg; + struct ec_response_get_features *features = &ec->features; int ret; - if (ec->features[0] == -1U && ec->features[1] == -1U) { + if (features->flags[0] == -1U && features->flags[1] == -1U) { /* features bitmap not read yet */ - msg = kzalloc(sizeof(*msg) + sizeof(ec->features), GFP_KERNEL); - if (!msg) - return -ENOMEM; - - msg->command = EC_CMD_GET_FEATURES + ec->cmd_offset; - msg->insize = sizeof(ec->features); - - ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); + ret = cros_ec_command(ec->ec_dev, 0, EC_CMD_GET_FEATURES + ec->cmd_offset, + NULL, 0, features, sizeof(*features)); if (ret < 0) { - dev_warn(ec->dev, "cannot get EC features: %d/%d\n", - ret, msg->result); - memset(ec->features, 0, sizeof(ec->features)); - } else { - memcpy(ec->features, msg->data, sizeof(ec->features)); + dev_warn(ec->dev, "cannot get EC features: %d\n", ret); + memset(features, 0, sizeof(*features)); } dev_dbg(ec->dev, "EC features %08x %08x\n", - ec->features[0], ec->features[1]); - - kfree(msg); + features->flags[0], features->flags[1]); } - return ec->features[feature / 32] & EC_FEATURE_MASK_0(feature); + return !!(features->flags[feature / 32] & EC_FEATURE_MASK_0(feature)); } EXPORT_SYMBOL_GPL(cros_ec_check_features); @@ -908,3 +897,51 @@ int cros_ec_get_sensor_count(struct cros_ec_dev *ec) return sensor_count; } EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count); + +/** + * cros_ec_command - Send a command to the EC. + * + * @ec_dev: EC device + * @version: EC command version + * @command: EC command + * @outdata: EC command output data + * @outsize: Size of outdata + * @indata: EC command input data + * @insize: Size of indata + * + * Return: >= 0 on success, negative error number on failure. + */ +int cros_ec_command(struct cros_ec_device *ec_dev, + unsigned int version, + int command, + void *outdata, + int outsize, + void *indata, + int insize) +{ + struct cros_ec_command *msg; + int ret; + + msg = kzalloc(sizeof(*msg) + max(insize, outsize), GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->version = version; + msg->command = command; + msg->outsize = outsize; + msg->insize = insize; + + if (outsize) + memcpy(msg->data, outdata, outsize); + + ret = cros_ec_cmd_xfer_status(ec_dev, msg); + if (ret < 0) + goto error; + + if (insize) + memcpy(indata, msg->data, insize); +error: + kfree(msg); + return ret; +} +EXPORT_SYMBOL_GPL(cros_ec_command); diff --git a/drivers/platform/chrome/cros_ec_sensorhub.c b/drivers/platform/chrome/cros_ec_sensorhub.c index 9c4af76a9956..31fb8bdaad5a 100644 --- a/drivers/platform/chrome/cros_ec_sensorhub.c +++ b/drivers/platform/chrome/cros_ec_sensorhub.c @@ -224,8 +224,7 @@ static int cros_ec_sensorhub_probe(struct platform_device *pdev) */ static int cros_ec_sensorhub_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct cros_ec_sensorhub *sensorhub = platform_get_drvdata(pdev); + struct cros_ec_sensorhub *sensorhub = dev_get_drvdata(dev); struct cros_ec_dev *ec = sensorhub->ec; if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) @@ -235,8 +234,7 @@ static int cros_ec_sensorhub_suspend(struct device *dev) static int cros_ec_sensorhub_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct cros_ec_sensorhub *sensorhub = platform_get_drvdata(pdev); + struct cros_ec_sensorhub *sensorhub = dev_get_drvdata(dev); struct cros_ec_dev *ec = sensorhub->ec; if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 262a891eded3..5de0bfb0bc4d 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -379,37 +379,6 @@ unregister_ports: return ret; } -static int cros_typec_ec_command(struct cros_typec_data *typec, - unsigned int version, - unsigned int command, - void *outdata, - unsigned int outsize, - void *indata, - unsigned int insize) -{ - struct cros_ec_command *msg; - int ret; - - msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL); - if (!msg) - return -ENOMEM; - - msg->version = version; - msg->command = command; - msg->outsize = outsize; - msg->insize = insize; - - if (outsize) - memcpy(msg->data, outdata, outsize); - - ret = cros_ec_cmd_xfer_status(typec->ec, msg); - if (ret >= 0 && insize) - memcpy(indata, msg->data, insize); - - kfree(msg); - return ret; -} - static int cros_typec_usb_safe_state(struct cros_typec_port *port) { port->state.mode = TYPEC_STATE_SAFE; @@ -596,8 +565,8 @@ mux_ack: /* Sending Acknowledgment to EC */ mux_ack.port = port_num; - if (cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_MUX_ACK, &mux_ack, - sizeof(mux_ack), NULL, 0) < 0) + if (cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_MUX_ACK, &mux_ack, + sizeof(mux_ack), NULL, 0) < 0) dev_warn(typec->dev, "Failed to send Mux ACK to EC for port: %d\n", port_num); @@ -668,8 +637,8 @@ static int cros_typec_get_mux_info(struct cros_typec_data *typec, int port_num, .port = port_num, }; - return cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_MUX_INFO, &req, - sizeof(req), resp, sizeof(*resp)); + return cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_MUX_INFO, &req, + sizeof(req), resp, sizeof(*resp)); } /* @@ -776,8 +745,8 @@ static int cros_typec_handle_sop_prime_disc(struct cros_typec_data *typec, int p int ret = 0; memset(disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE); - ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req), - disc, EC_PROTO2_MAX_RESPONSE_SIZE); + ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req), + disc, EC_PROTO2_MAX_RESPONSE_SIZE); if (ret < 0) { dev_err(typec->dev, "Failed to get SOP' discovery data for port: %d\n", port_num); goto sop_prime_disc_exit; @@ -859,8 +828,8 @@ static int cros_typec_handle_sop_disc(struct cros_typec_data *typec, int port_nu typec_partner_set_pd_revision(port->partner, pd_revision); memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE); - ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req), - sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE); + ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req), + sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE); if (ret < 0) { dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num); goto disc_exit; @@ -892,8 +861,8 @@ static int cros_typec_send_clear_event(struct cros_typec_data *typec, int port_n .clear_events_mask = events_mask, }; - return cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_CONTROL, &req, - sizeof(req), NULL, 0); + return cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_CONTROL, &req, + sizeof(req), NULL, 0); } static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num) @@ -904,8 +873,8 @@ static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num }; int ret; - ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req), - &resp, sizeof(resp)); + ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req), + &resp, sizeof(resp)); if (ret < 0) { dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num); return; @@ -983,9 +952,9 @@ static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) req.mux = USB_PD_CTRL_MUX_NO_CHANGE; req.swap = USB_PD_CTRL_SWAP_NONE; - ret = cros_typec_ec_command(typec, typec->pd_ctrl_ver, - EC_CMD_USB_PD_CONTROL, &req, sizeof(req), - &resp, sizeof(resp)); + ret = cros_ec_command(typec->ec, typec->pd_ctrl_ver, + EC_CMD_USB_PD_CONTROL, &req, sizeof(req), + &resp, sizeof(resp)); if (ret < 0) return ret; @@ -1035,8 +1004,8 @@ static int cros_typec_get_cmd_version(struct cros_typec_data *typec) /* We're interested in the PD control command version. */ req_v1.cmd = EC_CMD_USB_PD_CONTROL; - ret = cros_typec_ec_command(typec, 1, EC_CMD_GET_CMD_VERSIONS, - &req_v1, sizeof(req_v1), &resp, + ret = cros_ec_command(typec->ec, 1, EC_CMD_GET_CMD_VERSIONS, + &req_v1, sizeof(req_v1), &resp, sizeof(resp)); if (ret < 0) return ret; @@ -1116,12 +1085,11 @@ static int cros_typec_probe(struct platform_device *pdev) } ec_dev = dev_get_drvdata(&typec->ec->ec->dev); - typec->typec_cmd_supported = !!cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_CMD); - typec->needs_mux_ack = !!cros_ec_check_features(ec_dev, - EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK); + typec->typec_cmd_supported = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_CMD); + typec->needs_mux_ack = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK); - ret = cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_PORTS, NULL, 0, - &resp, sizeof(resp)); + ret = cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_PORTS, NULL, 0, + &resp, sizeof(resp)); if (ret < 0) return ret; diff --git a/drivers/platform/chrome/cros_usbpd_notify.c b/drivers/platform/chrome/cros_usbpd_notify.c index 48a6617aa12f..91ce6be91aac 100644 --- a/drivers/platform/chrome/cros_usbpd_notify.c +++ b/drivers/platform/chrome/cros_usbpd_notify.c @@ -53,50 +53,6 @@ void cros_usbpd_unregister_notify(struct notifier_block *nb) } EXPORT_SYMBOL_GPL(cros_usbpd_unregister_notify); -/** - * cros_ec_pd_command - Send a command to the EC. - * - * @ec_dev: EC device - * @command: EC command - * @outdata: EC command output data - * @outsize: Size of outdata - * @indata: EC command input data - * @insize: Size of indata - * - * Return: >= 0 on success, negative error number on failure. - */ -static int cros_ec_pd_command(struct cros_ec_device *ec_dev, - int command, - uint8_t *outdata, - int outsize, - uint8_t *indata, - int insize) -{ - struct cros_ec_command *msg; - int ret; - - msg = kzalloc(sizeof(*msg) + max(insize, outsize), GFP_KERNEL); - if (!msg) - return -ENOMEM; - - msg->command = command; - msg->outsize = outsize; - msg->insize = insize; - - if (outsize) - memcpy(msg->data, outdata, outsize); - - ret = cros_ec_cmd_xfer_status(ec_dev, msg); - if (ret < 0) - goto error; - - if (insize) - memcpy(indata, msg->data, insize); -error: - kfree(msg); - return ret; -} - static void cros_usbpd_get_event_and_notify(struct device *dev, struct cros_ec_device *ec_dev) { @@ -115,10 +71,8 @@ static void cros_usbpd_get_event_and_notify(struct device *dev, } /* Check for PD host events on EC. */ - ret = cros_ec_pd_command(ec_dev, EC_CMD_PD_HOST_EVENT_STATUS, - NULL, 0, - (uint8_t *)&host_event_status, - sizeof(host_event_status)); + ret = cros_ec_command(ec_dev, 0, EC_CMD_PD_HOST_EVENT_STATUS, + NULL, 0, &host_event_status, sizeof(host_event_status)); if (ret < 0) { dev_warn(dev, "Can't get host event status (err: %d)\n", ret); goto send_notify; diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h index 02599687770c..df3c78c92ca2 100644 --- a/include/linux/platform_data/cros_ec_proto.h +++ b/include/linux/platform_data/cros_ec_proto.h @@ -205,7 +205,7 @@ struct cros_ec_dev { struct cros_ec_debugfs *debug_info; bool has_kb_wake_angle; u16 cmd_offset; - u32 features[2]; + struct ec_response_get_features features; }; #define to_cros_ec_dev(dev) container_of(dev, struct cros_ec_dev, class_dev) @@ -227,10 +227,13 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); -int cros_ec_check_features(struct cros_ec_dev *ec, int feature); +bool cros_ec_check_features(struct cros_ec_dev *ec, int feature); int cros_ec_get_sensor_count(struct cros_ec_dev *ec); +int cros_ec_command(struct cros_ec_device *ec_dev, unsigned int version, int command, void *outdata, + int outsize, void *indata, int insize); + /** * cros_ec_get_time_ns() - Return time in ns. *