Received: by 10.223.185.116 with SMTP id b49csp2702461wrg; Mon, 12 Feb 2018 14:28:48 -0800 (PST) X-Google-Smtp-Source: AH8x224vNrtmd8cM0JcMzWfKzfvY2UQo9y46sg5pEsAQ0OoyBt1xlq+H8LtHbmcgKxXsRv0PZfSO X-Received: by 2002:a17:902:5a88:: with SMTP id r8-v6mr8787811pli.426.1518474528504; Mon, 12 Feb 2018 14:28:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518474528; cv=none; d=google.com; s=arc-20160816; b=ZjcQimsQNQa/RtFkb0XuW16OINtV/rzlrR6tS6mfOzRKwk2HTNCcCKoMeZY9GkUTS/ KkJFIAZnj+FMDEPnOZoxH7n65Uel20bt8wZmfc9+h5MD1+TXqri5Qc/FPxKMnKIbCmqo L5TDqGLS+/xVeGDof++MunZyp4edryCH9yerRi9cotN+NmNXP+aD3Y3OPqrJ1qQ7ZLd4 eazp7K+W3ihRHApj/MA2Y3WUYGAtlbezou2mkfmPPMbepWeV3lAEPsn0opXsfYB4rrK/ DxRy1Nl6i9sbg4xDb+Y2Im8rjcWLsIJtKJvN7yvdTzV9/JxDawDQmV9rqsKqoWuMODlg j6yQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=9tAUz+oVC5701NK04Eb4OiQRHhG+yx3pzoLsOpqiU6s=; b=VaHKHwXXVcPHAvOgUe6IRVw7/1ksE551PNm8o3tk1xMf/29CcaOOL9KtlROiLmhios 6jXSCYD9F3n/FThjAVQbfec2WU0YUQPCUnFNCbC+Z9YTIo8dNa93P6zX+ON4daUKH801 lVLRNsDePo+lvgifCcPI6jyGoAYIm7XwEVhcliWYTLEmEmnZKvz/CNoPAtRBI5wh0J+M Em5jtytfUChGLvgsTxx7LjbckLmijKIVMaLbPv7g/rKi+pq6nw8j4eECP3SLEV9eL60q 0sCoPf+0dAQewYApl4m22yK65AEZvJY7MmXKlh8bS7YyGTaCVdnLCLB2emwQ5B5JHv2b iIoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gateworks-com.20150623.gappssmtp.com header.s=20150623 header.b=fJGDkseh; 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 q15si344203pgc.727.2018.02.12.14.28.33; Mon, 12 Feb 2018 14:28:48 -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; dkim=pass header.i=@gateworks-com.20150623.gappssmtp.com header.s=20150623 header.b=fJGDkseh; 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 S932698AbeBLW16 (ORCPT + 99 others); Mon, 12 Feb 2018 17:27:58 -0500 Received: from mail-wm0-f47.google.com ([74.125.82.47]:38483 "EHLO mail-wm0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932628AbeBLW14 (ORCPT ); Mon, 12 Feb 2018 17:27:56 -0500 Received: by mail-wm0-f47.google.com with SMTP id 141so12668619wme.3 for ; Mon, 12 Feb 2018 14:27:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gateworks-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=9tAUz+oVC5701NK04Eb4OiQRHhG+yx3pzoLsOpqiU6s=; b=fJGDksehhfaz9meqvkSrGX4RuaG0ygndMykUSbmVMqzCUjyFjv0o+Zm0IszCO8Y7It 9O+7VOhYMruJbK8M9/WmLi7YVbmEF6xlgLAbp/ELdqlpf8inhhccDn/iTHkf//louQBl Tp95TuDTPTyzWUVFv/LeHVWHluJWi0vC9GqGkfKtlndIjh5ov20FAf8dFBSmvefi57wI yac2dvzFLjRlKoGOHr859I5YSFsV3lCz8lapg41/+5mMXjtDuLMROTjRTKWyifHc/0am OPCw6iWdUT+oTd49063mvcMbelzAYlhUCXvFrMIPuZbzFaAW+dCmGbS5LsA+6bTZTHU0 vilA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=9tAUz+oVC5701NK04Eb4OiQRHhG+yx3pzoLsOpqiU6s=; b=r6ZAP7/xoxcj0/ycc3EExoiaoCzvCjsVh4ZwQl6h8Gwyl7iYhmVRJmEVmzADcwOi39 W83tJzk0npU3Xs3HUKQT3jMeoIaV1clDjrTceNwYXvFiP/i+zFeHvSnaKmKfvCibxf5j 6d+daingITppajfUqIRLtv3X4+kFF/aq0O4KOSvGqVEg7UG9uButWsE5qJMdYJtaCc4y qjPJhjc8gCnTr4/L6z+ebYdfnQJFQ09Q3OWblLEZ4BMMJ+Vve3YY1GWOhvVYhcJ7tohU +WutfcqGfft21LJnrhP/QKyf8wU7GCJWjvBS//a/QovXcpgdpBQlaT9FeJMlLcHy186l USKA== X-Gm-Message-State: APf1xPDcNAUK+McLS+/OTAPDRykKQ3/Y4WkbrYY4YOCsVGkcOglnLAp5 i9Yt0UvopsHDUMqkqwa9PCxOs8It+iWlOoOA1954zg== X-Received: by 10.28.153.147 with SMTP id b141mr46292wme.47.1518474474578; Mon, 12 Feb 2018 14:27:54 -0800 (PST) MIME-Version: 1.0 Received: by 10.28.66.74 with HTTP; Mon, 12 Feb 2018 14:27:53 -0800 (PST) In-Reply-To: References: <1518157956-14220-1-git-send-email-tharvey@gateworks.com> <1518157956-14220-7-git-send-email-tharvey@gateworks.com> From: Tim Harvey Date: Mon, 12 Feb 2018 14:27:53 -0800 Message-ID: Subject: Re: [PATCH v10 6/8] media: i2c: Add TDA1997x HDMI receiver driver To: Hans Verkuil Cc: linux-media , alsa-devel@alsa-project.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Shawn Guo , Steve Longerbeam , Philipp Zabel , Hans Verkuil , Mauro Carvalho Chehab Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Feb 9, 2018 at 12:08 AM, Hans Verkuil wrote: > Hi Tim, > > We're almost there. Two more comments: > > On 02/09/2018 07:32 AM, Tim Harvey wrote: >> +static int >> +tda1997x_detect_std(struct tda1997x_state *state, >> + struct v4l2_dv_timings *timings) >> +{ >> + struct v4l2_subdev *sd = &state->sd; >> + u32 vper; >> + u16 hper; >> + u16 hsper; >> + int i; >> + >> + /* >> + * Read the FMT registers >> + * REG_V_PER: Period of a frame (or two fields) in MCLK(27MHz) cycles >> + * REG_H_PER: Period of a line in MCLK(27MHz) cycles >> + * REG_HS_WIDTH: Period of horiz sync pulse in MCLK(27MHz) cycles >> + */ >> + vper = io_read24(sd, REG_V_PER) & MASK_VPER; >> + hper = io_read16(sd, REG_H_PER) & MASK_HPER; >> + hsper = io_read16(sd, REG_HS_WIDTH) & MASK_HSWIDTH; >> + if (!vper || !hper || !hsper) >> + return -ENOLINK; > > See my comment for g_input_status below. This condition looks more like a > ENOLCK. > > Or perhaps it should be: > > if (!vper && !hper && !hsper) > return -ENOLINK; > if (!vper || !hper || !hsper) > return -ENOLCK; > > I would recommend that you test a bit with no signal and a bad signal (perhaps > one that uses a pixelclock that is too high for this device?). I can't figure out how to produce a signal that can't be locked onto with what I have available. > >> + v4l2_dbg(1, debug, sd, "Signal Timings: %u/%u/%u\n", vper, hper, hsper); >> + >> + for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) { >> + const struct v4l2_bt_timings *bt; >> + u32 lines, width, _hper, _hsper; >> + u32 vmin, vmax, hmin, hmax, hsmin, hsmax; >> + bool vmatch, hmatch, hsmatch; >> + >> + bt = &v4l2_dv_timings_presets[i].bt; >> + width = V4L2_DV_BT_FRAME_WIDTH(bt); >> + lines = V4L2_DV_BT_FRAME_HEIGHT(bt); >> + _hper = (u32)bt->pixelclock / width; >> + if (bt->interlaced) >> + lines /= 2; >> + /* vper +/- 0.7% */ >> + vmin = ((27000000 / 1000) * 993) / _hper * lines; >> + vmax = ((27000000 / 1000) * 1007) / _hper * lines; >> + /* hper +/- 1.0% */ >> + hmin = ((27000000 / 100) * 99) / _hper; >> + hmax = ((27000000 / 100) * 101) / _hper; >> + /* hsper +/- 2 (take care to avoid 32bit overflow) */ >> + _hsper = 27000 * bt->hsync / ((u32)bt->pixelclock/1000); >> + hsmin = _hsper - 2; >> + hsmax = _hsper + 2; >> + >> + /* vmatch matches the framerate */ >> + vmatch = ((vper <= vmax) && (vper >= vmin)) ? 1 : 0; >> + /* hmatch matches the width */ >> + hmatch = ((hper <= hmax) && (hper >= hmin)) ? 1 : 0; >> + /* hsmatch matches the hswidth */ >> + hsmatch = ((hsper <= hsmax) && (hsper >= hsmin)) ? 1 : 0; >> + if (hmatch && vmatch && hsmatch) { >> + *timings = v4l2_dv_timings_presets[i]; >> + v4l2_print_dv_timings(sd->name, "Detected format: ", >> + timings, false); >> + return 0; >> + } >> + } >> + >> + v4l_err(state->client, "no resolution match for timings: %d/%d/%d\n", >> + vper, hper, hsper); >> + return -EINVAL; >> +} > > -EINVAL isn't the correct error code here. I would go for -ERANGE. It's not > perfect, but close enough. > > -EINVAL indicates that the user filled in wrong values, but that's not the > case here. done > >> +static int >> +tda1997x_g_input_status(struct v4l2_subdev *sd, u32 *status) >> +{ >> + struct tda1997x_state *state = to_state(sd); >> + u32 vper; >> + u16 hper; >> + u16 hsper; >> + >> + mutex_lock(&state->lock); >> + v4l2_dbg(1, debug, sd, "inputs:%d/%d\n", >> + state->input_detect[0], state->input_detect[1]); >> + if (state->input_detect[0] || state->input_detect[1]) > > I'm confused. This device has two HDMI inputs? > > Does 'detecting input' equate to 'I see a signal and I am locked'? > I gather from the irq function that sets these values that it is closer > to 'I see a signal' and that 'I am locked' is something you would test > by looking at the vper/hper/hsper. The TDA19972 and/or TDA19973 has an A and B input but only a single output. I'm not entirely clear if/how to select between the two and I don't have proper documentation for the three chips. The TDA19971 which I have on my board only has 1 input which is reported as the 'A' input. I can likely nuke the stuff looking at the B input and/or put some qualifiers around it but I didn't want to remove code that was derived from some vendor code that might help support the other chips in the future. So I would rather like to leave the 'if A or B' stuff. > >> + *status = 0; >> + else { >> + vper = io_read24(sd, REG_V_PER) & MASK_VPER; >> + hper = io_read16(sd, REG_H_PER) & MASK_HPER; >> + hsper = io_read16(sd, REG_HS_WIDTH) & MASK_HSWIDTH; >> + v4l2_dbg(1, debug, sd, "timings:%d/%d/%d\n", vper, hper, hsper); >> + if (!vper || !hper || !hsper) >> + *status |= V4L2_IN_ST_NO_SYNC; >> + else >> + *status |= V4L2_IN_ST_NO_SIGNAL; > > So if we have valid vper, hper and hsper, then there is no signal? That doesn't > make sense. > > I'd expect to see something like this: > > if (!input_detect[0] && !input_detect[1]) > // no signal > else if (!vper || !hper || !vsper) > // no sync > else > // have signal and sync sure... reads a bit cleaner. I can't guarantee that any of vper/hper/vsper will be 0 if a signal can't be locked onto without proper documentation or ability to generate such a signal. I do know if I yank the source I get non-zero random values and must rely on the input_detect logic. > > I'm not sure about the precise meaning of input_detect, so I might be wrong about > that bit. ya... me either. I'm trying my hardest to get this driver up to shape but the documentation I have is utter crap and I'm doing some guessing as well as to what all the registers are and what the meaning of the very obfuscated vendor code does. would you object to detecting timings and displaying via v4l2_dbg when a resolution change is detected (just not 'using' those timings for anything?): @@ -1384,6 +1386,7 @@ static void tda1997x_irq_sus(struct tda1997x_state *state, u8 *flags) v4l_err(state->client, "BAD SUS STATUS\n"); return; } + if (debug) + tda1997x_detect_std(state, NULL); /* notify user of change in resolution */ v4l2_subdev_notify_event(&state->sd, &tda1997x_ev_fmt); } @@ -1140,16 +1140,18 @@ tda1997x_detect_std(struct tda1997x_state *state, /* hsmatch matches the hswidth */ hsmatch = ((hsper <= hsmax) && (hsper >= hsmin)) ? 1 : 0; if (hmatch && vmatch && hsmatch) { - *timings = v4l2_dv_timings_presets[i]; v4l2_print_dv_timings(sd->name, "Detected format: ", - timings, false); + &v4l2_dv_timings_presets[i], + false); + if (timings) + *timings = v4l2_dv_timings_presets[i]; return 0; } } It seems to make sense to me to be seeing a kernel message when timings change and what they change to without having to query :) Tim