Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp350636pxf; Thu, 11 Mar 2021 05:34:27 -0800 (PST) X-Google-Smtp-Source: ABdhPJyzado3J6IJ3BTqsu46RuEn92fHULcU5KsIASvfSQdYNustKLEr0NyREc29w/nwsxuQpmVZ X-Received: by 2002:aa7:d954:: with SMTP id l20mr8476697eds.1.1615469666810; Thu, 11 Mar 2021 05:34:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615469666; cv=none; d=google.com; s=arc-20160816; b=tquq//95QmDXJXlIjS1yOfTa7PkX+Poyqmph2qkYOSnpz1FWSgO38NPFEqFZoCBhj3 F/M2OWCS1i3iPF86WXd13iTYDaLihOaZmNuo10u7Egj3+fYLoi+RJwVo2LH5CEjiGcWN 2LJ+UZZRBU/smo43fMeXx+bQY7x/Zd9Evzp/oAOPPdM+CKN32t8z1r8rSAiGcbedYQNG P1d7S37mPorKpsWVt3yJg84yPOw9mpcwiUr5QZAcCWSWvBoIFnFMeFjfw6LZL4uwMbsH 80ToEMZnqeI056Mp+TcIXOLP6k44n8+lvM3ChwHQFhotrHCHGBNt2GEpYDlHrDtPLPmZ Sc9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date; bh=2LPHnonsaOKFONr4zrE8bl4o6Umi5pOIvGGo4+64f/0=; b=ZaKE/VZShblNwx4AGSR8+DooUC8s66A8hrGP9ZMb/83KVrPNNX9AUcQPPgXDByCrTb qJ21LxIoW3E9Xkm4Jcb13JrrF8Qkcex0kYMruJ50H+RojWpVmMdkCDPG1z99bxqzdIKL BrT+lD3KbYRf4LN/Y1YKbyLkoE/PdHJSq7sa6uB6bqU7MNniYFYcgVzfkxj7fePTvrNj XwJn+z7KIPtoGAMUdYcA//K3f3mLkv7B1livm319lov1gjOoYtfmXCZne4APAFLUHhLJ SOYOQDaBQamv9G0B81Au6SDE88DkOZsv9dAFeebLqCim9QDyD3JckesDpqXHB2xWD/+T rXWQ== 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 a23si1833129ejx.146.2021.03.11.05.34.04; Thu, 11 Mar 2021 05:34:26 -0800 (PST) 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 S233674AbhCKNa0 (ORCPT + 99 others); Thu, 11 Mar 2021 08:30:26 -0500 Received: from mslow2.mail.gandi.net ([217.70.178.242]:37811 "EHLO mslow2.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233725AbhCKNaU (ORCPT ); Thu, 11 Mar 2021 08:30:20 -0500 Received: from relay6-d.mail.gandi.net (unknown [217.70.183.198]) by mslow2.mail.gandi.net (Postfix) with ESMTP id C5A143E554D; Thu, 11 Mar 2021 13:10:28 +0000 (UTC) X-Originating-IP: 90.55.106.192 Received: from bootlin.com (atoulouse-258-1-35-192.w90-55.abo.wanadoo.fr [90.55.106.192]) (Authenticated sender: maxime.chevallier@bootlin.com) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id AD6DEC0004; Thu, 11 Mar 2021 13:10:03 +0000 (UTC) Date: Thu, 11 Mar 2021 14:09:59 +0100 From: Maxime Chevallier To: Hans Verkuil Cc: Mauro Carvalho Chehab , Rob Herring , linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Thomas Petazzoni , Miquel Raynal , Paul Kocialkowski Subject: Re: [PATCH v4 3/3] media: i2c: Introduce a driver for the Techwell TW9900 decoder Message-ID: <20210311140959.5a7b27e7@bootlin.com> In-Reply-To: References: <20210219081514.1592033-1-maxime.chevallier@bootlin.com> <20210219081514.1592033-4-maxime.chevallier@bootlin.com> X-Mailer: Claws Mail 3.17.8 (GTK+ 2.24.32; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Hans, and thanks for the review. On Thu, 4 Mar 2021 16:37:53 +0100 Hans Verkuil wrote: >Hi Maxime, > >Some more code review comments: > >> +static int tw9900_set_fmt(struct v4l2_subdev *sd, >> + struct v4l2_subdev_pad_config *cfg, >> + struct v4l2_subdev_format *fmt) >> +{ >> + struct tw9900 *tw9900 = to_tw9900(sd); >> + struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; >> + >> + tw9900_fill_fmt(tw9900->cur_mode, mbus_fmt); >> + >> + mbus_fmt->width = tw9900->cur_mode->width; >> + mbus_fmt->height = tw9900->cur_mode->height; > >These two lines are already done in tw9900_fill_fmt. Yes right, I'll remove that [...] >> + >> + return 0; >> +} >> + >> +static int tw9900_get_fmt(struct v4l2_subdev *sd, >> + struct v4l2_subdev_pad_config *cfg, >> + struct v4l2_subdev_format *fmt) >> +{ >> + struct tw9900 *tw9900 = to_tw9900(sd); >> + struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; >> + >> + tw9900_fill_fmt(tw9900->cur_mode, mbus_fmt); >> + >> + return 0; >> +} > >In fact, tw9900_set_fmt is identical to tw9900_get_fmt. I would just drop >tw9900_set_fmt and point both .get_fmt and .set_fmt to the same function. OK, that will be cleaner indeed [...] >> + >> +static int tw9900_enum_mbus_code(struct v4l2_subdev *sd, >> + struct v4l2_subdev_pad_config *cfg, >> + struct v4l2_subdev_mbus_code_enum *code) >> +{ >> + if (code->index >= 1) >> + return -EINVAL; >> + >> + code->code = MEDIA_BUS_FMT_UYVY8_2X8; >> + >> + return 0; >> +} >> + >> +static int tw9900_enum_frame_sizes(struct v4l2_subdev *sd, >> + struct v4l2_subdev_pad_config *cfg, >> + struct v4l2_subdev_frame_size_enum *fse) >> +{ >> + u32 index = fse->index; >> + >> + if (index >= 1) >> + return -EINVAL; >> + >> + fse->code = MEDIA_BUS_FMT_UYVY8_2X8; >> + >> + fse->min_width = supported_modes[index].width; >> + fse->max_width = supported_modes[index].width; >> + fse->max_height = supported_modes[index].height; >> + fse->min_height = supported_modes[index].height; >> + >> + return 0; >> +} > >This function is not typically used by video receivers since the framesize is >fixed depending on the standard. So there is nothing to enumerate. > >It is wrong in any case since it reports just supported_modes[0] (i.e. PAL) >even if the current mode is NTSC. But it can just be dropped for video receivers. Ok thanks, I'll drop that then. [...] >> + /* Wait for VSync lock */ >> + for (i = 0; i < VSYNC_WAIT_MAX_POLLS; i++) { >> + u8 status = tw9900_read_reg(tw9900->client, >> + TW9900_REG_CHIP_STATUS); >> + if (!(status & TW9900_REG_CHIP_STATUS_VDLOSS) && >> + (status & TW9900_REG_CHIP_STATUS_VLOCK)) >> + break; >> + >> + msleep(VSYNC_POLL_INTERVAL_MS); >> + } > >Why do you have to wait for a vsync lock? > >Most drivers just start regardless of lock. If there is no lock, then there >is either no data being streamed (so the DMA of the video bridge will be idle >as well) or it is just transmitting noise (typical for SDTV receivers). At least >until a valid signal appears eventually. In this case, it will transmit noise. As stated a bit below, this was implemented because this decoder actually supports automatic standard detection, but the reported standard can only be read once the vsync lock is acquired. So this is a remainder of what I implemented to try to get the standard detection work, but I can drop that for now. [...] >> +static int tw9900_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) >> +{ >> + struct tw9900 *tw9900 = to_tw9900(sd); >> + struct v4l2_mbus_framefmt *try_fmt; >> + >> + try_fmt = v4l2_subdev_get_try_format(sd, fh->pad, 0); >> + >> + /* Initialize try_fmt */ >> + tw9900_fill_fmt(tw9900->cur_mode, try_fmt); >> + >> + return 0; >> +} > >Since the format is fixed based on the current standard, there is no point >in initializing try_fmt as it won't be used. So just drop tw9900_open altogether. Ok I'll drop that :) [...] >> +static const struct v4l2_subdev_video_ops tw9900_video_ops = { >> + .s_std = tw9900_s_std, >> + .g_std = tw9900_g_std, > >Can the tw9900 detect the standard? (I.e. PAL, SECAM, NTSC) > >If so, you should implement querystd. I see that none of the other tw*.c drivers >support this, so I suspect there is no hardware support for this. So, there's hardware support for this, and I've been trying to get this to work for a while. I've come to a point where the standard detection "almost" works, but detects the wrong standard about once every 10 occurences. I don't know if this is due to the hardware I'm testing this on, my setup, or the decoder itself. This is in a setup where the standard can change on the fly (I have 2 cameras, one that streams PAL, one that streams NTSC, that are connected to the TW9900 through a switch, and I have to make so that we can detect a standard change (due to switching a camera) on the fly while the stream is started. The standard detection is also a process that is quite long and that has to be manually started, and then checked regularly to see if the decoder successfully identified a standard. I do have a followup question, which is when querystd() would be called in a "normal" scenarion (I feel that my usecase seems a bit off-track compared to classic usecases). Is it when the stream is started, or stopped ? >You also must implement g_tvnorms to report the TV standards that the hardware >can understand. Ok I didn't know about that, I'll implement that then. [...] >> + >> + tw9900->subdev.internal_ops = &tw9900_internal_ops; >> + tw9900->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; > >This is a duplicate of a similar '|=' above. My bad, I'll remove that line. > >Regards, > > Hans Thanks, Maxime