Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp3837975ybg; Sun, 20 Oct 2019 22:55:54 -0700 (PDT) X-Google-Smtp-Source: APXvYqxKBwcZaJUD+SloeRqGZ25pUWOxUiy9Q2Lghzm5BLHH1y7zRlGCU7SkyupB2AJ8uuSDYXyV X-Received: by 2002:a17:906:d8c3:: with SMTP id re3mr20373859ejb.167.1571637353946; Sun, 20 Oct 2019 22:55:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571637353; cv=none; d=google.com; s=arc-20160816; b=XCDUNleqUI/Er+P+ksph6IE4TJ+c+7RbOhcZCIY5WKcCUtVHic6Na9+MAJdlm2h41s C7f35x3I1tBFrbWoOTctj//mtPZunOzuj77/vqpd0jWKI2bKY6V0tHFdEDCPiwog5kew uufCHBFCD0G0BEwvoRuTG2gDqwJfhagWCDCtW3K5Vy4Yg9vZ0Sv9sa14A6aKUYHlHfMs XBeNHdb50lP0XGtAn4INYEMp2jYT0R3NYTlKJqpVDSMItoIRNwv0I48OEJdKPg9k1KKs 2HLhvcWtfs300xJssOcnqZl7byqM0xpXc2AoIaASo7HaAXTdiXtRVNn7vfeWAu+ItrJP saBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=/S7uG+di49uMPvOgcSRYYqyni8kI/2um7+75z2ze7EY=; b=VDjGUJrPLnBLLWzmQsLCZ16WTgYAkHCrngZRjhvw/ljIAy//Db6ZP5iS+WAbo2TFNG 04Kl1pdmV8SnJ7WR8zSwXAQVQqaDwDhP7c2mf/tVnlzoSRtYGP6MXHQ6VY+hG/QGkrBs BCBd9+Hi4YEcnoRojUsb9E1ZwQPKUi64xYOgF4n3X8ufhlOJYSOxO1hk3MdBBJH6JwrY 55SO49HXtAdhE2khikllMuzgOVFeOboUQmZaxHsiNySmZNUa7sEz95SJwTp2152ox6EF SIxU5vUvnUeSQGUrWjeY4rHScGWN7CLycfj0/yTxV5HEdJHt6U0OaRKRQvcDom7TPbAu o2zg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=VS1NUdeE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n8si8425869eju.311.2019.10.20.22.55.30; Sun, 20 Oct 2019 22:55:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=VS1NUdeE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727410AbfJUFy4 (ORCPT + 99 others); Mon, 21 Oct 2019 01:54:56 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:40348 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727307AbfJUFyg (ORCPT ); Mon, 21 Oct 2019 01:54:36 -0400 Received: by mail-pl1-f196.google.com with SMTP id d22so6072676pll.7 for ; Sun, 20 Oct 2019 22:54:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/S7uG+di49uMPvOgcSRYYqyni8kI/2um7+75z2ze7EY=; b=VS1NUdeE1rjAVyLQedmXw05r3lRRUCT5pHH1J7iDxWLMne7iBSdK/zBrGc5//H/twr bVpOkj7/cCsufgvaRwrkdBt/I6RWubQvBWxLhA8+yT9zm3DRSw5FKwCIqfWkpQ6VxECx 12K97LOZO3VuQ5jFdiB8GcsidtZH+LKe+oEiw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/S7uG+di49uMPvOgcSRYYqyni8kI/2um7+75z2ze7EY=; b=jeJOS5sU570D8joKzvPMzrTXxc0gopAmU1MobCGIM2RpCCRQT2UgEr3V4MOxtqWbY5 bySMF6L7vGgXUXBzQDcXWtNZOplHH2HcLiSlcXc2YZoDBB+Q5RmP8oqm8zGow5LTr+Rt 8SFuzlqJ2ZAW+6AbjW/MsR+6q+p+H9K7WZpJKsSBGcn1t3qUbaHf89MtMJdbMC7f/yXO PhPsZCmElzCPYdG66fX4P+SS6DA69BnO2gtimhwrsI2/pBUQK7yk5cElDmMBXjIQ+4gW iC/kCCRJ1IHiU/jzu9aqzJwPXlWxV/yYJJZ/DW9+5X5CcJ06eC4mr8lJ3Dz6lI60rYew PS+g== X-Gm-Message-State: APjAAAXeXxDtaEutQdixMsYEq08wm2E5mgUfrcn+HD36I+d42P+5yJKq w8G7jiCdK/NNWzm63ImBvsGojQ== X-Received: by 2002:a17:902:9308:: with SMTP id bc8mr22485990plb.178.1571637274014; Sun, 20 Oct 2019 22:54:34 -0700 (PDT) Received: from localhost ([2620:15c:202:1:3c8f:512b:3522:dfaf]) by smtp.gmail.com with ESMTPSA id u7sm14322508pfn.61.2019.10.20.22.54.33 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 20 Oct 2019 22:54:33 -0700 (PDT) From: Gwendal Grignou To: briannorris@chromium.org, jic23@kernel.org, knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net, lee.jones@linaro.org, bleung@chromium.org, enric.balletbo@collabora.com, dianders@chromium.org, groeck@chromium.org, fabien.lahoudere@collabora.com Cc: linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, Gwendal Grignou Subject: [PATCH v2 14/18] iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO Date: Sun, 20 Oct 2019 22:53:59 -0700 Message-Id: <20191021055403.67849-15-gwendal@chromium.org> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog In-Reply-To: <20191021055403.67849-1-gwendal@chromium.org> References: <20191021055403.67849-1-gwendal@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When EC supports FIFO, each IIO device registers a callback, to put samples in the buffer when they arrives from the FIFO. We can still use a trigger to collect samples, but there may be some duplications in the buffer: EC has a single FIFO, so once one sensor is using it, all sensors event will be in the FIFO. To be sure events generated by cros_ec_sensorhub or the trigger uses the same time domain, current_timestamp_clock must be set to "boottime". When no FIFO, the user space app needs to call trigger_new, or better register a high precision timer. Signed-off-by: Gwendal Grignou --- Change in v2 from "Use triggered buffer only when EC does not support FIFO": - Keep trigger all the time. - Add devm_add_action to cleanup callback registration. - EC that "reports" legacy sensors do not have FIFO. - Use iiio_is_buffer_enabled instead of checking the scan_mask before sending samples to buffer. - Add empty lines for visibility. drivers/iio/accel/cros_ec_accel_legacy.c | 8 +- .../cros_ec_sensors/cros_ec_lid_angle.c | 2 +- .../common/cros_ec_sensors/cros_ec_sensors.c | 8 +- .../cros_ec_sensors/cros_ec_sensors_core.c | 80 ++++++++++++++++++- drivers/iio/light/cros_ec_light_prox.c | 8 +- drivers/iio/pressure/cros_ec_baro.c | 8 +- .../linux/iio/common/cros_ec_sensors_core.h | 12 ++- 7 files changed, 96 insertions(+), 30 deletions(-) diff --git a/drivers/iio/accel/cros_ec_accel_legacy.c b/drivers/iio/accel/cros_ec_accel_legacy.c index 65f85faf6f31d..66683df9fc433 100644 --- a/drivers/iio/accel/cros_ec_accel_legacy.c +++ b/drivers/iio/accel/cros_ec_accel_legacy.c @@ -171,7 +171,8 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev) if (!indio_dev) return -ENOMEM; - ret = cros_ec_sensors_core_init(pdev, indio_dev, true); + ret = cros_ec_sensors_core_init(pdev, indio_dev, true, + cros_ec_sensors_capture, NULL); if (ret) return ret; @@ -191,11 +192,6 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev) state->sign[CROS_EC_SENSOR_Z] = -1; } - ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, - cros_ec_sensors_capture, NULL); - if (ret) - return ret; - return devm_iio_device_register(dev, indio_dev); } diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c index 1dcc2a16ab2dd..e30a59fcf0f95 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c @@ -97,7 +97,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev) if (!indio_dev) return -ENOMEM; - ret = cros_ec_sensors_core_init(pdev, indio_dev, false); + ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL); if (ret) return ret; diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c index 7dce044734678..9e7903ff99f80 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c @@ -231,7 +231,8 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) if (!indio_dev) return -ENOMEM; - ret = cros_ec_sensors_core_init(pdev, indio_dev, true); + ret = cros_ec_sensors_core_init(pdev, indio_dev, true, + cros_ec_sensors_capture, cros_ec_sensors_push_data); if (ret) return ret; @@ -293,11 +294,6 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) else state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; - ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, - cros_ec_sensors_capture, NULL); - if (ret) - return ret; - return devm_iio_device_register(dev, indio_dev); } 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 4acb8b7310d43..3d2e17093c75a 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 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -83,17 +84,72 @@ static void get_default_min_max_freq(enum motionsensor_type type, } } +int cros_ec_sensors_push_data( + struct iio_dev *indio_dev, + s16 *data, + s64 timestamp) +{ + struct cros_ec_sensors_core_state *st = iio_priv(indio_dev); + s16 *out; + unsigned int i; + + /* + * It can happen if we get a samples before the iio device is fully + * registered. + */ + if (!st) + return 0; + + /* + * Ignore samples if the buffer is not set: it is needed if the ODR is + * set but the buffer is not enabled yet. + */ + if (!iio_buffer_enabled(indio_dev)) + return 0; + + out = (s16 *)st->samples; + for_each_set_bit(i, + indio_dev->active_scan_mask, + indio_dev->masklength) { + *out = data[i]; + out++; + } + + iio_push_to_buffers_with_timestamp(indio_dev, st->samples, timestamp); + + return 0; +} +EXPORT_SYMBOL_GPL(cros_ec_sensors_push_data); + +static void cros_ec_sensors_core_clean(void *arg) +{ + struct platform_device *pdev = (struct platform_device *)arg; + struct cros_ec_sensorhub *sensor_hub = + dev_get_drvdata(pdev->dev.parent); + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct cros_ec_sensors_core_state *st = iio_priv(indio_dev); + u8 sensor_num = st->param.info.sensor_num; + + cros_ec_sensorhub_unregister_push_data(sensor_hub, sensor_num); +} + /** * cros_ec_sensors_core_init() - basic initialization of the core structure * @pdev: platform device created for the sensors * @indio_dev: iio device structure of the device * @physical_device: true if the device refers to a physical device + * @trigger_capture: function pointer to call buffer is triggered, + * for backward compatibility. + * @push_data: function to call when cros_ec_sensorhub receives + * a sample for that sensor. * * Return: 0 on success, -errno on failure. */ int cros_ec_sensors_core_init(struct platform_device *pdev, struct iio_dev *indio_dev, - bool physical_device) + bool physical_device, + cros_ec_sensors_capture_t trigger_capture, + cros_ec_sensorhub_push_data_cb_t push_data) { struct device *dev = &pdev->dev; struct cros_ec_sensors_core_state *state = iio_priv(indio_dev); @@ -132,8 +188,6 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, indio_dev->name = pdev->name; if (physical_device) { - indio_dev->modes = INDIO_DIRECT_MODE; - state->param.cmd = MOTIONSENSE_CMD_INFO; state->param.info.sensor_num = sensor_platform->sensor_num; ret = cros_ec_motion_send_host_cmd(state, 0); @@ -162,9 +216,27 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, state->frequencies[2] = state->resp->info_3.max_frequency; } + + ret = devm_iio_triggered_buffer_setup( + dev, indio_dev, NULL, + trigger_capture, NULL); + if (ret) + return ret; + + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { + ret = cros_ec_sensorhub_register_push_data( + sensor_hub, + sensor_platform->sensor_num, + indio_dev, push_data); + if (ret) + return ret; + + ret = devm_add_action_or_reset( + dev, cros_ec_sensors_core_clean, pdev); + } } - return 0; + return ret; } EXPORT_SYMBOL_GPL(cros_ec_sensors_core_init); diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c index d85a391e50c59..da40c38370965 100644 --- a/drivers/iio/light/cros_ec_light_prox.c +++ b/drivers/iio/light/cros_ec_light_prox.c @@ -178,7 +178,8 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) if (!indio_dev) return -ENOMEM; - ret = cros_ec_sensors_core_init(pdev, indio_dev, true); + ret = cros_ec_sensors_core_init(pdev, indio_dev, true, + cros_ec_sensors_capture, cros_ec_sensors_push_data); if (ret) return ret; @@ -237,11 +238,6 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; - ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, - cros_ec_sensors_capture, NULL); - if (ret) - return ret; - return devm_iio_device_register(dev, indio_dev); } diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c index 2354302375dee..fb7daeb4b29f9 100644 --- a/drivers/iio/pressure/cros_ec_baro.c +++ b/drivers/iio/pressure/cros_ec_baro.c @@ -134,7 +134,8 @@ static int cros_ec_baro_probe(struct platform_device *pdev) if (!indio_dev) return -ENOMEM; - ret = cros_ec_sensors_core_init(pdev, indio_dev, true); + ret = cros_ec_sensors_core_init(pdev, indio_dev, true, + cros_ec_sensors_capture, cros_ec_sensors_push_data); if (ret) return ret; @@ -180,11 +181,6 @@ static int cros_ec_baro_probe(struct platform_device *pdev) state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; - ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, - cros_ec_sensors_capture, NULL); - if (ret) - return ret; - return devm_iio_device_register(dev, indio_dev); } diff --git a/include/linux/iio/common/cros_ec_sensors_core.h b/include/linux/iio/common/cros_ec_sensors_core.h index 0af918978f975..b4eb3790cde11 100644 --- a/include/linux/iio/common/cros_ec_sensors_core.h +++ b/include/linux/iio/common/cros_ec_sensors_core.h @@ -12,6 +12,7 @@ #include #include #include +#include enum { CROS_EC_SENSOR_X, @@ -32,6 +33,9 @@ enum { /* Minimum sampling period to use when device is suspending */ #define CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY 1000 /* 1 second */ +typedef irqreturn_t (*cros_ec_sensors_capture_t)(int irq, void *p); + + /** * struct cros_ec_sensors_core_state - state data for EC sensors IIO driver * @ec: cros EC device structure @@ -87,9 +91,15 @@ int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask, struct platform_device; int cros_ec_sensors_core_init(struct platform_device *pdev, - struct iio_dev *indio_dev, bool physical_device); + struct iio_dev *indio_dev, bool physical_device, + cros_ec_sensors_capture_t trigger_capture, + cros_ec_sensorhub_push_data_cb_t push_data); irqreturn_t cros_ec_sensors_capture(int irq, void *p); +int cros_ec_sensors_push_data( + struct iio_dev *indio_dev, + s16 *data, + s64 timestamp); int cros_ec_motion_send_host_cmd(struct cros_ec_sensors_core_state *st, u16 opt_length); -- 2.23.0.866.gb869b98d4c-goog