Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp5967164imu; Tue, 13 Nov 2018 14:50:34 -0800 (PST) X-Google-Smtp-Source: AJdET5f/HtmVbbS707K96f8I4hZfSJzKoYwpre1AAxnFZ1AqP6LgCWbhZOaVs8mhR8Fa5yAzPpU9 X-Received: by 2002:a62:a48:: with SMTP id s69mr7364125pfi.136.1542149434896; Tue, 13 Nov 2018 14:50:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542149434; cv=none; d=google.com; s=arc-20160816; b=f9JbA9UbYlUSl3U4CsiUV27OFDUKrJSY2VT4e2ZGJ/r8FRymQfkUU4tYnD19NvECB1 BCIl5BMax1wCfGmo0/fI9eSXrCFlSHxfpvd9+DIS0XQARId7uc3l7Q1HPZLpRur7SRx5 yDdk/fKsBPSAS9b/HZk9wg2AXLPfXlXjRPZQi8VWbmzdLCKC1y4OKYY67WKsNY+Qvcga byInu9ZMOfD23yEakm1nECrQ6XrPm3KRlsqM2bO+vaBsZSMyG+2GkWo1xnOToG9qCQUf s4A+r/11K7MC7m5YcSxEW5oeRDu28BGWVYt93ioc9zgN365tZwMigad7o11ZDotGaYF0 /6qA== 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 :content-language:in-reply-to:mime-version:user-agent:date :message-id:references:cc:to:subject:from; bh=hT/S8RpthexNE7NmrQCmdFMck5sxmIsgUIJu63zc/LA=; b=xjWzfTit+t8Tqq9tLT7K6JQIkfJ6rMxfP5t+0E9UGBbO0LYVTYIi+rNnYNKNA/eP7d T7XzMZjie1sPNtJZqVCxWPqJaUTrs7NwX5cQl2ILcI5KH0MysvyFZF8dDd0G2gQOc/XC Cc2Rl+kzbRS+D1s1OKcmMmgTNIjz6YvFQNOUSISD74XSMPJCE/D8sxWZdJq6vPvTlzMH 4GT39yB2XJZ6WelVP9vG9aRoT79th15EZxO6ZNtQzlrM+FlKbdoYxdgF4dMD+KJoUan4 WGWKnGAfyFuqvilC2OkEvXEvvoAOhM4rX4bdVhlsoGKyynhMcK5nTbCasK7f4s8GBj1a glxg== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u69si3083116pfj.219.2018.11.13.14.50.19; Tue, 13 Nov 2018 14:50:34 -0800 (PST) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731381AbeKNIuS convert rfc822-to-8bit (ORCPT + 99 others); Wed, 14 Nov 2018 03:50:18 -0500 Received: from srv-hp10-72.netsons.net ([94.141.22.72]:53637 "EHLO srv-hp10-72.netsons.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726022AbeKNIuS (ORCPT ); Wed, 14 Nov 2018 03:50:18 -0500 Received: from [5.157.104.112] (port=36772 helo=[192.168.77.57]) by srv-hp10.netsons.net with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.91) (envelope-from ) id 1gMhVH-005nwa-Ea; Tue, 13 Nov 2018 23:49:51 +0100 From: Luca Ceresoli Subject: Re: [PATCH v4 3/4] media: i2c: Add MAX9286 driver To: Kieran Bingham , linux-renesas-soc@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, sakari.ailus@iki.fi Cc: =?UTF-8?Q?Niklas_S=c3=b6derlund?= , Jacopo Mondi , Laurent Pinchart , Kieran Bingham , linux-kernel@vger.kernel.org, Jacopo Mondi , Laurent Pinchart , =?UTF-8?Q?Niklas_S=c3=b6derlund?= References: <20181102154723.23662-1-kieran.bingham@ideasonboard.com> <20181102154723.23662-4-kieran.bingham@ideasonboard.com> Message-ID: <5238fa80-7678-97a8-47ee-6a26970d862d@lucaceresoli.net> Date: Tue, 13 Nov 2018 23:49:53 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: <20181102154723.23662-4-kieran.bingham@ideasonboard.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8BIT X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - srv-hp10.netsons.net X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - lucaceresoli.net X-Get-Message-Sender-Via: srv-hp10.netsons.net: authenticated_id: luca+lucaceresoli.net/only user confirmed/virtual account not confirmed X-Authenticated-Sender: srv-hp10.netsons.net: luca@lucaceresoli.net X-Source: X-Source-Args: X-Source-Dir: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Kieran, All, below a few minor questions, and a big one at the bottom. On 02/11/18 16:47, Kieran Bingham wrote: > From: Kieran Bingham > > The MAX9286 is a 4-channel GMSL deserializer with coax or STP input and > CSI-2 output. The device supports multicamera streaming applications, > and features the ability to synchronise the attached cameras. > > CSI-2 output can be configured with 1 to 4 lanes, and a control channel > is supported over I2C, which implements an I2C mux to facilitate > communications with connected cameras across the reverse control > channel. > > Signed-off-by: Jacopo Mondi > Signed-off-by: Kieran Bingham > Signed-off-by: Laurent Pinchart > Signed-off-by: Niklas Söderlund [...] > +struct max9286_device { > + struct i2c_client *client; > + struct v4l2_subdev sd; > + struct media_pad pads[MAX9286_N_PADS]; > + struct regulator *regulator; > + bool poc_enabled; > + int streaming; > + > + struct i2c_mux_core *mux; > + unsigned int mux_channel; > + > + struct v4l2_ctrl_handler ctrls; > + > + struct v4l2_mbus_framefmt fmt[MAX9286_N_SINKS]; 5 pads, 4 formats. Why does the source node have no fmt? > +static int max9286_init(struct device *dev, void *data) > +{ > + struct max9286_device *max9286; > + struct i2c_client *client; > + struct device_node *ep; > + unsigned int i; > + int ret; > + > + /* Skip non-max9286 devices. */ > + if (!dev->of_node || !of_match_node(max9286_dt_ids, dev->of_node)) > + return 0; > + > + client = to_i2c_client(dev); > + max9286 = i2c_get_clientdata(client); > + > + /* Enable the bus power. */ > + ret = regulator_enable(max9286->regulator); > + if (ret < 0) { > + dev_err(&client->dev, "Unable to turn PoC on\n"); > + return ret; > + } > + > + max9286->poc_enabled = true; > + > + ret = max9286_setup(max9286); > + if (ret) { > + dev_err(dev, "Unable to setup max9286\n"); > + goto err_regulator; > + } > + > + v4l2_i2c_subdev_init(&max9286->sd, client, &max9286_subdev_ops); > + max9286->sd.internal_ops = &max9286_subdev_internal_ops; > + max9286->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; ^ This way you're clearing the V4L2_SUBDEV_FL_IS_I2C set by v4l2_i2c_subdev_init(), even though using devicetree I think this won't matter in the current kernel code. However I think "max9286->sd.flags |= ..." is more correct here, and it's also what most other drivers do. > + v4l2_ctrl_handler_init(&max9286->ctrls, 1); > + /* > + * FIXME: Compute the real pixel rate. The 50 MP/s value comes from the > + * hardcoded frequency in the BSP CSI-2 receiver driver. > + */ > + v4l2_ctrl_new_std(&max9286->ctrls, NULL, V4L2_CID_PIXEL_RATE, > + 50000000, 50000000, 1, 50000000); > + max9286->sd.ctrl_handler = &max9286->ctrls; > + ret = max9286->ctrls.error; > + if (ret) > + goto err_regulator; > + > + max9286->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; According to the docs MEDIA_ENT_F_VID_IF_BRIDGE appears more fitting. > +static int max9286_probe(struct i2c_client *client, > + const struct i2c_device_id *did) > +{ > + struct max9286_device *dev; > + unsigned int i; > + int ret; > + > + dev = kzalloc(sizeof(*dev), GFP_KERNEL); > + if (!dev) > + return -ENOMEM; > + > + dev->client = client; > + i2c_set_clientdata(client, dev); > + > + for (i = 0; i < MAX9286_N_SINKS; i++) > + max9286_init_format(&dev->fmt[i]); > + > + ret = max9286_parse_dt(dev); > + if (ret) > + return ret; > + > + dev->regulator = regulator_get(&client->dev, "poc"); > + if (IS_ERR(dev->regulator)) { > + if (PTR_ERR(dev->regulator) != -EPROBE_DEFER) > + dev_err(&client->dev, > + "Unable to get PoC regulator (%ld)\n", > + PTR_ERR(dev->regulator)); > + ret = PTR_ERR(dev->regulator); > + goto err_free; > + } > + > + /* > + * We can have multiple MAX9286 instances on the same physical I2C > + * bus, and I2C children behind ports of separate MAX9286 instances > + * having the same I2C address. As the MAX9286 starts by default with > + * all ports enabled, we need to disable all ports on all MAX9286 > + * instances before proceeding to further initialize the devices and > + * instantiate children. > + * > + * Start by just disabling all channels on the current device. Then, > + * if all other MAX9286 on the parent bus have been probed, proceed > + * to initialize them all, including the current one. > + */ > + max9286_i2c_mux_close(dev); > + > + /* > + * The MAX9286 initialises with auto-acknowledge enabled by default. > + * This means that if multiple MAX9286 devices are connected to an I2C > + * bus, another MAX9286 could ack I2C transfers meant for a device on > + * the other side of the GMSL links for this MAX9286 (such as a > + * MAX9271). To prevent that disable auto-acknowledge early on; it > + * will be enabled later as needed. > + */ > + max9286_configure_i2c(dev, false); > + > + ret = device_for_each_child(client->dev.parent, &client->dev, > + max9286_is_bound); > + if (ret) > + return 0; > + > + dev_dbg(&client->dev, > + "All max9286 probed: start initialization sequence\n"); > + ret = device_for_each_child(client->dev.parent, NULL, > + max9286_init); I can't manage to like this initialization sequence, sorry. If at all possible, each max9286 should initialize itself independently from each other, like any normal driver. First, it requires that each chip on the remote side can configure its own slave address. Not all chips do. Second, using a static i2c address map does not scale well and limits hotplugging, as I discussed in my reply to patch 1/4. The problem should be solvable cleanly if the MAX9286 supports address translation like the TI chips. Thanks, -- Luca