From nobody Thu Dec 18 19:42:40 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EA1A0C77B7A for ; Sat, 20 May 2023 21:39:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229991AbjETVjC (ORCPT ); Sat, 20 May 2023 17:39:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50868 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229865AbjETVi5 (ORCPT ); Sat, 20 May 2023 17:38:57 -0400 Received: from mx.kolabnow.com (mx.kolabnow.com [212.103.80.154]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BDB9A18F; Sat, 20 May 2023 14:38:54 -0700 (PDT) Received: from localhost (unknown [127.0.0.1]) by mx.kolabnow.com (Postfix) with ESMTP id 4E342614; Sat, 20 May 2023 23:38:53 +0200 (CEST) Authentication-Results: ext-mx-out002.mykolab.com (amavisd-new); dkim=pass (4096-bit key) reason="pass (just generated, assumed good)" header.d=kolabnow.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolabnow.com; h= content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:date:subject:subject:from:from :received:received:received; s=dkim20160331; t=1684618730; x= 1686433131; bh=xUjD2Wp3SXV+MRyN28bv1RSgHTtU6BQiyYxEPdqA7JI=; b=5 /wTErVrZZXU38YWQyJlyX+GRU2cd0Q3d7d23qVM7BGVCarqYeii96KSZ6wyQmDN4 IQzWofpKdITw4VWLEGOCXYAdxgwzHKEfR6dkorbv8azLm7dpcOwKjNKJDKtAMsfY 1V6TeEzj94ERP/XAvQ2JcHxuQFwM6ZEU9jlnlEf81pfdt+CnZbpbkS3ELh/ryBTf uaJDvFwQBt4QIOLkOdyTC8oA3/5j9Z3ues4m4dQK6iyuUvJ9pdAnJrZDRrgqxsc5 aPpY9vwii0hBVvylMlnxPM+c1B3Vu08tn9BJ7JwgFfKQM9YpMjIxajVsVppBLYcT G3cK5DEnhNVaxE72sAFjWuAXAEEvApwhQe18m4YQUCfBXsxaMmyEekhudWSE8Z04 BklxPEVXDZjqwF2ijjZUtG7hsawE0dxbnVPDBhj0LxHwNwOctHxYsmgmSCRSdhW6 FCx4cMyeGdr+iNw7oLn2beJ88vt24b6fhJpK5DosFIHmMnyVO6KknwWL6em5UQIX efVjiDpTTlQt7Li3tErCQo5XY3B512rINd16JyFXUqdbJYki3d35xsxZhccQ/YbA 8XRCOnKXP5etbrO45/t31wUQ8oFEXY9ac79mavxi1mDIUfTqMEkd6HkguTwNo7Sj +PsLglPHXG7A11Qk6rcdNnERS1BmJD8g+1cMrYH/yc= X-Virus-Scanned: amavisd-new at mykolab.com Received: from mx.kolabnow.com ([127.0.0.1]) by localhost (ext-mx-out002.mykolab.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id azbFCaygKepa; Sat, 20 May 2023 23:38:50 +0200 (CEST) Received: from int-mx001.mykolab.com (unknown [10.9.13.1]) by mx.kolabnow.com (Postfix) with ESMTPS id F34BC5BA; Sat, 20 May 2023 23:38:49 +0200 (CEST) Received: from ext-subm002.mykolab.com (unknown [10.9.6.2]) by int-mx001.mykolab.com (Postfix) with ESMTPS id 4A340368; Sat, 20 May 2023 23:38:49 +0200 (CEST) From: alison@she-devel.com To: johan@kernel.org Cc: robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, alison@she-devel.com, achaiken@aurora.tech Subject: [PATCH v7 1/2] gnss: ubx: customize serial device open to set U-Blox Zed-F9P baud Date: Sat, 20 May 2023 14:38:34 -0700 Message-Id: <20230520213835.1932087-2-alison@she-devel.com> In-Reply-To: <20230520213835.1932087-1-alison@she-devel.com> References: <20230520213835.1932087-1-alison@she-devel.com> MIME-Version: 1.0 Organization: Aurora Innovation Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Alison Chaiken Add support for setting the baud rate of U-Blox Zed-F9P GNSS devices. Provide functions that support writing of arbitrary configuration messages to the device plus one that specifically configures the baud rate. Override the default gnss_serial_open() with a new method that writes the configuration message to the GNSS if the devicetree declares it to be a Zed F9P and requests a non-default baud. Add a boolean flag to the ubx_data private data of the GNSS driver in order to track whether the configuration message has already been written. Set the Zed F9P to its default port speed if the devicetree does not specify a value. Signed-off-by: Alison Chaiken --- V7 -> V6 Fixed version. V6 -> V5 Change #ifdef to _maybe_unused and fix warnings. V5 -> V4 Wrap all new code in a CONFIG_OF=3Dy check V4 -> V3 Lookup device-specific properties by matching driver data. V2 -> V3 Add email recipients whom I foolishly missed the first two times. V1 -> V2 Fixes error identified by kernel test robot: drivers/gnss/ubx.c | 243 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 232 insertions(+), 11 deletions(-) diff --git a/drivers/gnss/ubx.c b/drivers/gnss/ubx.c index c951be202ca2..e857733aabe9 100644 --- a/drivers/gnss/ubx.c +++ b/drivers/gnss/ubx.c @@ -9,18 +9,212 @@ #include #include #include +#include #include #include +#include +#include +#include #include #include =20 #include "serial.h" =20 +/* Total configuration message length =3D PREAMBLE_LEN + MESSAGE_CLASS_LEN= + + * MESSAGE_LENGTH_LEN + payload length + CHECKSUM_LEN + */ +const int32_t PREAMBLE_LEN =3D 2; +const int32_t MESSAGE_CLASS_LEN =3D 2; +const int32_t MESSAGE_LENGTH_LEN =3D 2; +const int32_t CHECKSUM_LEN =3D 2; +const size_t FIRST_CONFIG_REGISTER_BYTE =3D 10U; +const size_t FIRST_VALUE_BYTE =3D 14U; +const size_t FIRST_CHECKSUM_BYTE =3D 18U; +const size_t CFG_MSG_TOTAL_LEN =3D 20U; + +uint8_t ZED_F9P_CFG_VALSET_MSG[] =3D { + 0xB5, 0x62, /* 0-1 preamble */ + 0x06, 0x8A, /* 2-3 CFG_VALSET command */ + 0x0C, 0x00, /* 4-5 payload length =3D 12 for one key-value pair */ + 0x00, /* 6 U-Blox API version */ + 0x01, /* 7 Write to RAM */ + 0x00, 0x00, /* 8-9 Reserved */ + 0x00, 0x00, 0x00, 0x00, /* 10-13 Placeholder for configuration register */ + 0x00, 0x00, 0x00, 0x00, /* 14-17 Placeholder for baud value */ + 0x00, 0x00 /* 18-19 Placeholder for checksum */ +}; + +struct ubx_features { + u32 min_baud; + u32 default_baud; + u32 max_baud; + size_t baud_config_reg; + int (*open)(struct gnss_device *gdev); +}; + struct ubx_data { struct regulator *v_bckp; struct regulator *vcc; + const struct ubx_features *features; + unsigned long is_configured; }; =20 +union message_length { + uint16_t ml; + uint8_t bytes[2]; +}; + +union int_to_bytes { + uint32_t int_val; + uint8_t bytes[4]; +}; + +/* Payload length is contained in bytes 0-2 after message class and ID. + * While the checksum includes the Message class and ID plus message leng= th, the + * payload does not. + */ +static uint16_t get_payload_length(const uint8_t msg[]) +{ + union message_length hs_msg_len; + + hs_msg_len.bytes[0] =3D msg[PREAMBLE_LEN + MESSAGE_CLASS_LEN]; + hs_msg_len.bytes[1] =3D msg[PREAMBLE_LEN + MESSAGE_CLASS_LEN + 1U]; + return hs_msg_len.ml; +} + +static int32_t get_msg_total_len(const uint8_t msg[]) +{ + const size_t payload_len =3D get_payload_length(msg); + + return PREAMBLE_LEN + MESSAGE_CLASS_LEN + MESSAGE_LENGTH_LEN + payload_len + + CHECKSUM_LEN; +} + +/* The checksum is calculated on message class, message ID, message length= and + * payload. + */ +static void calc_ubx_checksum(const uint8_t msg[], uint8_t checksum[], + const uint16_t total_len) +{ + uint8_t CK_A =3D 0; + uint8_t CK_B =3D 0; + int i; + + for (i =3D PREAMBLE_LEN; i < (total_len - CHECKSUM_LEN); i++) { + CK_A +=3D msg[i]; + CK_B +=3D CK_A; + } + checksum[0] =3D CK_A; + checksum[1] =3D CK_B; +} + +static uint32_t check_baud(speed_t speed, const struct device *dev, + const struct ubx_features *features) +{ + if ((speed < features->min_baud) || (speed > features->max_baud)) { + dev_warn(dev, "Baud rate specification %d out of range\n", speed); + speed =3D features->default_baud; + } + return speed; +} + +static int prepare_zedf9p_config_msg(const speed_t speed, + const struct device *dev, + const struct ubx_features *features) +{ + union int_to_bytes cfg_val, cfg_register; + int i =3D 0; + uint8_t checksum[2]; + const size_t total_len =3D get_msg_total_len(ZED_F9P_CFG_VALSET_MSG); + + if (total_len !=3D CFG_MSG_TOTAL_LEN) + goto bad_msg; + + cfg_val.int_val =3D check_baud(speed, dev, features); + cfg_register.int_val =3D features->baud_config_reg; + for (i =3D 0; i < 4; i++) { + ZED_F9P_CFG_VALSET_MSG[FIRST_VALUE_BYTE + i] =3D cfg_val.bytes[i]; + ZED_F9P_CFG_VALSET_MSG[FIRST_CONFIG_REGISTER_BYTE + i] =3D cfg_register.= bytes[i]; + } + calc_ubx_checksum(ZED_F9P_CFG_VALSET_MSG, checksum, total_len); + ZED_F9P_CFG_VALSET_MSG[FIRST_CHECKSUM_BYTE] =3D checksum[0]; + ZED_F9P_CFG_VALSET_MSG[FIRST_CHECKSUM_BYTE + 1U] =3D checksum[1]; + return 0; + + bad_msg: + dev_err(dev, "Malformed UBX-CFG-VALSET message\n"); + return -EINVAL; +} + +/* Configure the Zed F9P baud rate via the UBX-CFG-VALSET message. */ +static int set_zedf9p_baud(struct gnss_device *gdev, + struct serdev_device *serdev, struct gnss_serial *gserial) +{ + const struct ubx_data *data =3D gnss_serial_get_drvdata(gserial); + const struct ubx_features *features =3D data->features; + size_t count =3D 0U; + int ret; + + if (!data->features) + return -EINVAL; + if (gserial->speed =3D=3D features->default_baud) + return 0; + + ret =3D prepare_zedf9p_config_msg(gserial->speed, &gdev->dev, features); + if (ret) + return ret; + /* Initially set the UART to the default speed to match the GNSS' power-o= n value. */ + serdev_device_set_baudrate(serdev, features->default_baud); + /* Now set the new baud rate. */ + count =3D gdev->ops->write_raw(gdev, ZED_F9P_CFG_VALSET_MSG, CFG_MSG_TOTA= L_LEN); + if (count !=3D CFG_MSG_TOTAL_LEN) + return count; + + return 0; +} + +static int zed_f9p_serial_open(struct gnss_device *gdev) +{ + struct gnss_serial *gserial =3D gnss_get_drvdata(gdev); + struct serdev_device *serdev =3D gserial->serdev; + struct ubx_data *data =3D gnss_serial_get_drvdata(gserial); + int ret; + + ret =3D serdev_device_open(serdev); + if (ret) + return ret; + if (!data->features) + return -EINVAL; + + serdev_device_set_flow_control(serdev, false); + + if (!data->is_configured) { + /* 4800 is the default value set by gnss_serial_parse_dt() */ + if (gserial->speed =3D=3D 4800) { + /* Fall back instead to Zed F9P default */ + gserial->speed =3D data->features->default_baud; + } else { + ret =3D set_zedf9p_baud(gdev, serdev, gserial); + if (ret) + return ret; + } + data->is_configured =3D 1; + } + serdev_device_set_baudrate(serdev, gserial->speed); + + ret =3D pm_runtime_get_sync(&serdev->dev); + if (ret < 0) { + pm_runtime_put_noidle(&serdev->dev); + goto err_close; + } + return 0; + +err_close: + serdev_device_close(serdev); + + return ret; +} + static int ubx_set_active(struct gnss_serial *gserial) { struct ubx_data *data =3D gnss_serial_get_drvdata(gserial); @@ -63,10 +257,31 @@ static const struct gnss_serial_ops ubx_gserial_ops = =3D { .set_power =3D ubx_set_power, }; =20 + +static const struct ubx_features __maybe_unused zedf9p_feats =3D { + .min_baud =3D 9600, + .default_baud =3D 38400, + .max_baud =3D 921600, + .baud_config_reg =3D 0x40520001, + .open =3D zed_f9p_serial_open, +}; + +#ifdef CONFIG_OF +static const struct of_device_id ubx_of_match[] =3D { + { .compatible =3D "u-blox,neo-6m" }, + { .compatible =3D "u-blox,neo-8" }, + { .compatible =3D "u-blox,neo-m8" }, + { .compatible =3D "u-blox,zed-f9p", .data =3D &zedf9p_feats }, + {}, +}; +MODULE_DEVICE_TABLE(of, ubx_of_match); +#endif + static int ubx_probe(struct serdev_device *serdev) { struct gnss_serial *gserial; struct ubx_data *data; + struct gnss_operations *ubx_gnss_ops; int ret; =20 gserial =3D gnss_serial_allocate(serdev, sizeof(*data)); @@ -74,13 +289,29 @@ static int ubx_probe(struct serdev_device *serdev) ret =3D PTR_ERR(gserial); return ret; } + ubx_gnss_ops =3D kzalloc(sizeof(struct gnss_operations), GFP_KERNEL); + if (IS_ERR(ubx_gnss_ops)) { + ret =3D PTR_ERR(ubx_gnss_ops); + return ret; + } =20 gserial->ops =3D &ubx_gserial_ops; =20 gserial->gdev->type =3D GNSS_TYPE_UBX; =20 data =3D gnss_serial_get_drvdata(gserial); - +#if IS_ENABLED(CONFIG_OF) + { + data->is_configured =3D 0; + data->features =3D of_match_device(ubx_of_match, &serdev->dev)->data; + if (data->features && data->features->open) { + ubx_gnss_ops->open =3D data->features->open; + ubx_gnss_ops->close =3D gserial->gdev->ops->close; + ubx_gnss_ops->write_raw =3D gserial->gdev->ops->write_raw; + gserial->gdev->ops =3D ubx_gnss_ops; + } + } +#endif data->vcc =3D devm_regulator_get(&serdev->dev, "vcc"); if (IS_ERR(data->vcc)) { ret =3D PTR_ERR(data->vcc); @@ -128,16 +359,6 @@ static void ubx_remove(struct serdev_device *serdev) gnss_serial_free(gserial); } =20 -#ifdef CONFIG_OF -static const struct of_device_id ubx_of_match[] =3D { - { .compatible =3D "u-blox,neo-6m" }, - { .compatible =3D "u-blox,neo-8" }, - { .compatible =3D "u-blox,neo-m8" }, - {}, -}; -MODULE_DEVICE_TABLE(of, ubx_of_match); -#endif - static struct serdev_device_driver ubx_driver =3D { .driver =3D { .name =3D "gnss-ubx", --=20 2.39.2 From nobody Thu Dec 18 19:42:40 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3A7B1C7EE2D for ; Sat, 20 May 2023 21:39:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229942AbjETVjA (ORCPT ); Sat, 20 May 2023 17:39:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50874 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229869AbjETVi5 (ORCPT ); Sat, 20 May 2023 17:38:57 -0400 Received: from mx.kolabnow.com (mx.kolabnow.com [212.103.80.153]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 95B9219F; Sat, 20 May 2023 14:38:56 -0700 (PDT) Received: from localhost (unknown [127.0.0.1]) by mx.kolabnow.com (Postfix) with ESMTP id 4783040315; Sat, 20 May 2023 23:38:55 +0200 (CEST) Authentication-Results: ext-mx-out003.mykolab.com (amavisd-new); dkim=pass (4096-bit key) reason="pass (just generated, assumed good)" header.d=kolabnow.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolabnow.com; h= content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:date:subject:subject:from:from :received:received:received; s=dkim20160331; t=1684618734; x= 1686433135; bh=uW/Pj1AFyhgRgOzjlpGQjJyF6cL/aUOxR6xtJ/BltvY=; b=3 VjIxle5pdQDefRZFR1AiIO9Nrrlqx7cb+uxMAo0BHZqbUjSSA8y1Kf+q+FpOv08+ XLjjZhYQu71w0skTIcnP97KdcQQjeRLMjMHYz9Byz8A6NTCl7tAos825RrItGzVe r+nZcukqzSNaXwwlpnlbRZ+0HUGcamQzVGzpGOmr/pNG7zJndw+wy1INeHOtJJpR 0ItFWn4fBby2fAobB8KWpz3wAs/Z/gPMsQ9w/d5fc12Sdfk6eRV7lHo8EuffmMb8 E+Qmr9tTNVuvGydr07qwAUqtkA5NvFvZP3Bb/riPtIqdUFQOonpmmWFCOh01/Qzw tUF+rjF7XIe46YjKowRRsRkg1nC0Tn+lpOaj0a/eRwa9UFNcMF89lZ5U8W6rX5fW 2B6GnRcSTe6OfuAtQqzTPZ7nFCuIkEy3jh35uCx5LZjjfBd5KlPzRTzcAJxFLGKS NRDSX2b4IPrv829+PojwlWCBTgRfNuMQwKHrzlWhXsMrwCmX7FWLj4MSpcXMdknb LHoXKTWVqdryG3Jl4PxVizutR6x4IFq6RunpkUXdhvuDZ3h+vmNtvjuQQ8Obbcuo xSgId1slatkXUwHy2frv74j3OH07pRmtsBC5iVpfyPpWeyjwKV2PGMf35VjEH1nE 3J+K0y54iMC1dWGYfC0mAiQntEqA/rlY9uCrbQSNe4= X-Virus-Scanned: amavisd-new at mykolab.com Received: from mx.kolabnow.com ([127.0.0.1]) by localhost (ext-mx-out003.mykolab.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gvzix2uiyLxp; Sat, 20 May 2023 23:38:54 +0200 (CEST) Received: from int-mx002.mykolab.com (unknown [10.9.13.2]) by mx.kolabnow.com (Postfix) with ESMTPS id BBA46400B4; Sat, 20 May 2023 23:38:54 +0200 (CEST) Received: from ext-subm002.mykolab.com (unknown [10.9.6.2]) by int-mx002.mykolab.com (Postfix) with ESMTPS id 3C3D52991; Sat, 20 May 2023 23:38:54 +0200 (CEST) From: alison@she-devel.com To: johan@kernel.org Cc: robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, alison@she-devel.com, achaiken@aurora.tech, Rob Herring Subject: [PATCH v7 2/2] dt-bindings: gnss: Add U-Blox Zed-F9 Date: Sat, 20 May 2023 14:38:35 -0700 Message-Id: <20230520213835.1932087-3-alison@she-devel.com> In-Reply-To: <20230520213835.1932087-1-alison@she-devel.com> References: <20230520213835.1932087-1-alison@she-devel.com> MIME-Version: 1.0 Organization: Aurora Innovation Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Alison Chaiken Add support for the U-Blox Zed-F9P GNSS device. Signed-off-by: Alison Chaiken Acked-by: Rob Herring --- V7 -> V6 Moved Acked-by tag and fixed version. Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml b/Do= cumentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml index 4835a280b3bf..86b65d4d9266 100644 --- a/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml +++ b/Documentation/devicetree/bindings/gnss/u-blox,neo-6m.yaml @@ -21,6 +21,7 @@ properties: - u-blox,neo-6m - u-blox,neo-8 - u-blox,neo-m8 + - u-blox,zed-f9p =20 reg: description: > --=20 2.39.2