Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp755764pxb; Mon, 16 Aug 2021 17:21:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwCaVR4pF9lZPpTMrH2qTNefg9bHJRRC9DmOi7X3R3/L2mmAOAhNc8fkT3MMOLeKSBrR5JM X-Received: by 2002:a5d:8784:: with SMTP id f4mr738274ion.48.1629159706424; Mon, 16 Aug 2021 17:21:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629159706; cv=none; d=google.com; s=arc-20160816; b=N/R9kiWAqranOQDIisuy/isxfGt3hb+poA+ZaGd5n3XE2SubYJGzv0318qokZIr10P zI7CH+tpVOh1ieTaKQv9++Wbety1zDoJ0Sh5982vDSU++cOHAsdFy45YnT0ysPv8NPDa aJxKnF45JhAMj1Rlm57ZkkrDpFW7UcXI4ayB7wHF846l5hhL8BKa8RIX7QpMFfA7Yv5H fDytVq363GSun8h3j3vVovxNt07LuN253Ql8NOIdzugzDHEcg6HcHN4Iht7m3s+SGBaa 9w1jWo6ZT4+YAHUYhxVkpMFr5xePlVagvZM/crEoK3LADzNLIHTAJXVHSc2yoZkpp13Y TZNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version; bh=EeSSxZWCjTCKnIGHCtg9XhHy/XSSxUFCkMov+L5HlGg=; b=WKvDe841r/hW7bNDYS33tp7OBcRd/5HSyDqFTvRGaunhDkDydUwOXs5rQRmUNHNn3c pdqwBmgXoXAsdgs4pGtUf5JCdZ+pBMCkJCyqscK58sQD45H/asSX3yZr0qLiADYB1Y2L bf+U48zkidfvqC2kBwPV4mvvCupNZIEMMxFkmO41gkrxp2qW6GhIYLcqgqT3HCxYeR7s D0RCNXm6u69mxYVNKCaQogzfBGjjwyu8n4KgTK7DYcy1Lowp2J0EQYDSlMWlyoDj3NLw fWEVamuPGKBkHMOdrCZwWlYmC9Arll1PKcU9IOzLs+rqs4BtLCjzIRW0DdCDWFCA5tTp Nqnw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q17si436952ilj.42.2021.08.16.17.21.34; Mon, 16 Aug 2021 17:21:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234976AbhHQAUk (ORCPT + 99 others); Mon, 16 Aug 2021 20:20:40 -0400 Received: from mail-lf1-f42.google.com ([209.85.167.42]:47095 "EHLO mail-lf1-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232993AbhHQAUj (ORCPT ); Mon, 16 Aug 2021 20:20:39 -0400 Received: by mail-lf1-f42.google.com with SMTP id u22so6752441lfq.13; Mon, 16 Aug 2021 17:20:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=EeSSxZWCjTCKnIGHCtg9XhHy/XSSxUFCkMov+L5HlGg=; b=Btl8ELxQZACi5EV4gfV7Y4ZvnUZ9lIyHYzCLqIQ7LUeKpqSgA5Xf4dtk/y5X3Z3htI /t09I4YNTuXjHLPdblIjRW8CkNFQ4xhYgF3LrLiLcJJulr1WN54TKiHRwWwzBjlBsa8O dPdYwtjGhTvpSNyA71nSSbqSKubKrwz01IWZQoZX7wmUdoW3Xfwq4MwEqZcgYyU/0DHq zb0tMdeZPJsGkWTCfKVp9NXhhnVn43pnAONSizlulJ9m8IBLpglymIZ27NoHOcB0MgPx o0/NXw1/zKwi+wP7VPu/u3Zd/NfV0hSAdiZM24nIjYVfEu9HHan5a+35lEh0RwLDTVsn S65g== X-Gm-Message-State: AOAM530Y74egIHx7kV36YqI7Kr3lwp0mRi4MOalQeRglwIQiOmJKfn5g GKlKp6ePsxJNRWQt4KyoGIO0LhlvvRrQt99RNK4= X-Received: by 2002:a19:c112:: with SMTP id r18mr287174lff.531.1629159605630; Mon, 16 Aug 2021 17:20:05 -0700 (PDT) MIME-Version: 1.0 References: <20210816114840.17502-1-o.rempel@pengutronix.de> <20210816114840.17502-3-o.rempel@pengutronix.de> In-Reply-To: <20210816114840.17502-3-o.rempel@pengutronix.de> From: Vincent MAILHOL Date: Tue, 17 Aug 2021 09:19:54 +0900 Message-ID: Subject: Re: [PATCH v1 3/3] can: dev: provide optional GPIO based termination support To: Oleksij Rempel Cc: Wolfgang Grandegger , Marc Kleine-Budde , "David S. Miller" , Jakub Kicinski , Rob Herring , linux-can , netdev , devicetree@vger.kernel.org, open list , kernel@pengutronix.de, David Jander Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon. 16 Aug 2021 at 20:48, Oleksij Rempel wrote: > For CAN buses to work, a termination resistor has to be present at both > ends of the bus. This resistor is usually 120 Ohms, other values may be > required for special bus topologies. > > This patch adds support for a generic GPIO based CAN termination. The > resistor value has to be specified via device tree, and it can only be > attached to or detached from the bus. By default the termination is not > active. > > Signed-off-by: Oleksij Rempel > --- > drivers/net/can/dev/dev.c | 54 +++++++++++++++++++++++++++++++++++++++ > include/linux/can/dev.h | 7 +++++ > 2 files changed, 61 insertions(+) > > diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c > index 311d8564d611..b4a6c7a6fc18 100644 > --- a/drivers/net/can/dev/dev.c > +++ b/drivers/net/can/dev/dev.c > @@ -15,6 +15,7 @@ > #include > #include > #include > +#include > #include > > #define MOD_DESC "CAN device driver interface" > @@ -400,10 +401,57 @@ void close_candev(struct net_device *dev) > } > EXPORT_SYMBOL_GPL(close_candev); > > +static int can_set_termination(struct net_device *ndev, u16 term) > +{ > + struct can_priv *priv = netdev_priv(ndev); > + int set; > + > + if (term == priv->termination_gpio_ohms[CAN_TERMINATION_GPIO_ENABLED]) > + set = 1; > + else > + set = 0; > + > + gpiod_set_value(priv->termination_gpio, set); > + > + return 0; > +} > + > +static int can_get_termination(struct net_device *ndev) > +{ > + struct can_priv *priv = netdev_priv(ndev); > + struct device *dev = ndev->dev.parent; > + struct gpio_desc *gpio; > + u16 term; > + int ret; > + > + /* Disabling termination by default is the safe choice: Else if many > + * bus participants enable it, no communication is possible at all. > + */ > + gpio = devm_gpiod_get_optional(dev, "termination", GPIOD_OUT_LOW); > + if (IS_ERR(gpio)) > + return dev_err_probe(dev, PTR_ERR(gpio), > + "Cannot get termination-gpios\n"); > + > + ret = device_property_read_u16(dev, "termination-ohms", &term); > + if (ret) > + return ret; > + > + priv->termination_const_cnt = ARRAY_SIZE(priv->termination_gpio_ohms); > + priv->termination_const = priv->termination_gpio_ohms; > + priv->termination_gpio = gpio; > + priv->termination_gpio_ohms[CAN_TERMINATION_GPIO_DISABLED] = > + CAN_TERMINATION_DISABLED; > + priv->termination_gpio_ohms[CAN_TERMINATION_GPIO_ENABLED] = term; > + priv->do_set_termination = can_set_termination; > + > + return 0; > +} > + > /* Register the CAN network device */ > int register_candev(struct net_device *dev) > { > struct can_priv *priv = netdev_priv(dev); > + int err; > > /* Ensure termination_const, termination_const_cnt and > * do_set_termination consistency. All must be either set or > @@ -419,6 +467,12 @@ int register_candev(struct net_device *dev) > if (!priv->data_bitrate_const != !priv->data_bitrate_const_cnt) > return -EINVAL; > > + if (!priv->termination_const) { > + err = can_get_termination(dev); > + if (err) > + return err; > + } > + > dev->rtnl_link_ops = &can_link_ops; > netif_carrier_off(dev); > > diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h > index 27b275e463da..82bdc5b09a3a 100644 > --- a/include/linux/can/dev.h > +++ b/include/linux/can/dev.h > @@ -32,6 +32,11 @@ enum can_mode { > CAN_MODE_SLEEP > }; > > +enum can_termination_gpio { > + CAN_TERMINATION_GPIO_DISABLED = 0, > + CAN_TERMINATION_GPIO_ENABLED, I would add a last entry to automatically calculate the length of the termination_gpio_ohms array. + CAN_TERMINATION_GPIO_MAX > +}; > + > /* > * CAN common private data > */ > @@ -55,6 +60,8 @@ struct can_priv { > unsigned int termination_const_cnt; > const u16 *termination_const; > u16 termination; > + struct gpio_desc *termination_gpio; > + u16 termination_gpio_ohms[2]; This way, you can replace the constant value 2: + u16 termination_gpio_ohms[CAN_TERMINATION_GPIO_MAX]; > > enum can_state state; Yours sincerely, Vincent