From patchwork Mon Jun 24 09:52:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709253 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD47212E1F6 for ; Mon, 24 Jun 2024 09:55:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222914; cv=none; b=r9gfTkyPlmI71w836aR9bY320jrzCsqHntdqJDqP1UKCGflbNAwf2Zg3MXMXddYzOkQuNobRynuU1YM9H3Bf+0zV1LL9bIM5bSuQDYvUuemcTDNauhcJn3m5keW8vRy51xhp0JYn0mS3w5R4h4Wirxr4pgYAeM+pgUpemZc6Jnw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222914; c=relaxed/simple; bh=VSFBbg9fQfHgCcEb0q8PTXYqQmPK8UhIVmlSWR7Jaws=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=F/LGYCuBCCk7LJAnuzuE6Pxk2ReLHyy4ItLLKN/45wyp80h7kMBTUgv8+ATy+Kdv1e5QfTQ5W8xRu/MsKeKh9fLvnjBmSKPHt2oejqxf3cpCdptAC0VZnVb8RtbwDp+UjSGYLk2NG9DakNfnq8WrBgTnu3krtzzhsWheoBxe3ms= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=eiCSqxHW; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eiCSqxHW" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-424720e73e1so33458015e9.1 for ; Mon, 24 Jun 2024 02:55:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719222911; x=1719827711; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PWv9lGW8ZISyKh5uccQb58M33+vfoTS4drgAEK8mR0w=; b=eiCSqxHWg+w4sMKw2U4koTVwCK69ChGxgzwCWmeOSxxMggFiw5+c9vhJkz7VMSRE87 l8agsVsoHrgRZebIyvEWLILpR7lqxY2834rC2oCD62zbaNoLdj2pQSb/7dvK0rubeMMg g9DnkgPcKK1d++VDUAu3IVd4bP+CHuWzFGWGeGFjSwarHPU1bpo0zvNimExnqJer1iuq kXROsvCQ1MInfb7f652P7T8tBYuBZcA8B3AGiuouAQsjTky21TBQibuFj67ISNOBNHxj htuDSkwP7mY4JoyL4fnhIaNnD2B1e+K1jp7O1iVT4QpZNViKhhTQb+DFyhH7JOR1mMgo yKKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719222911; x=1719827711; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PWv9lGW8ZISyKh5uccQb58M33+vfoTS4drgAEK8mR0w=; b=ljxkmRhcy00WqLbcIzh1HuL1LU0IurvGZGfQ4W5n0kDr62v9B7hd6xJvrKeRfo3nzh IVBqY2Hao2tnkVw/yoWqPFD3awGVB1IcHMa3ZU7WY9AJyywMmQUhRRlWeebCGqpMbksx OgZVe+lUvqSR0lGx+IjuYMGWB9e8kmxfQo8XNvbpuQxNdGKMwLvXP6I5MG/h4+MbNlV3 EwzmpeCGLvlNPkluXnA/kMq8Q1N7k/FRZmk84ZLYWm2GuiaUKlDk0EPphl4ldEFXpZFs H6FLRRt2x6cc7FA96CD8V4s0qnbOJ/WSRM39WfKMK2qvxRKrv83RM+roEB6cl2I6NBzV og3g== X-Gm-Message-State: AOJu0YzQwE9vSMIDG0SpF0v05dPavFO5yoQRfB6KZLeAYphtSj31BzZu dQQ0svcNXfzgKS+DHyZ7IsZfmbAlH7glcN2JLGS/B4FU/BEuKcBc63cNAjQ= X-Google-Smtp-Source: AGHT+IFhocGizDs8pem8Gyg52bywIZ6yklgfHSgtdswF/opR933pCkUxbL7RBeUU3E13v8qSo6/UVw== X-Received: by 2002:a5d:6a42:0:b0:366:d5ea:6098 with SMTP id ffacd0b85a97d-366e94d86b8mr2615041f8f.3.1719222910591; Mon, 24 Jun 2024 02:55:10 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.55.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:55:10 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com, Hans Verkuil Subject: [PATCH 01/10] media: Documentation: vivid.rst: fix confusing section refs Date: Mon, 24 Jun 2024 12:52:53 +0300 Message-Id: <20240624095300.745567-2-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Hans Verkuil The documentation contained several instances of "section X" references, which no longer map to whatever X was. Replace these by the section titles. Also fix a single confusing typo in the "Radio & RDS Looping" section: "are regular frequency intervals" -> "at regular frequency intervals" Signed-off-by: Hans Verkuil --- Documentation/admin-guide/media/vivid.rst | 41 ++++++++++++----------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst index b6f658c0997e..04de7b69c817 100644 --- a/Documentation/admin-guide/media/vivid.rst +++ b/Documentation/admin-guide/media/vivid.rst @@ -313,10 +313,10 @@ Video Capture This is probably the most frequently used feature. The video capture device can be configured by using the module options num_inputs, input_types and -ccs_cap_mode (see section 1 for more detailed information), but by default -four inputs are configured: a webcam, a TV tuner, an S-Video and an HDMI -input, one input for each input type. Those are described in more detail -below. +ccs_cap_mode (see "Configuring the driver" for more detailed information), +but by default four inputs are configured: a webcam, a TV tuner, an S-Video +and an HDMI input, one input for each input type. Those are described in more +detail below. Special attention has been given to the rate at which new frames become available. The jitter will be around 1 jiffie (that depends on the HZ @@ -434,10 +434,10 @@ Video Output ------------ The video output device can be configured by using the module options -num_outputs, output_types and ccs_out_mode (see section 1 for more detailed -information), but by default two outputs are configured: an S-Video and an -HDMI input, one output for each output type. Those are described in more detail -below. +num_outputs, output_types and ccs_out_mode (see "Configuring the driver" +for more detailed information), but by default two outputs are configured: +an S-Video and an HDMI input, one output for each output type. Those are +described in more detail below. Like with video capture the framerate is also exact in the long term. @@ -1200,15 +1200,15 @@ and WSS (50 Hz formats) VBI data is looped. Teletext VBI data is not looped. Radio & RDS Looping ~~~~~~~~~~~~~~~~~~~ -As mentioned in section 6 the radio receiver emulates stations are regular -frequency intervals. Depending on the frequency of the radio receiver a -signal strength value is calculated (this is returned by VIDIOC_G_TUNER). -However, it will also look at the frequency set by the radio transmitter and -if that results in a higher signal strength than the settings of the radio -transmitter will be used as if it was a valid station. This also includes -the RDS data (if any) that the transmitter 'transmits'. This is received -faithfully on the receiver side. Note that when the driver is loaded the -frequencies of the radio receiver and transmitter are not identical, so +As mentioned in the "Radio Receiver" section, the radio receiver emulates +stations at regular frequency intervals. Depending on the frequency of the +radio receiver a signal strength value is calculated (this is returned by +VIDIOC_G_TUNER). However, it will also look at the frequency set by the radio +transmitter and if that results in a higher signal strength than the settings +of the radio transmitter will be used as if it was a valid station. This also +includes the RDS data (if any) that the transmitter 'transmits'. This is +received faithfully on the receiver side. Note that when the driver is loaded +the frequencies of the radio receiver and transmitter are not identical, so initially no looping takes place. @@ -1218,8 +1218,8 @@ Cropping, Composing, Scaling This driver supports cropping, composing and scaling in any combination. Normally which features are supported can be selected through the Vivid controls, but it is also possible to hardcode it when the module is loaded through the -ccs_cap_mode and ccs_out_mode module options. See section 1 on the details of -these module options. +ccs_cap_mode and ccs_out_mode module options. See "Configuring the driver" on +the details of these module options. This allows you to test your application for all these variations. @@ -1260,7 +1260,8 @@ is set, then the alpha component is only used for the color red and set to The driver has to be configured to support the multiplanar formats. By default the driver instances are single-planar. This can be changed by setting the -multiplanar module option, see section 1 for more details on that option. +multiplanar module option, see "Configuring the driver" for more details on that +option. If the driver instance is using the multiplanar formats/API, then the first single planar format (YUYV) and the multiplanar NV16M and NV61M formats the From patchwork Mon Jun 24 09:52:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709254 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB7E112E1F6 for ; Mon, 24 Jun 2024 09:55:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222920; cv=none; b=ORbGF3nUddS8U5Cz5vNdzQVc7i9WrCbnzntlpI3RrlIxm3eUJJEtJDtskdbu7mOZAf6r9K+02ojMVuAr/hoIOc8KPExlVv02n9O4/SVNrUrcJG4qo/5lsRRJIOAaOdtZ4/zn8DqZaxn4cw1K+bFIRdMqwqqw9ffXPD5DwExjmo0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222920; c=relaxed/simple; bh=pFFsiyTMsJFwoweK6WIj5SyTkZYwx2mrHFXvTDZ5x3k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fgBeXwIO6yJW0USApYiXtN1K4mRZZLwzyKqlFPyN+GU/PZFESr3JOq5cpTGUOS/C5QUJacvV8kW4KBuMD7mxXt2/hRB3oAkts5sIt30ONr53Dw8ABkDnVx/Ay7ypNb1cljLwlExdjkdXhtsOxz1Bd4M6bkPIegDEDQQ1wHayDIk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=L2n0HL91; arc=none smtp.client-ip=209.85.128.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="L2n0HL91" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-4247f36f689so28724655e9.1 for ; Mon, 24 Jun 2024 02:55:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719222917; x=1719827717; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=i1+ccEk4s+CNZ58f0ojOOCaFbBcXQLr9fD7KFZ9QweU=; b=L2n0HL91qSVb24crI1ng0nAMssm5rdhfkQxMI5/+tJxneARslZtuVVqqfp2m70j1w4 lh/yxMhdPJdD8GEmRV1xF68vBLNGv7tfKh9o1+jvQpv6sK8yDF1m4D9JGfLEMXXdBGmA mq9KYoxYq5dCmJDK5GPevnUx1Ny2UOlvWkQV5ZWgIGg9Yz890HwE+IidQykfr4HN8rIV 2G337kggarHtB9sjKmJ06mZ0JPGaI/kPExxb3RHuC125I2a1/vlFUQXCQw1Ub0Mv3nLp bj9CVLJ3UZi55fljbW5RUdbyM0XiW6BB40DMwNGY8fhV1b0cVImYrUY6n4WVPDwXdZvD f1VQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719222917; x=1719827717; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=i1+ccEk4s+CNZ58f0ojOOCaFbBcXQLr9fD7KFZ9QweU=; b=VRPb17+Y9t3AZnNsCuV6Xzvty0iC3UBxyNaOWfnXWFQazo5NT8UbcdQvhDGvGx3XMC 8z+Ksv6Dt7DOui45zY9ZJKEXAa+jjaHqre7E+XTltFyM5yXYATdCYEAADDEHybIZKLYV 4ckVHK79AzbWcBr7p/7DVqDqIem6WpdjU1ON1UxMqBT3Ri9SwhaHXz8Xn4pVWnTYOSED J3Uf4mjBh5aaAY0baoH3Fi31u1pQd3QRpub0C6yEkmdJWIQFBeWSorbu5dFzyiHIVULv Yos2T46ZtX3wccbNTQ9/+b6DOqD3WP2T73k7nPBn2Won0Clq1qP71wT5aofIOg1W/Ohk Vj9Q== X-Gm-Message-State: AOJu0YzEbwg0tqjwpiHvvoP0hXURKw33Nd6h1Fn3GCqv7YY4BE3n6bA5 XV0qDjYZCyWALb+FoZQLlD6Uq223oGwMSRv49xShZQb9WTVqmD7omkMfj7U= X-Google-Smtp-Source: AGHT+IGX96ADMzIxzr/Dw3X01RT3His87CPRoaxzLrXLZgvZHXcJy20hTg2pPzrUI9KpH5Ok1Vo8kA== X-Received: by 2002:a05:600c:26d4:b0:422:aca:f887 with SMTP id 5b1f17b1804b1-4248b9cf993mr34928885e9.28.1719222916723; Mon, 24 Jun 2024 02:55:16 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.55.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:55:16 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com, Hans Verkuil Subject: [PATCH 02/10] media: Documentation: vivid.rst: drop "Video, VBI and RDS Looping" Date: Mon, 24 Jun 2024 12:52:54 +0300 Message-Id: <20240624095300.745567-3-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Hans Verkuil Drop the "Video, VBI and RDS Looping" section, instead moving the Video/VBI info to section "Video and Sliced VBI looping" and the RDS info to section "Radio & RDS Looping". Signed-off-by: Hans Verkuil --- Documentation/admin-guide/media/vivid.rst | 32 ++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst index 04de7b69c817..d7d5a01f4e59 100644 --- a/Documentation/admin-guide/media/vivid.rst +++ b/Documentation/admin-guide/media/vivid.rst @@ -1130,26 +1130,19 @@ Metadata Capture Controls if set, then the generated metadata stream contains Source Clock information. -Video, VBI and RDS Looping --------------------------- -The vivid driver supports looping of video output to video input, VBI output -to VBI input and RDS output to RDS input. For video/VBI looping this emulates -as if a cable was hooked up between the output and input connector. So video -and VBI looping is only supported between S-Video and HDMI inputs and outputs. -VBI is only valid for S-Video as it makes no sense for HDMI. +Video and Sliced VBI Looping +---------------------------- -Since radio is wireless this looping always happens if the radio receiver -frequency is close to the radio transmitter frequency. In that case the radio -transmitter will 'override' the emulated radio stations. +The vivid driver supports looping of video output to video input, and VBI +output to VBI input. For video/VBI looping this emulates as if a cable was +hooked up between the output and input connector. So video and VBI looping +is only supported between S-Video and HDMI inputs and outputs. +VBI is only valid for S-Video as it makes no sense for HDMI. Looping is currently supported only between devices created by the same vivid driver instance. - -Video and Sliced VBI looping -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - The way to enable video/VBI looping is currently fairly crude. A 'Loop Video' control is available in the "Vivid" control class of the video capture and VBI capture devices. When checked the video looping will be enabled. @@ -1198,7 +1191,16 @@ and WSS (50 Hz formats) VBI data is looped. Teletext VBI data is not looped. Radio & RDS Looping -~~~~~~~~~~~~~~~~~~~ +------------------- + +The vivid driver supports looping of RDS output to RDS input. + +Since radio is wireless this looping always happens if the radio receiver +frequency is close to the radio transmitter frequency. In that case the radio +transmitter will 'override' the emulated radio stations. + +RDS looping is currently supported only between devices created by the same +vivid driver instance. As mentioned in the "Radio Receiver" section, the radio receiver emulates stations at regular frequency intervals. Depending on the frequency of the From patchwork Mon Jun 24 09:52:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709255 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 016C6134407 for ; Mon, 24 Jun 2024 09:55:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222927; cv=none; b=EZS8WimBHvZmfTPTAR3X4JGIj4WrCEMgn1D4y4BvjimlHqaFTdx33yl6b8ItuZxco72JGK6HMTlLCS2LxjAG8aX8rZgFnKogT6TPj2GaBJLKLelt4okvVjNR3OdqzFJeM2UqfH6vzfLsXr7A3CE0Y9yCU4vuZkx4MIhSCHiFBhg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222927; c=relaxed/simple; bh=05XRxdK5KSF9/nWjTvS2qW0gk3XjqLPSY4/AihOYYlQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=B/w8Sv2ZeY2toBAZjhHAY1KbVUgrF2khEqhV4l8eTakvyuvpeSCID1RVGrkciU1jYf+5mMp1RXIXr200DD35D7DZRqs0g1RtjD/FSq7kPYDWSHDF4zh9Xn69rA5PKoQmGfw6qCsJeRZmt5Y4n0OMWNjfpyQjaQ6pLOPBk99GfIY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BugPHSgH; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BugPHSgH" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-421757d217aso45134735e9.3 for ; Mon, 24 Jun 2024 02:55:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719222924; x=1719827724; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NuKH1L6SOVF9s069qwn3whS+iN8IefC7VE5uaYSL6oQ=; b=BugPHSgHlheYg0AHM7yujzhWoyRAu65tXPq4N1c5lleTR2km6WZKy8i4UadWcfCikA b6ykorgu7NHS1Lc3QihvWoSj7aCUK6t8+AVJBLnjTYf6AXJT4WnhcqZsEscIjoryX9bb b07SB5YZ/hBc7n3wNTz/95q8kC6DNryaZZFButOzxT9TncdbN5JFh0g39XOg7fq4A7Ez afxp+4kWWsMyNxLBju3CEVVOyoxGBaUEpAJH8osTyWlJ4UJmbPwfmfUnyWcYWfXCF1iw usjJHpkv7EoFKb8HvOaCdk4e+iMc6Or/GxxRUXinBDMniKisDASqBG/AQ4CMIJdTxQyD 1XQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719222924; x=1719827724; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NuKH1L6SOVF9s069qwn3whS+iN8IefC7VE5uaYSL6oQ=; b=ICl6toAHwrdJ6Yqx0QXtmgpc2ds/5+4bpc+rG2V31iI3xYBON0Tr6CorHgo7/MxPuU 9x5Mcy9gMdVeg5aL8b12CaoNHX2HfngSvwNiprJbM+Eo4lIPRtWKidbOe4gZecqjMlmH JAeBlaHSmM1ZYQo9Vz5ry02CHfA+zDZsAur5wqvH/gq2ZmzCAIigzyEYXnmDFgDgAsMc Bbpn5EKfGTC+6apJ43OtsizWiz5Kv5qzp0U3Js+3EEcf6nj6rJM6ZtoW0ihutf3xUCCi VdxU/m8ocJG0284O8zM3KY0olKW5N6iwvu0FJvr09KLhHmBJF/ZGZPn1wkk1L79zgBTW z7kg== X-Gm-Message-State: AOJu0Yz0tuRRLjYkdMTyThTR/DCpjrVDxHHHmIUMllMT7/Lpyxcm45q7 Rd3CLUflBqCq5tL9Gs2g5/vwQaQee9+TRq+qZZykUZfa6gxPUKbxEdeDvsA= X-Google-Smtp-Source: AGHT+IGXWU5ZgAY5idFL6bKvQQxVMKxJ03kKoDBrWrlI9wZaiRjokFUYyxYM4AYRO7a+fkSGHMkI2A== X-Received: by 2002:a05:600c:4f92:b0:424:9612:f738 with SMTP id 5b1f17b1804b1-4249612fb0dmr9225455e9.28.1719222923944; Mon, 24 Jun 2024 02:55:23 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.55.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:55:23 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com, Hans Verkuil Subject: [PATCH 03/10] media: Documentation: vivid.rst: add supports_requests Date: Mon, 24 Jun 2024 12:52:55 +0300 Message-Id: <20240624095300.745567-4-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Hans Verkuil The module option supports_requests was not documented, add it. Signed-off-by: Hans Verkuil --- Documentation/admin-guide/media/vivid.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst index d7d5a01f4e59..917b57225939 100644 --- a/Documentation/admin-guide/media/vivid.rst +++ b/Documentation/admin-guide/media/vivid.rst @@ -302,6 +302,15 @@ all configurable using the following module options: - 0: forbid hints - 1: allow hints +- supports_requests: + + specifies if the device should support the Request API. There are + three possible values, default is 1: + + - 0: no request + - 1: supports requests + - 2: requires requests + Taken together, all these module options allow you to precisely customize the driver behavior and test your application with all sorts of permutations. It is also very suitable to emulate hardware that is not yet available, e.g. From patchwork Mon Jun 24 09:52:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709256 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 93A2E12E1F6 for ; Mon, 24 Jun 2024 09:55:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222944; cv=none; b=kR1MTnqrDa5ldaoAy7IG5gG94B1k0IAyp9mUZmo/op6EFb0mnzv0wV2lOrc3dveWB/fRO0n3UAV9P+oDEdB6HqsZbsJoJJcel7Z8q7PE6Y4x7h5AHkDekpGK+AGcN4oH+eLyXe4qbVWHsDI6Rfx6DVudR2sWqpP0TSwE7fIQ2mE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222944; c=relaxed/simple; bh=u7dipANjaxDtqPp/l5/VY1sxA3WnXlxgwt1Womrd2UY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ScgJpEMwijT/lDdK6W0TW9/4OtwH8QmXNEaVPOIK2WPfKJSu4gi7RN15xLpy8s9J05qezITsVusH699fbj/WXea0e8vNqQBCrpDpcr+7wFF0MN0M/oWc4vVKEwLQE8uPTnaldaE8uRq0kHWXJIAx1UFyzattI6p/Y3DUWsJAiCU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RnpkivYL; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RnpkivYL" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-421b9068274so36285895e9.1 for ; Mon, 24 Jun 2024 02:55:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719222941; x=1719827741; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=yVNiWfuaFq46y6Euu+d/DApjCpD2SqkQJUanWaoYbzU=; b=RnpkivYLZBSa6+pnvo4aYzsDA6ap5m6ztR6tRpXJYRiVr7VnXCUcxK9CwPDvDK6YKZ OF8WrtPcXwDOhkasLg+8p1iQperNIaX3Nr98D8NQCfy09QCDOknFKOR9ZRzVhgNm7B7o 187OVUEhlYbP3xvooXft0EXAfVsx8WhwoO7CHrHQWxOAPRUjgEy7zfk0rtYK5TTyplKy HiqztUPVzntdQCi9X0j6erxr9pM8ifWpvsOXi/Dpfll8CGU/j3aU9FcHyh8GOWo2/Yxq ZT9QIOsiE48aI1KNDzxhNUV2ATKUYSJ4dgZoprPacybtvn161Dy38hnLM8Uht6EqsS9u e/FQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719222941; x=1719827741; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yVNiWfuaFq46y6Euu+d/DApjCpD2SqkQJUanWaoYbzU=; b=kwE3I/mggwf+JuJ2znJDK9k8C9leRbR29ndXGq9LOh6Zz2smixbGkMTUFHZ50XB0wd qit7B4jWsdy+pLQH7HUGeZb+QdPgRewieniswtiay0yMBc9g6/o23Z7I1WDoPENL+yNn qWWvGChNBXIHQefhZsUykvY1rjs6h/6FkbHQGu4QyDt+hisCWJBqQ4mDNXDrPwsFxamz JHEk/cjxD1hlQBP8Xnuv0KRIYPVZjN9luZllf6bxOzR5hFl7nihix2W+OAKGOuU2eKaC SUxYZAd6YaF7/luP5S70hjeLc9bwOcoigWiI4+PswKhDuQrM339NlTIr/oWMdR7pe02E OYCg== X-Gm-Message-State: AOJu0YzwjV2zvvtNHdMJcXEy7dBX3A3J1h15jQGHX001l/5H6jltnn3X fLJWpEjpDsJ5v66sV+s2GX8pt3GkiqgUAgmsNSrR8ZtLej8mRRwV/BGw1Uc= X-Google-Smtp-Source: AGHT+IHJGIKSiuX00J4XY30XGfNsGMUf3ejAoo/bnuh86AVPgAfaEuJkE3xqcsuogNlw3zPsQ0ke/g== X-Received: by 2002:a05:600c:5699:b0:422:384e:4365 with SMTP id 5b1f17b1804b1-4248b936414mr34640145e9.2.1719222940442; Mon, 24 Jun 2024 02:55:40 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.55.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:55:40 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com Subject: [PATCH 04/10] media: Documentation: vivid.rst: Remove documentation for Capture Overlay Date: Mon, 24 Jun 2024 12:52:57 +0300 Message-Id: <20240624095300.745567-5-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Modifying documentation to remove 'Capture Overlay section' as destructive capture overlay support was removed. See commit ccaa9d50ca73 ("media: vivid: drop overlay support") Signed-off-by: Dorcas Anono Litunya --- Documentation/admin-guide/media/vivid.rst | 68 ----------------------- 1 file changed, 68 deletions(-) diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst index 917b57225939..31fb86030249 100644 --- a/Documentation/admin-guide/media/vivid.rst +++ b/Documentation/admin-guide/media/vivid.rst @@ -1282,74 +1282,6 @@ data_offset to be non-zero, so this is a useful feature for testing applications Video output will also honor any data_offset that the application set. -Capture Overlay ---------------- - -Note: capture overlay support is implemented primarily to test the existing -V4L2 capture overlay API. In practice few if any GPUs support such overlays -anymore, and neither are they generally needed anymore since modern hardware -is so much more capable. By setting flag 0x10000 in the node_types module -option the vivid driver will create a simple framebuffer device that can be -used for testing this API. Whether this API should be used for new drivers is -questionable. - -This driver has support for a destructive capture overlay with bitmap clipping -and list clipping (up to 16 rectangles) capabilities. Overlays are not -supported for multiplanar formats. It also honors the struct v4l2_window field -setting: if it is set to FIELD_TOP or FIELD_BOTTOM and the capture setting is -FIELD_ALTERNATE, then only the top or bottom fields will be copied to the overlay. - -The overlay only works if you are also capturing at that same time. This is a -vivid limitation since it copies from a buffer to the overlay instead of -filling the overlay directly. And if you are not capturing, then no buffers -are available to fill. - -In addition, the pixelformat of the capture format and that of the framebuffer -must be the same for the overlay to work. Otherwise VIDIOC_OVERLAY will return -an error. - -In order to really see what it going on you will need to create two vivid -instances: the first with a framebuffer enabled. You configure the capture -overlay of the second instance to use the framebuffer of the first, then -you start capturing in the second instance. For the first instance you setup -the output overlay for the video output, turn on video looping and capture -to see the blended framebuffer overlay that's being written to by the second -instance. This setup would require the following commands: - -.. code-block:: none - - $ sudo modprobe vivid n_devs=2 node_types=0x10101,0x1 - $ v4l2-ctl -d1 --find-fb - /dev/fb1 is the framebuffer associated with base address 0x12800000 - $ sudo v4l2-ctl -d2 --set-fbuf fb=1 - $ v4l2-ctl -d1 --set-fbuf fb=1 - $ v4l2-ctl -d0 --set-fmt-video=pixelformat='AR15' - $ v4l2-ctl -d1 --set-fmt-video-out=pixelformat='AR15' - $ v4l2-ctl -d2 --set-fmt-video=pixelformat='AR15' - $ v4l2-ctl -d0 -i2 - $ v4l2-ctl -d2 -i2 - $ v4l2-ctl -d2 -c horizontal_movement=4 - $ v4l2-ctl -d1 --overlay=1 - $ v4l2-ctl -d0 -c loop_video=1 - $ v4l2-ctl -d2 --stream-mmap --overlay=1 - -And from another console: - -.. code-block:: none - - $ v4l2-ctl -d1 --stream-out-mmap - -And yet another console: - -.. code-block:: none - - $ qv4l2 - -and start streaming. - -As you can see, this is not for the faint of heart... - - Output Overlay -------------- From patchwork Mon Jun 24 09:52:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709257 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1A9A013248E for ; Mon, 24 Jun 2024 09:55:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222955; cv=none; b=IFLi63+umB2q6Y7d3Ynv0zCaCzERn89x4/y9gaB11vlhx7f4kaj38F/9wKw4nvl8sySXBycCdjsIapmUFlYlHvbmLor0Eip2NW7Paq//uME9H8nlrqt8OYLSxBtC5XQOnRIQ4ZcWgNvSri/IV66RO/lNx4eynzqbCrZrcbLGqs0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222955; c=relaxed/simple; bh=FJMHlIcGPE6yU14Apfn5AmKH0FSzCEBzXYJ3Ya0nAj4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=sYME6QpQqSXjM1i9iiu7lCUhl+MoJDy9k1oEyJpZADogu9cdyr5hyx8lW1dQRizXaK29q9+HOqRPb4Y18K5qsjRrk2tc9GYOIoo/a9Uhw4ZlROji+9UeV8I9upw9y/C+SM5GMAjj7PoCZ8VIxmoXRqvsf94fGOEMEsUHJ1JVo/I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=G1VBP7OM; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="G1VBP7OM" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-4230366ad7bso45209145e9.1 for ; Mon, 24 Jun 2024 02:55:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719222952; x=1719827752; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BWSZpdRr8ss4XLyazOufDG/vY72XV8sVtx2q8BwJKKk=; b=G1VBP7OMwVOXsBvjqLGpB82T8zReUF+XOGwBv8SQGv1nvudyt6QIVZVvNA/ZXavuVx X107fAcTk0EvSmqju5WK1fc0VGiwNZSAovC3rIcztg/Uka0pjUZlngEJUoVKqIdMPGnb LxXEqS6kuXUoZnbGzS4TEFIBhhF68hUuqIdlXRZG+bjjWoc4Jo1Acaur9a5zBMii24yQ XdMgG13MMb4OrNeXHs2rus2d+N2WElKNJvZ/GMJcKBHnGtu+bvmQ0Vw/zw/ge9X5XEaa tRMwSJuS5N1FpyZwyWbTbXWshgIYQxAyH3SNGakV2yBb2nK1nWJStOsqKL5OBnDtioSV REJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719222952; x=1719827752; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BWSZpdRr8ss4XLyazOufDG/vY72XV8sVtx2q8BwJKKk=; b=vuoFOFAJNLlCiSMRGdRg+Zw7EaSII3fk7z6bDUFf7bzrfpqsCy5sBdcaNj3x24DkBC TQ6icjMavH8JEg3EpODDDoJN48fKCygwpWyPg21warL+oDRPuaSiwUR8xz5stpmB0uE/ k61je5IA1yiCSJpogppWo8IrPPMgc+t88iCmz6MZnES8jt8WpX7aSI0UDl+t5wfaMIfk XsixG/pEvFxCtDhDOF4GcxbI2vBkAI7he8HOQgRJ1qQzg066hxlHA8aNa0B5XD/frezB 0aA/7nFNN+kXUzPTkEWyCecC/Av/bwBngbRBAkLDKsCcnwKtQ2/4JtbHZV0NQ26YcCfe Xxlg== X-Gm-Message-State: AOJu0YzRCeAa3JNH7FCSoUMelbdP2y51QTYS6El+SE/95OsFrmOwsP/k 1JJq+pLyxPYeOWWYE/jCYGHC7KVaXN9PRS3wYj6N1ksjY6WcOhfrQ7A5DiA= X-Google-Smtp-Source: AGHT+IHXUjt9Y5vlhETtbvvTRlRHKEPz55bQup5bs9zUkv2VppJJ2Rb7Zb+OUOTf8pMoWmlbYnmLAg== X-Received: by 2002:a05:600c:791:b0:422:683b:df31 with SMTP id 5b1f17b1804b1-4248cc1792emr34071925e9.7.1719222952116; Mon, 24 Jun 2024 02:55:52 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.55.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:55:51 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com, Hans Verkuil Subject: [PATCH 05/10] media: vivid: vidioc_g_edid: do not change the original input EDID Date: Mon, 24 Jun 2024 12:52:58 +0300 Message-Id: <20240624095300.745567-6-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Hans Verkuil Returning an EDID for a connected output would modify the original input EDID with the physical address of the output. That causes problems, and it should just update the physical address of the output EDID. Update vivid_hdmi_edid to set the physical address to 0.0.0.0. Signed-off-by: Hans Verkuil --- drivers/media/test-drivers/vivid/vivid-core.c | 4 ++-- .../test-drivers/vivid/vivid-vid-common.c | 22 +++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c index 0273bc9863b0..4a9d9b30aa42 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.c +++ b/drivers/media/test-drivers/vivid/vivid-core.c @@ -218,7 +218,7 @@ static const u8 vivid_hdmi_edid[256] = { 0x5e, 0x5d, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21, 0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03, - 0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4, 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3, 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d, @@ -229,7 +229,7 @@ static const u8 vivid_hdmi_edid[256] = { 0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51, 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, }; static int vidioc_querycap(struct file *file, void *priv, diff --git a/drivers/media/test-drivers/vivid/vivid-vid-common.c b/drivers/media/test-drivers/vivid/vivid-vid-common.c index 38d788b5cf19..a3e8eb90f11b 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-common.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-common.c @@ -1038,6 +1038,7 @@ int vidioc_g_edid(struct file *file, void *_fh, struct vivid_dev *dev = video_drvdata(file); struct video_device *vdev = video_devdata(file); struct cec_adapter *adap; + unsigned int loc; memset(edid->reserved, 0, sizeof(edid->reserved)); if (vdev->vfl_dir == VFL_DIR_RX) { @@ -1068,8 +1069,25 @@ int vidioc_g_edid(struct file *file, void *_fh, return -EINVAL; if (edid->blocks > dev->edid_blocks - edid->start_block) edid->blocks = dev->edid_blocks - edid->start_block; - if (adap) - v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); + memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128); + + loc = cec_get_edid_spa_location(dev->edid, dev->edid_blocks * 128); + if (vdev->vfl_dir == VFL_DIR_TX && adap && loc && + loc >= edid->start_block * 128 && + loc < (edid->start_block + edid->blocks) * 128) { + unsigned int i; + u8 sum = 0; + + loc -= edid->start_block * 128; + edid->edid[loc] = adap->phys_addr >> 8; + edid->edid[loc + 1] = adap->phys_addr & 0xff; + loc &= ~0x7f; + + /* update the checksum */ + for (i = loc; i < loc + 127; i++) + sum += edid->edid[i]; + edid->edid[i] = 256 - sum; + } return 0; } From patchwork Mon Jun 24 09:52:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709258 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2F39F13248E for ; Mon, 24 Jun 2024 09:56:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222963; cv=none; b=XK9q5aMIbfU+5/9GNwEmkLjuRbNJXhIOimpAvUUYpnSMmPF62jYb20IA0mmQlB40DgB5X0ztmAtLppgJ00EGNQITpW4fybSPoRLAgTOFFm/v/79VJAAXb3xKMT1Dlx7PSvvK1fdyWxcBoHhBNYbYRt9150knU8IaOjRDiLokgc0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222963; c=relaxed/simple; bh=Z+ybKs8LSEAIG6A+4bC/ShBudIgAMGPcBSsJSKdVzts=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oSewQC8/JlNAMWd9cSpP5KmJUzsuSB6kKu4xeXmoBSZPXXAsjBZZ3fkfek7HT23t8/66ChxDC0KDxzTuc8YX5+BrOq0A3cILGQeeGFtv330BLjrj6MZeGxtjy8m3d9IyWB+gGaf2A0RKJLJFC9ew8bIcGKSTgQH7YONW0kTp960= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=aAuL2nim; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="aAuL2nim" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-421757d217aso45140735e9.3 for ; Mon, 24 Jun 2024 02:56:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719222960; x=1719827760; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7EEqxuVwryGkI9e6OWNQevVQjBpVhdVGw/fICJinrH4=; b=aAuL2nimrCPKE97PN0OIVu958FH2a/oznAbRoj1xfBXn30GVyemgLL+TF3tyh9fijT W48wkcBcsVoVPy52e1DsmuD10Jv6bwGsFAWXPrax7tDDOzY5WeYxC3ZG9IO5wipjLhy3 P2nP2/rJtqW+iWvwntDSglJSwCpf68bBYYTXhIkzOC/eiEgFjA/gUHKPCS7Uq075MhSz KC7e2Pq7PH6XRYDFJlV5/Foua4E9Yk/BgA8PKOvhr6ogIGQQbAXxBsvsLaeTMY4YhQOE v+/PNg9Ufph3FkFVl/DGiIaoPtuc/NhpOG4quZo29gdrrZZ+61OQpsJ76ijCAg1W0aYN 7CKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719222960; x=1719827760; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7EEqxuVwryGkI9e6OWNQevVQjBpVhdVGw/fICJinrH4=; b=tPYnXcCIjj/uCVzvbkqaimmcw7owkch6U0K8KZL2ArgDANhOSNjdMKVWXxJEI5C/6b TMxLaUDeaLVXfDmunB54aIHf+i/YqISXTdKWjyN/tqMoiuQB+T6aOQNw3keHEimToXRh av1Mg25bn3Ro8zcAMGbEWuUvOt1NRkQIyGYnixmd2cRW3kezltZaSuvklB1YKyI9WCsh rn+rnNf2vGFn7KIJrnCwm8fTSIMtcBW8CfbELzHmP9h9WJ65ChTI/+gykkPN20HZvOSX HkZ9KSRMWp8anhiOl7glIzt339/4+16qvA10iabjYxAKrGEtGkuHyBjJ2VtsxFpK6ziW SpwQ== X-Gm-Message-State: AOJu0YyN8R6j2m4h7R5pB349pk3/np8EJD8QAZWIywbzNt0u5yQJhqwD SEcMrFa+qIFqPS2duG0G5Yy3a7kdxtlbVqNL+q+Jav8f3E7PX94UJwNF0qU= X-Google-Smtp-Source: AGHT+IFeYfGx9dY1+Y4lwz701h3lzH3qMQaL8/luX72kzAtXfnk2rxIu6sXEAbyPs1mVaUKkPO9kbw== X-Received: by 2002:a05:600c:3c90:b0:424:90f4:309d with SMTP id 5b1f17b1804b1-42490f430dbmr23751625e9.8.1719222960271; Mon, 24 Jun 2024 02:56:00 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.55.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:56:00 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com, Hans Verkuil Subject: [PATCH 06/10] media: vivid: don't set HDMI TX controls if there are no HDMI outputs Date: Mon, 24 Jun 2024 12:52:59 +0300 Message-Id: <20240624095300.745567-7-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Hans Verkuil When setting the EDID it would attempt to update two controls that are only present if there is an HDMI output configured. If there isn't any (e.g. when the vivid module is loaded with node_types=1), then calling VIDIOC_S_EDID would crash. Fix this by first checking if outputs are present. Signed-off-by: Hans Verkuil --- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c index 2804975fe278..de4cb85e397f 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c @@ -1553,8 +1553,10 @@ int vidioc_s_edid(struct file *file, void *_fh, return -EINVAL; if (edid->blocks == 0) { dev->edid_blocks = 0; - v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0); - v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0); + if (dev->num_outputs) { + v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0); + v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0); + } phys_addr = CEC_PHYS_ADDR_INVALID; goto set_phys_addr; } @@ -1578,8 +1580,10 @@ int vidioc_s_edid(struct file *file, void *_fh, display_present |= dev->display_present[i] << j++; - v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present); - v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present); + if (dev->num_outputs) { + v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present); + v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present); + } set_phys_addr: /* TODO: a proper hotplug detect cycle should be emulated here */ From patchwork Mon Jun 24 09:53:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709259 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 793FA13248E for ; Mon, 24 Jun 2024 09:56:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222969; cv=none; b=i1LOux8sMCpmn16Jpb8jgxErigj96N31K8cZS9Tylf0bQg6Diov0j5/WTG4jYiM1UWGpDLGa7935iBfVrFGmhHVfRQKagk7Jb+3DRkvc4mUax1t8P5dowfiOgHT/s61qvbzcGGUsmI+RZNxD8Mg0CHmsjZ4RHTSKaIXuDzamX4M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222969; c=relaxed/simple; bh=qmHKEKDnN45JhCq/y1mfhsYJUYs57zV4/K11uePgzR8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tiU+/R5y/3vIn+Os4d4xcwdj9IM4ngVmZgJUzFdvW/UwCYILuwWFCEHbfSW1BCcqhMVf1it93gj8Zs43YNZHMI4LbOlrDqZcU4zQr1oZoWjVORLGaBqqv/0/13GJqybCZHOYqMTVjzCLdzl9XSW8yo2TQA77/sCC3aQG+VaMVhU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OV1kVDJ5; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OV1kVDJ5" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-421757d217aso45141465e9.3 for ; Mon, 24 Jun 2024 02:56:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719222966; x=1719827766; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kLiiebCYn2vPGhf2nnjMbWinX/JVBJIu6bSK5TOGy64=; b=OV1kVDJ5ThQHRp5zV5/7XeuwqL2G+xI7aMl/fqM+6SBlammUhILw7rX8BzdQIF2kz4 n2ZlxV0g5PG7/ssG7zkDIsGmcWvwgghB6Ag8duAH0qdzZ/dW22mLnweeDlj3bIlY8V9L bwLftYu5EzNxS8T13H2J/MhUlFHw5KBiBdf/Bg7fpyJXYl/ftsWCNcBuWyYuBdGb5IEF N+JhCOJh2RG6SVW40ELRPyzI+ihzZAfxvotQMOW6L6fvQw9p0vKxehGtSplyemOgYVnO zDvYUJoXUDoFOG+8KWCPV5kh0Pb83quoSTy2oIPFOg0W6Q3jebOlEEBYDibFjEd/blVt Wc9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719222966; x=1719827766; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kLiiebCYn2vPGhf2nnjMbWinX/JVBJIu6bSK5TOGy64=; b=q7v92vmk8Yf0BEwGj0Hu/hjXUsVbF9vu28ZKzxCcLzVj55UIZofRfCY1GZJCz1RZfP j0xAL8OHboHVxQ/EX5S4usbjcYSYww/8KrqyWmqZchKXxPoo7WsSyk5nk/KYk5IvOw3s CQ3qGBo/tnsQ5tJlDmlJ/XgppTTsbhHV9yVqiVmIl5vIUAu7G9zTgLQNiNqerIyfkChJ Od8IrMqjTdYLhqvpBCqtySnCU/+sP7vJ1HOwBW7rYVhItehjOVLbxdMU0fc804qVubIC cSES4qzvwNWeALvIWF9xFXTZeHD8gwxlMAD3tn0KkGSKNVrU4GS3Rh6glHZMbeTVF119 BI3A== X-Gm-Message-State: AOJu0YxGaWpPdQj+a2kFuCxR57Ltr/YooI/IcATnEfjMH5mg0PXOHvyb B3T1n0dHyz/rVyEYf+2Goh/6iz2xDs3rVTz6X6qMAU8bAD6Z+yPGj8TW2vY= X-Google-Smtp-Source: AGHT+IH6L5gbSEKxI57b1KxuVDcZO4s7as7lcAJsCLgTmyB+XwJHs067PgIS7+rGWox6aOlnsCcRkw== X-Received: by 2002:a05:600c:470d:b0:424:784c:b134 with SMTP id 5b1f17b1804b1-4248cc17964mr36730135e9.6.1719222965752; Mon, 24 Jun 2024 02:56:05 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.56.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:56:05 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com, Hans Verkuil Subject: [PATCH 07/10] media: vivid: add instance number to input/output names Date: Mon, 24 Jun 2024 12:53:00 +0300 Message-Id: <20240624095300.745567-8-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Hans Verkuil Add the instance number before the input or output number. So "HDMI 1" becomes "HDMI 000-1". This is helps identifying which input or output belongs to which vivid instance. Signed-off-by: Hans Verkuil --- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 16 ++++++++-------- drivers/media/test-drivers/vivid/vivid-vid-out.c | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c index de4cb85e397f..fcbef8b58127 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c @@ -1072,13 +1072,13 @@ int vidioc_enum_input(struct file *file, void *priv, inp->type = V4L2_INPUT_TYPE_CAMERA; switch (dev->input_type[inp->index]) { case WEBCAM: - snprintf(inp->name, sizeof(inp->name), "Webcam %u", - dev->input_name_counter[inp->index]); + snprintf(inp->name, sizeof(inp->name), "Webcam %03u-%u", + dev->inst, dev->input_name_counter[inp->index]); inp->capabilities = 0; break; case TV: - snprintf(inp->name, sizeof(inp->name), "TV %u", - dev->input_name_counter[inp->index]); + snprintf(inp->name, sizeof(inp->name), "TV %03u-%u", + dev->inst, dev->input_name_counter[inp->index]); inp->type = V4L2_INPUT_TYPE_TUNER; inp->std = V4L2_STD_ALL; if (dev->has_audio_inputs) @@ -1086,16 +1086,16 @@ int vidioc_enum_input(struct file *file, void *priv, inp->capabilities = V4L2_IN_CAP_STD; break; case SVID: - snprintf(inp->name, sizeof(inp->name), "S-Video %u", - dev->input_name_counter[inp->index]); + snprintf(inp->name, sizeof(inp->name), "S-Video %03u-%u", + dev->inst, dev->input_name_counter[inp->index]); inp->std = V4L2_STD_ALL; if (dev->has_audio_inputs) inp->audioset = (1 << ARRAY_SIZE(vivid_audio_inputs)) - 1; inp->capabilities = V4L2_IN_CAP_STD; break; case HDMI: - snprintf(inp->name, sizeof(inp->name), "HDMI %u", - dev->input_name_counter[inp->index]); + snprintf(inp->name, sizeof(inp->name), "HDMI %03u-%u", + dev->inst, dev->input_name_counter[inp->index]); inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; if (dev->edid_blocks == 0 || dev->dv_timings_signal_mode[dev->input] == NO_SIGNAL) diff --git a/drivers/media/test-drivers/vivid/vivid-vid-out.c b/drivers/media/test-drivers/vivid/vivid-vid-out.c index 1653b2988f7e..a299b872c05a 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-out.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-out.c @@ -964,16 +964,16 @@ int vidioc_enum_output(struct file *file, void *priv, out->type = V4L2_OUTPUT_TYPE_ANALOG; switch (dev->output_type[out->index]) { case SVID: - snprintf(out->name, sizeof(out->name), "S-Video %u", - dev->output_name_counter[out->index]); + snprintf(out->name, sizeof(out->name), "S-Video %03u-%u", + dev->inst, dev->output_name_counter[out->index]); out->std = V4L2_STD_ALL; if (dev->has_audio_outputs) out->audioset = (1 << ARRAY_SIZE(vivid_audio_outputs)) - 1; out->capabilities = V4L2_OUT_CAP_STD; break; case HDMI: - snprintf(out->name, sizeof(out->name), "HDMI %u", - dev->output_name_counter[out->index]); + snprintf(out->name, sizeof(out->name), "HDMI %03u-%u", + dev->inst, dev->output_name_counter[out->index]); out->capabilities = V4L2_OUT_CAP_DV_TIMINGS; break; } From patchwork Mon Jun 24 09:53:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709260 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 960F413248E for ; Mon, 24 Jun 2024 09:56:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222985; cv=none; b=ZrczOIyx2cVw6UemEMk8qIyBnsyUfECUd4u5H8Zz+SSKDHu5UCytLFEKOV7hcoYPwrl4i0e0Na3UKFGOz3HHtV3onl7gNl19qXDnBORjLhytX4BNYpb3VuQO54qooFf24u8uMRtlNIw4pLlHK4m7Ba4AB5uolOIV5CfsinGXfOc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719222985; c=relaxed/simple; bh=ZbxkaXUjkoKEBQIHe7O84lbuiaoG7L3RP7sepkCl9so=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=V7fHwxmFQdctauarkOUbVTaBysCSzbu35LpdSfnKIUA9XLQsoR3GYHzF3YnPFGurvPc+5GXVubJVtHJ2hpD/7x+TOHgV/0tK4xoBpijGR1q3UXsAA/vDXkCzgGGHT+daff7e9hQsOEaEhar/lYntlUJsaJ0WOkE9Oc9QjHcUjts= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Sc9fgr+U; arc=none smtp.client-ip=209.85.128.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Sc9fgr+U" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-4217136a74dso33424075e9.2 for ; Mon, 24 Jun 2024 02:56:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719222982; x=1719827782; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=L90fFcZUTsPRJLMIQLbMgoHBhy3pX5pcNxZhWtqHv0w=; b=Sc9fgr+USvpij/NztAmBKfsoVSHof+EJ3XoV1fPB1WZEA24IE0QhKBKfFSkP1a3Kg0 +ECililUXwy/0gYY5Mb0bXJJfNH0JZrg74xfAV8a561e8rfJdrBLshf2S+PMqxqERI6F EaCj9eCsWj0xeotuadg7pWtUO82i9AUwwOCha5YvUZ7fskp+clmXA1an/trDVjwpYeAr oKJ5DVmTJ4MR5krQIbNQJjgjrAa9hsEjWxU8Xn7jRDPPaucLNV0RVK2a+VyWaW0XAMaV 5b6co1blXrG8sofWKbmkZYMdr10nogfqaHu6xHQqYtbXMFR72NXKx/FMuMnmqchH2tHC oGig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719222982; x=1719827782; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=L90fFcZUTsPRJLMIQLbMgoHBhy3pX5pcNxZhWtqHv0w=; b=JZG9FMOg7WBNgaYOi0TNRRi7nqTpiE37mImEbB0L7DHFWeiaqz4j317aw8dg4N604U OsA6t8vBIfnmBB5C9k38v+E1+Az1UhjTTPen4YqwVHH1Kh3kXgCXy067MH0oX7UYLVYv Hirm96ify2u+xbOrkxZwMDEyfWqCnhlJmc9+vRPRExIUwYzvBa4/Ey8KbXHuBKMHTrFX ubAbqhOV26gwxAds3cOHxq4zTOoTeKOVgFm0k7o7SGWeZSoqr+S3QArerVOIXj1S4pEP 4dxBNwku1HcvLvx3TnUqLoG7rtGBE/D5NOKE1lHXidxTZ2I10vB3VggDeYckqWH1soFR npaA== X-Gm-Message-State: AOJu0Yy/omE2etSLR09P/4ez807rZv4b0B7Wce0R6rlAHxKkWWA9PJlk 0+9ySF0z/OyWPkkTaonA3RZMSddmcZWAcPs5RVcDqp8Dyd2+1AY6HMtEx7s= X-Google-Smtp-Source: AGHT+IEQMkZ62smg5rNTkfph1O56O3HHjnuRbzt+EaxEfIthxYqXfUP/xaHfXD1TYKgEwP6uVlhYYA== X-Received: by 2002:a05:600c:3501:b0:424:8ff8:b12e with SMTP id 5b1f17b1804b1-4248ff8b1b6mr19497965e9.11.1719222981652; Mon, 24 Jun 2024 02:56:21 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.56.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:56:21 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com, Hans Verkuil Subject: [PATCH 08/10] media: vivid: Add 'Is Connected To' menu controls Date: Mon, 24 Jun 2024 12:53:02 +0300 Message-Id: <20240624095300.745567-9-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The video loopback functionality in vivid is very crude. What we really want is to be able to emulate connecting an HDMI or S-Video input to an HDMI or S-Video output, and the input and output can be in different vivid instances. Effectively this emulates what happens when you physically connect an HDMI or S-Video cable between two devices. In particular, this makes prototyping with vivid much more realistic. This patch creates a menu control for each HDMI or S-Video input. The menu control starts with "Test Pattern Generator" and "None" (i.e. disconnected). After that up to 62 HDMI or S-Video outputs are listed that you can connect the input to. If there are more than 62 HDMI or S-Video outputs, then those will not be included in the menu (currently menucontrols have max 64 entries). If an input is connected to an output, then all other 'Connected To' controls are updated to exclude that output to avoid having multiple inputs connected to the same output. Signed-off-by: Dorcas Anono Litunya Signed-off-by: Hans Verkuil --- drivers/media/test-drivers/vivid/vivid-core.c | 207 +++++++++++++++++- drivers/media/test-drivers/vivid/vivid-core.h | 109 ++++++++- .../media/test-drivers/vivid/vivid-ctrls.c | 102 +++++++++ 3 files changed, 401 insertions(+), 17 deletions(-) diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c index 4a9d9b30aa42..7eb8a0a5d4d3 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.c +++ b/drivers/media/test-drivers/vivid/vivid-core.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only + /* * vivid-core.c - A Virtual Video Test Driver, core initialization * @@ -42,15 +43,13 @@ #include "vivid-touch-cap.h" #define VIVID_MODULE_NAME "vivid" - -/* The maximum number of vivid devices */ -#define VIVID_MAX_DEVS CONFIG_VIDEO_VIVID_MAX_DEVS +#define MAX_STRING_LENGTH 23 MODULE_DESCRIPTION("Virtual Video Test Driver"); MODULE_AUTHOR("Hans Verkuil"); MODULE_LICENSE("GPL"); -static unsigned n_devs = 1; +unsigned int n_devs = 1; module_param(n_devs, uint, 0444); MODULE_PARM_DESC(n_devs, " number of driver instances to create"); @@ -186,7 +185,31 @@ MODULE_PARM_DESC(supports_requests, " support for requests, default is 1.\n" "\t\t 1 == supports requests\n" "\t\t 2 == requires requests"); -static struct vivid_dev *vivid_devs[VIVID_MAX_DEVS]; +struct vivid_dev *vivid_devs[VIVID_MAX_DEVS]; + +DEFINE_SPINLOCK(hdmi_output_skip_mask_lock); +struct workqueue_struct *update_hdmi_ctrls_workqueue; +u64 hdmi_to_output_menu_skip_mask; + +struct vivid_dev *vivid_ctrl_hdmi_to_output_instance[MAX_MENU_ITEMS]; +unsigned int vivid_ctrl_hdmi_to_output_index[MAX_MENU_ITEMS]; + +char *vivid_ctrl_hdmi_to_output_strings[MAX_MENU_ITEMS + 1] = { + "Test Pattern Generator", + "None" +}; + +DEFINE_SPINLOCK(svid_output_skip_mask_lock); +struct workqueue_struct *update_svid_ctrls_workqueue; +u64 svid_to_output_menu_skip_mask; + +struct vivid_dev *vivid_ctrl_svid_to_output_instance[MAX_MENU_ITEMS]; +unsigned int vivid_ctrl_svid_to_output_index[MAX_MENU_ITEMS]; + +char *vivid_ctrl_svid_to_output_strings[MAX_MENU_ITEMS + 1] = { + "Test Pattern Generator", + "None" +}; const struct v4l2_rect vivid_min_rect = { 0, 0, MIN_WIDTH, MIN_HEIGHT @@ -827,6 +850,7 @@ static void vivid_dev_release(struct v4l2_device *v4l2_dev) { struct vivid_dev *dev = container_of(v4l2_dev, struct vivid_dev, v4l2_dev); + cancel_work_sync(&dev->update_hdmi_ctrl_work); vivid_free_controls(dev); v4l2_device_unregister(&dev->v4l2_dev); #ifdef CONFIG_MEDIA_CONTROLLER @@ -946,6 +970,7 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst, dev->num_inputs--; } dev->num_hdmi_inputs = in_type_counter[HDMI]; + dev->num_svid_inputs = in_type_counter[SVID]; /* how many outputs do we have and of what type? */ dev->num_outputs = num_outputs[inst]; @@ -1734,6 +1759,42 @@ static int vivid_create_devnodes(struct platform_device *pdev, return 0; } +static void update_hdmi_ctrls_work_handler(struct work_struct *work) +{ + u64 skip_mask; + + spin_lock(&hdmi_output_skip_mask_lock); + skip_mask = hdmi_to_output_menu_skip_mask; + spin_unlock(&hdmi_output_skip_mask_lock); + for (int i = 0; i < n_devs && vivid_devs[i]; i++) { + for (int j = 0; j < vivid_devs[i]->num_hdmi_inputs; j++) { + struct v4l2_ctrl *c = vivid_devs[i]->ctrl_hdmi_to_output[j]; + + v4l2_ctrl_modify_range(c, c->minimum, c->maximum, + skip_mask & ~(1ULL << c->cur.val), + c->default_value); + } + } +} + +static void update_svid_ctrls_work_handler(struct work_struct *work) +{ + u64 skip_mask; + + spin_lock(&svid_output_skip_mask_lock); + skip_mask = svid_to_output_menu_skip_mask; + spin_unlock(&svid_output_skip_mask_lock); + for (int i = 0; i < n_devs && vivid_devs[i]; i++) { + for (int j = 0; j < vivid_devs[i]->num_svid_inputs; j++) { + struct v4l2_ctrl *c = vivid_devs[i]->ctrl_svid_to_output[j]; + + v4l2_ctrl_modify_range(c, c->minimum, c->maximum, + skip_mask & ~(1ULL << c->cur.val), + c->default_value); + } + } +} + static int vivid_create_instance(struct platform_device *pdev, int inst) { static const struct v4l2_dv_timings def_dv_timings = @@ -1850,6 +1911,22 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) dev->edid_max_blocks = dev->edid_blocks = 2; memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid)); dev->radio_rds_init_time = ktime_get(); + INIT_WORK(&dev->update_hdmi_ctrl_work, update_hdmi_ctrls_work_handler); + INIT_WORK(&dev->update_svid_ctrl_work, update_svid_ctrls_work_handler); + for (int j = 0, k = 0; j < dev->num_inputs; ++j) + if (dev->input_type[j] == HDMI) + dev->hdmi_index_to_input_index[k++] = j; + for (int j = 0, k = 0; j < dev->num_outputs; ++j) + if (dev->output_type[j] == HDMI) { + dev->output_to_iface_index[j] = k; + dev->hdmi_index_to_output_index[k++] = j; + } + for (int j = 0, k = 0; j < dev->num_inputs; ++j) + if (dev->input_type[j] == SVID) + dev->svid_index_to_input_index[k++] = j; + for (int j = 0, k = 0; j < dev->num_outputs; ++j) + if (dev->output_type[j] == SVID) + dev->output_to_iface_index[j] = k++; /* create all controls */ ret = vivid_create_controls(dev, ccs_cap == -1, ccs_out == -1, no_error_inj, @@ -1986,7 +2063,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) vb2_video_unregister_device(&dev->vid_out_dev); vb2_video_unregister_device(&dev->vid_cap_dev); cec_unregister_adapter(dev->cec_rx_adap); - for (i = 0; i < MAX_OUTPUTS; i++) + for (i = 0; i < MAX_HDMI_OUTPUTS; i++) cec_unregister_adapter(dev->cec_tx_adap[i]); if (dev->kthread_cec) kthread_stop(dev->kthread_cec); @@ -2033,6 +2110,42 @@ static int vivid_probe(struct platform_device *pdev) /* n_devs will reflect the actual number of allocated devices */ n_devs = i; + /* Determine qmenu items actually in use */ + int hdmi_count = FIXED_MENU_ITEMS; + int svid_count = FIXED_MENU_ITEMS; + + for (int i = 0; i < n_devs; i++) { + struct vivid_dev *dev = vivid_devs[i]; + + if (!dev->has_vid_out) + continue; + for (int j = 0; j < dev->num_outputs && hdmi_count < MAX_MENU_ITEMS; ++j) { + if (dev->output_type[j] == HDMI) { + vivid_ctrl_hdmi_to_output_instance[hdmi_count] = vivid_devs[i]; + vivid_ctrl_hdmi_to_output_index[hdmi_count++] = j; + } + } + for (int j = 0; j < dev->num_outputs && svid_count < MAX_MENU_ITEMS; ++j) { + if (dev->output_type[j] == SVID) { + vivid_ctrl_svid_to_output_instance[svid_count] = vivid_devs[i]; + vivid_ctrl_svid_to_output_index[svid_count++] = j; + } + } + } + hdmi_count = min(hdmi_count, MAX_MENU_ITEMS); + svid_count = min(svid_count, MAX_MENU_ITEMS); + for (int i = 0; i < n_devs; i++) { + for (int j = 0; j < vivid_devs[i]->num_hdmi_inputs; j++) { + struct v4l2_ctrl *c = vivid_devs[i]->ctrl_hdmi_to_output[j]; + + v4l2_ctrl_modify_range(c, c->minimum, hdmi_count - 1, 0, c->default_value); + } + for (int j = 0; j < vivid_devs[i]->num_svid_inputs; j++) { + struct v4l2_ctrl *c = vivid_devs[i]->ctrl_svid_to_output[j]; + + v4l2_ctrl_modify_range(c, c->minimum, svid_count - 1, 0, c->default_value); + } + } return ret; } @@ -2109,7 +2222,7 @@ static void vivid_remove(struct platform_device *pdev) vb2_video_unregister_device(&dev->touch_cap_dev); } cec_unregister_adapter(dev->cec_rx_adap); - for (j = 0; j < MAX_OUTPUTS; j++) + for (j = 0; j < MAX_HDMI_OUTPUTS; j++) cec_unregister_adapter(dev->cec_tx_adap[j]); if (dev->kthread_cec) kthread_stop(dev->kthread_cec); @@ -2137,21 +2250,91 @@ static struct platform_driver vivid_pdrv = { static int __init vivid_init(void) { - int ret; - + int hdmi_count = FIXED_MENU_ITEMS; + int svid_count = FIXED_MENU_ITEMS; + int ret = -ENOMEM; + unsigned int ndevs; + + /* Sanity check, prevent insane number of vivid instances */ + if (n_devs > 64) + n_devs = 64; + ndevs = clamp_t(unsigned int, n_devs, 1, VIVID_MAX_DEVS); + + for (unsigned int i = 0; i < ndevs; i++) { + if (!(node_types[i] & (1 << 8))) + continue; + unsigned int n_outputs = min(num_outputs[i], MAX_OUTPUTS); + + for (u8 j = 0, k = 0; j < n_outputs && hdmi_count < MAX_MENU_ITEMS && + k < MAX_HDMI_OUTPUTS; ++j) { + if (output_types[i] & BIT(j)) { + vivid_ctrl_hdmi_to_output_strings[hdmi_count] = + kmalloc(MAX_STRING_LENGTH, GFP_KERNEL); + if (!vivid_ctrl_hdmi_to_output_strings[hdmi_count]) + goto free_output_strings; + snprintf(vivid_ctrl_hdmi_to_output_strings[hdmi_count], + MAX_STRING_LENGTH, "Output HDMI %03d-%d", + i & 0xff, k); + k++; + hdmi_count++; + } + } + for (u8 j = 0, k = 0; j < n_outputs && svid_count < MAX_MENU_ITEMS; ++j) { + if (!(output_types[i] & BIT(j))) { + vivid_ctrl_svid_to_output_strings[svid_count] = + kmalloc(MAX_STRING_LENGTH, GFP_KERNEL); + if (!vivid_ctrl_svid_to_output_strings[svid_count]) + goto free_output_strings; + snprintf(vivid_ctrl_svid_to_output_strings[svid_count], + MAX_STRING_LENGTH, "Output S-Video %03d-%d", + i & 0xff, k); + k++; + svid_count++; + } + } + } ret = platform_device_register(&vivid_pdev); if (ret) - return ret; - + goto free_output_strings; ret = platform_driver_register(&vivid_pdrv); if (ret) - platform_device_unregister(&vivid_pdev); + goto unreg_device; + + /* Initialize workqueue before module is loaded */ + update_hdmi_ctrls_workqueue = create_workqueue("update_hdmi_ctrls_wq"); + if (!update_hdmi_ctrls_workqueue) { + ret = -ENOMEM; + goto unreg_driver; + } + update_svid_ctrls_workqueue = create_workqueue("update_svid_ctrls_wq"); + if (!update_svid_ctrls_workqueue) { + ret = -ENOMEM; + goto destroy_hdmi_wq; + } + return ret; +destroy_hdmi_wq: + destroy_workqueue(update_hdmi_ctrls_workqueue); +unreg_driver: + platform_driver_register(&vivid_pdrv); +unreg_device: + platform_device_unregister(&vivid_pdev); +free_output_strings: + for (int i = FIXED_MENU_ITEMS; i < MAX_MENU_ITEMS; i++) { + kfree(vivid_ctrl_hdmi_to_output_strings[i]); + kfree(vivid_ctrl_svid_to_output_strings[i]); + } return ret; } static void __exit vivid_exit(void) { + for (int i = FIXED_MENU_ITEMS; i < MAX_MENU_ITEMS; i++) { + kfree(vivid_ctrl_hdmi_to_output_strings[i]); + kfree(vivid_ctrl_svid_to_output_strings[i]); + } + destroy_workqueue(update_svid_ctrls_workqueue); + destroy_workqueue(update_hdmi_ctrls_workqueue); platform_driver_unregister(&vivid_pdrv); platform_device_unregister(&vivid_pdev); } diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h index cfb8e66083f6..b0c5b7369de5 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.h +++ b/drivers/media/test-drivers/vivid/vivid-core.h @@ -50,10 +50,87 @@ #define JIFFIES_PER_DAY (3600U * 24U * HZ) #define JIFFIES_RESYNC (JIFFIES_PER_DAY * (0xf0000000U / JIFFIES_PER_DAY)) +/* + * Maximum number of HDMI inputs allowed by vivid, due to limitations + * of the Physical Address in the EDID and used by CEC we stop at 15 + * inputs and outputs. + */ +#define MAX_HDMI_INPUTS 15 +#define MAX_HDMI_OUTPUTS 15 + +/* Maximum number of S-Video inputs allowed by vivid */ +#define MAX_SVID_INPUTS 16 + +/* The maximum number of items in a menu control */ +#define MAX_MENU_ITEMS BITS_PER_LONG_LONG + +/* Number of fixed menu items in the 'Connected To' menu controls */ +#define FIXED_MENU_ITEMS 2 + +/* The maximum number of vivid devices */ +#define VIVID_MAX_DEVS CONFIG_VIDEO_VIVID_MAX_DEVS + extern const struct v4l2_rect vivid_min_rect; extern const struct v4l2_rect vivid_max_rect; extern unsigned vivid_debug; +/* + * NULL-terminated string array for the HDMI 'Connected To' menu controls + * with the list of possible HDMI outputs. + * + * The first two items are fixed ("TPG" and "None"). + */ +extern char *vivid_ctrl_hdmi_to_output_strings[1 + MAX_MENU_ITEMS]; +/* Menu control skip mask of all HDMI outputs that are in use */ +extern u64 hdmi_to_output_menu_skip_mask; +/* Spinlock for access to hdmi_to_output_menu_skip_mask */ +extern spinlock_t hdmi_output_skip_mask_lock; +/* + * Workqueue that updates the menu controls whenever the HDMI menu skip mask + * changes. + */ +extern struct workqueue_struct *update_hdmi_ctrls_workqueue; + +/* + * The HDMI menu control value (index in the menu list) maps to an HDMI + * output that is part of the given vivid_dev instance and has the given + * output index (as returned by VIDIOC_G_OUTPUT). + * + * NULL/0 if not available. + */ +extern struct vivid_dev *vivid_ctrl_hdmi_to_output_instance[MAX_MENU_ITEMS]; +extern unsigned int vivid_ctrl_hdmi_to_output_index[MAX_MENU_ITEMS]; + +/* + * NULL-terminated string array for the S-Video 'Connected To' menu controls + * with the list of possible S-Video outputs. + * + * The first two items are fixed ("TPG" and "None"). + */ +extern char *vivid_ctrl_svid_to_output_strings[1 + MAX_MENU_ITEMS]; +/* Menu control skip mask of all S-Video outputs that are in use */ +extern u64 svid_to_output_menu_skip_mask; +/* Spinlock for access to svid_to_output_menu_skip_mask */ +extern spinlock_t svid_output_skip_mask_lock; +/* + * Workqueue that updates the menu controls whenever the S-Video menu skip mask + * changes. + */ +extern struct workqueue_struct *update_svid_ctrls_workqueue; + +/* + * The S-Video menu control value (index in the menu list) maps to an S-Video + * output that is part of the given vivid_dev instance and has the given + * output index (as returned by VIDIOC_G_OUTPUT). + * + * NULL/0 if not available. + */ +extern struct vivid_dev *vivid_ctrl_svid_to_output_instance[MAX_MENU_ITEMS]; +extern unsigned int vivid_ctrl_svid_to_output_index[MAX_MENU_ITEMS]; + +extern struct vivid_dev *vivid_devs[VIVID_MAX_DEVS]; +extern unsigned int n_devs; + struct vivid_fmt { u32 fourcc; /* v4l2 format id */ enum tgp_color_enc color_enc; @@ -118,7 +195,7 @@ struct vivid_cec_xfer { }; struct vivid_dev { - unsigned inst; + u8 inst; struct v4l2_device v4l2_dev; #ifdef CONFIG_MEDIA_CONTROLLER struct media_device mdev; @@ -161,6 +238,8 @@ struct vivid_dev { spinlock_t slock; struct mutex mutex; + struct work_struct update_hdmi_ctrl_work; + struct work_struct update_svid_ctrl_work; /* capabilities */ u32 vid_cap_caps; @@ -176,12 +255,13 @@ struct vivid_dev { /* supported features */ bool multiplanar; - unsigned num_inputs; - unsigned int num_hdmi_inputs; + u8 num_inputs; + u8 num_hdmi_inputs; + u8 num_svid_inputs; u8 input_type[MAX_INPUTS]; u8 input_name_counter[MAX_INPUTS]; - unsigned num_outputs; - unsigned int num_hdmi_outputs; + u8 num_outputs; + u8 num_hdmi_outputs; u8 output_type[MAX_OUTPUTS]; u8 output_name_counter[MAX_OUTPUTS]; bool has_audio_inputs; @@ -204,6 +284,20 @@ struct vivid_dev { bool has_touch_cap; bool can_loop_video; + /* Output index (0-MAX_OUTPUTS) to vivid instance of connected input */ + struct vivid_dev *output_to_input_instance[MAX_OUTPUTS]; + /* Output index (0-MAX_OUTPUTS) to input index (0-MAX_INPUTS) of connected input */ + u8 output_to_input_index[MAX_OUTPUTS]; + /* Output index (0-MAX_OUTPUTS) to HDMI or S-Video output index (0-MAX_HDMI/SVID_OUTPUTS) */ + u8 output_to_iface_index[MAX_OUTPUTS]; + /* ctrl_hdmi_to_output or ctrl_svid_to_output control value for each input */ + s32 input_is_connected_to_output[MAX_INPUTS]; + /* HDMI index (0-MAX_HDMI_OUTPUTS) to output index (0-MAX_OUTPUTS) */ + u8 hdmi_index_to_output_index[MAX_HDMI_OUTPUTS]; + /* HDMI index (0-MAX_HDMI_INPUTS) to input index (0-MAX_INPUTS) */ + u8 hdmi_index_to_input_index[MAX_HDMI_INPUTS]; + /* S-Video index (0-MAX_SVID_INPUTS) to input index (0-MAX_INPUTS) */ + u8 svid_index_to_input_index[MAX_SVID_INPUTS]; /* controls */ struct v4l2_ctrl *brightness; @@ -276,6 +370,11 @@ struct vivid_dev { struct v4l2_ctrl *radio_rx_rds_psname; struct v4l2_ctrl *radio_rx_rds_radiotext; + struct v4l2_ctrl *ctrl_hdmi_to_output[MAX_HDMI_INPUTS]; + char ctrl_hdmi_to_output_names[MAX_HDMI_INPUTS][32]; + struct v4l2_ctrl *ctrl_svid_to_output[MAX_SVID_INPUTS]; + char ctrl_svid_to_output_names[MAX_SVID_INPUTS][32]; + unsigned input_brightness[MAX_INPUTS]; unsigned osd_mode; unsigned button_pressed; diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.c b/drivers/media/test-drivers/vivid/vivid-ctrls.c index f2b20e25a7a4..f278bd86e99d 100644 --- a/drivers/media/test-drivers/vivid/vivid-ctrls.c +++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c @@ -104,6 +104,12 @@ #define VIVID_CID_META_CAP_GENERATE_PTS (VIVID_CID_VIVID_BASE + 111) #define VIVID_CID_META_CAP_GENERATE_SCR (VIVID_CID_VIVID_BASE + 112) +/* HDMI inputs are in the range 0-14. The next available CID is VIVID_CID_VIVID_BASE + 128 */ +#define VIVID_CID_HDMI_IS_CONNECTED_TO_OUTPUT(input) (VIVID_CID_VIVID_BASE + 113 + (input)) + +/* S-Video inputs are in the range 0-15. The next available CID is VIVID_CID_VIVID_BASE + 144 */ +#define VIVID_CID_SVID_IS_CONNECTED_TO_OUTPUT(input) (VIVID_CID_VIVID_BASE + 128 + (input)) + /* General User Controls */ static void vivid_unregister_dev(bool valid, struct video_device *vdev) @@ -454,6 +460,10 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) }; struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap); unsigned int i, j; + struct vivid_dev *output_inst = NULL; + int index = 0; + int hdmi_index, svid_index; + s32 input_index = 0; switch (ctrl->id) { case VIVID_CID_TEST_PATTERN: @@ -604,6 +614,56 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) if (dev->edid_blocks > dev->edid_max_blocks) dev->edid_blocks = dev->edid_max_blocks; break; + case VIVID_CID_HDMI_IS_CONNECTED_TO_OUTPUT(0) ... VIVID_CID_HDMI_IS_CONNECTED_TO_OUTPUT(14): + hdmi_index = ctrl->id - VIVID_CID_HDMI_IS_CONNECTED_TO_OUTPUT(0); + output_inst = vivid_ctrl_hdmi_to_output_instance[ctrl->cur.val]; + index = vivid_ctrl_hdmi_to_output_index[ctrl->cur.val]; + input_index = dev->hdmi_index_to_input_index[hdmi_index]; + dev->input_is_connected_to_output[input_index] = ctrl->val; + + if (output_inst) + output_inst->output_to_input_instance[index] = NULL; + if (ctrl->val >= FIXED_MENU_ITEMS) { + output_inst = vivid_ctrl_hdmi_to_output_instance[ctrl->val]; + index = vivid_ctrl_hdmi_to_output_index[ctrl->val]; + output_inst->output_to_input_instance[index] = dev; + output_inst->output_to_input_index[index] = + dev->hdmi_index_to_input_index[hdmi_index]; + } + spin_lock(&hdmi_output_skip_mask_lock); + hdmi_to_output_menu_skip_mask &= ~(1ULL << ctrl->cur.val); + if (ctrl->val >= FIXED_MENU_ITEMS) + hdmi_to_output_menu_skip_mask |= 1ULL << ctrl->val; + spin_unlock(&hdmi_output_skip_mask_lock); + if (ctrl->val < FIXED_MENU_ITEMS && ctrl->cur.val < FIXED_MENU_ITEMS) + break; + queue_work(update_hdmi_ctrls_workqueue, &dev->update_hdmi_ctrl_work); + break; + case VIVID_CID_SVID_IS_CONNECTED_TO_OUTPUT(0) ... VIVID_CID_SVID_IS_CONNECTED_TO_OUTPUT(15): + svid_index = ctrl->id - VIVID_CID_SVID_IS_CONNECTED_TO_OUTPUT(0); + output_inst = vivid_ctrl_svid_to_output_instance[ctrl->cur.val]; + index = vivid_ctrl_svid_to_output_index[ctrl->cur.val]; + input_index = dev->svid_index_to_input_index[svid_index]; + dev->input_is_connected_to_output[input_index] = ctrl->val; + + if (output_inst) + output_inst->output_to_input_instance[index] = NULL; + if (ctrl->val >= FIXED_MENU_ITEMS) { + output_inst = vivid_ctrl_svid_to_output_instance[ctrl->val]; + index = vivid_ctrl_svid_to_output_index[ctrl->val]; + output_inst->output_to_input_instance[index] = dev; + output_inst->output_to_input_index[index] = + dev->svid_index_to_input_index[svid_index]; + } + spin_lock(&svid_output_skip_mask_lock); + svid_to_output_menu_skip_mask &= ~(1ULL << ctrl->cur.val); + if (ctrl->val >= FIXED_MENU_ITEMS) + svid_to_output_menu_skip_mask |= 1ULL << ctrl->val; + spin_unlock(&svid_output_skip_mask_lock); + if (ctrl->val < FIXED_MENU_ITEMS && ctrl->cur.val < FIXED_MENU_ITEMS) + break; + queue_work(update_svid_ctrls_workqueue, &dev->update_svid_ctrl_work); + break; } return 0; } @@ -1710,6 +1770,48 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_hdmi_video_guard_band, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL); + + WARN_ON(dev->num_hdmi_inputs > MAX_HDMI_INPUTS); + WARN_ON(dev->num_svid_inputs > MAX_SVID_INPUTS); + + for (int i = 0; i < dev->num_hdmi_inputs; i++) { + snprintf(dev->ctrl_hdmi_to_output_names[i], + sizeof(dev->ctrl_hdmi_to_output_names[i]), + "HDMI %03u-%u Is Connected To", dev->inst, i); + } + + for (int i = 0; i < dev->num_hdmi_inputs; i++) { + struct v4l2_ctrl_config ctrl_config = { + .ops = &vivid_vid_cap_ctrl_ops, + .id = VIVID_CID_HDMI_IS_CONNECTED_TO_OUTPUT(i), + .name = dev->ctrl_hdmi_to_output_names[i], + .type = V4L2_CTRL_TYPE_MENU, + .max = 1, + .qmenu = (const char * const *)vivid_ctrl_hdmi_to_output_strings, + }; + dev->ctrl_hdmi_to_output[i] = v4l2_ctrl_new_custom(hdl_vid_cap, + &ctrl_config, NULL); + } + + for (int i = 0; i < dev->num_svid_inputs; i++) { + snprintf(dev->ctrl_svid_to_output_names[i], + sizeof(dev->ctrl_svid_to_output_names[i]), + "S-Video %03u-%u Is Connected To", dev->inst, i); + } + + for (int i = 0; i < dev->num_svid_inputs; i++) { + struct v4l2_ctrl_config ctrl_config = { + .ops = &vivid_vid_cap_ctrl_ops, + .id = VIVID_CID_SVID_IS_CONNECTED_TO_OUTPUT(i), + .name = dev->ctrl_svid_to_output_names[i], + .type = V4L2_CTRL_TYPE_MENU, + .max = 1, + .qmenu = (const char * const *)vivid_ctrl_svid_to_output_strings, + }; + dev->ctrl_svid_to_output[i] = v4l2_ctrl_new_custom(hdl_vid_cap, + &ctrl_config, NULL); + } + if (show_ccs_cap) { dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_has_crop_cap, NULL); From patchwork Mon Jun 24 09:53:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709261 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F074613248E for ; Mon, 24 Jun 2024 09:56:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719223009; cv=none; b=hUrcQHKBzuiuBeGTH7gD0040fcs2IcWcsVuFvH7Qa6JWbs/qRKES/Kmisl3ujRFTNh/aN1Jj0JrqAahebm+NkzKhwL3bS1Yc6VsxrR2DRtNwIHI24t7R5k/viJB/cDn0r208UPCSgcjXW3ZMK4Adgd4yK/ExalMAXsVZz731P2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719223009; c=relaxed/simple; bh=OZ6C7ozPGa1TtmZrTQhK4mFUSdp2h6EBkITPJ/G3aG0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OLg3Wty3LE2SRfF9i0jwqIOZ01TFxJxsklZyVYJKiC78U6wykaKYbEdEAReYXwFUWuMTU5FzCqAl9fJPkPlqq2xl+DkNgAmpjbiZfoSbJfF9uF8V21n5A11EOl1x+3BH0bTPlY/CbNn3o7KvqodwNqEO5r9yM9Oxa01C+NOJZQU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hJQMKtT9; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hJQMKtT9" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-35f2c9e23d3so3149490f8f.0 for ; Mon, 24 Jun 2024 02:56:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719223004; x=1719827804; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mBp7ugIbNixhraLb7en7Gvov5f9s3gKpBq27g/BSbLA=; b=hJQMKtT98fWm3vWXkNzh73XTbudoEALSM7/Xx+lBKFFqhJzN5PcNPBk0Cwv7BFtsFk 9pXDImcPyGbhMuwVRW1BBfxH6kuAm6HPDGAtyr4YVIYUQ2jh/atfarOrm1GGea82JLos cJJ0oW4DQ8JzFuQ4DL8cyPfrEa+pY6vQMeuehK6fOcfVWwirxZeFTjzrog0AOfDV7+88 kqFeA9A72XWqjg/XhGnc7RtH3srM2Js3gHE7Yo8cZYJ/DWxhqzE+A3oUYxMUwRmgGnzM Mb8p1Jt+Wt+/bRv39knMlt5aEwPH9E1/uIrE0N4Uoh/p9/1U0x0XD4BXoGN87BnLDkdX 4WXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719223004; x=1719827804; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mBp7ugIbNixhraLb7en7Gvov5f9s3gKpBq27g/BSbLA=; b=qnBPmZeAP6vX/sNUlEq1SfCWdmcEK52EJ8c1QjJ/SEDGI4tWdRCXhOJQrXZe4RPtG4 egT6EWYPjy7QHJBXThUw6EhwFx96iiINYtHgCVUqxw1E/DNjD6mESWKu9RkmcIBY2aS1 o1uRb654Gb/eIjVG5Z6zH5wEmUfP55R06aZZPv7iUaqkli1xTq7lQ1+VRlgokMhYLUym 8sbHfJvL3LLxSZYfIKQM57rP/HgXEyYSJoDmMXfzdjBiBIPbDMQI0pVqH/zaWHvmQsv6 DA7Tvkr5xedGRDImbtrhZicbaRYnqYdXtM3aRGKe+000/B/l8ybGDUs5i5j8NoQxxN/A rrgg== X-Gm-Message-State: AOJu0YwBu432yR652sAcGMNFvHV2WggYXCKjXCdW7pKPObaLW9z+vqP1 ty3apzXBJtvRSVzu+dC015hhALmeKDKNnkN7x3XslUbsE/eZS1x5jhWByIs= X-Google-Smtp-Source: AGHT+IE9sksAhjU41nlr30kdiCAZrVg8IoaGM35tQ97QBXZCwqaNur2nfHV/r2PZmBUwkhzx9MjCMw== X-Received: by 2002:a05:6000:1a8c:b0:363:776:821b with SMTP id ffacd0b85a97d-366e31bc9f4mr5718398f8f.0.1719223003705; Mon, 24 Jun 2024 02:56:43 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.56.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:56:43 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com, Hans Verkuil Subject: [PATCH 09/10] media: vivid: loopback based on 'Connected To' controls Date: Mon, 24 Jun 2024 12:53:04 +0300 Message-Id: <20240624095300.745567-10-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Hans Verkuil Instead of using hardwired video loopback limited to a single vivid instance, use the new 'Connected To' controls to only loopback if an HDMI or S-Video input is connected to another output, which can be in another vivid instance. Effectively this emulates connecting and disconnecting an HDMI/S-Video cable. The Loop Video control is dropped since it has now been replaced by the new 'Connected To' controls. The Display Present has also been dropped since it no longer fits. Signed-off-by: Hans Verkuil Co-developed-by: Dorcas Anono Litunya Signed-off-by: Dorcas Anono Litunya --- Documentation/admin-guide/media/vivid.rst | 5 - drivers/media/test-drivers/vivid/vivid-cec.c | 88 ++++++++-- drivers/media/test-drivers/vivid/vivid-core.c | 39 ++--- drivers/media/test-drivers/vivid/vivid-core.h | 18 +- .../media/test-drivers/vivid/vivid-ctrls.c | 162 ++++++------------ .../test-drivers/vivid/vivid-kthread-cap.c | 86 ++++++---- .../media/test-drivers/vivid/vivid-vbi-cap.c | 5 +- .../media/test-drivers/vivid/vivid-vid-cap.c | 103 +++++++---- .../media/test-drivers/vivid/vivid-vid-cap.h | 2 + .../test-drivers/vivid/vivid-vid-common.c | 114 ++++++++---- .../test-drivers/vivid/vivid-vid-common.h | 5 +- .../media/test-drivers/vivid/vivid-vid-out.c | 17 +- 12 files changed, 362 insertions(+), 282 deletions(-) diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst index 31fb86030249..29481241d7cb 100644 --- a/Documentation/admin-guide/media/vivid.rst +++ b/Documentation/admin-guide/media/vivid.rst @@ -1020,11 +1020,6 @@ Digital Video Controls affects the reported colorspace since DVI_D outputs will always use sRGB. -- Display Present: - - sets the presence of a "display" on the HDMI output. This affects - the tx_edid_present, tx_hotplug and tx_rxsense controls. - FM Radio Receiver Controls ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/media/test-drivers/vivid/vivid-cec.c b/drivers/media/test-drivers/vivid/vivid-cec.c index 1f7469ff04d5..941ef4263214 100644 --- a/drivers/media/test-drivers/vivid/vivid-cec.c +++ b/drivers/media/test-drivers/vivid/vivid-cec.c @@ -23,7 +23,7 @@ struct xfer_on_bus { static bool find_dest_adap(struct vivid_dev *dev, struct cec_adapter *adap, u8 dest) { - unsigned int i; + unsigned int i, j; if (dest >= 0xf) return false; @@ -33,12 +33,29 @@ static bool find_dest_adap(struct vivid_dev *dev, cec_has_log_addr(dev->cec_rx_adap, dest)) return true; - for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) { - if (adap == dev->cec_tx_adap[i]) + for (i = 0, j = 0; i < dev->num_inputs; i++) { + unsigned int menu_idx = + dev->input_is_connected_to_output[i]; + + if (dev->input_type[i] != HDMI) + continue; + j++; + if (menu_idx < FIXED_MENU_ITEMS) + continue; + + struct vivid_dev *dev_tx = vivid_ctrl_hdmi_to_output_instance[menu_idx]; + unsigned int output = vivid_ctrl_hdmi_to_output_index[menu_idx]; + + if (!dev_tx) continue; - if (!dev->cec_tx_adap[i]->is_configured) + + unsigned int hdmi_output = dev_tx->output_to_iface_index[output]; + + if (adap == dev_tx->cec_tx_adap[hdmi_output]) + continue; + if (!dev_tx->cec_tx_adap[hdmi_output]->is_configured) continue; - if (cec_has_log_addr(dev->cec_tx_adap[i], dest)) + if (cec_has_log_addr(dev_tx->cec_tx_adap[hdmi_output], dest)) return true; } return false; @@ -96,7 +113,7 @@ static void adjust_sfts(struct vivid_dev *dev) int vivid_cec_bus_thread(void *_dev) { u32 last_sft; - unsigned int i; + unsigned int i, j; unsigned int dest; ktime_t start, end; s64 delta_us, retry_us; @@ -193,9 +210,27 @@ int vivid_cec_bus_thread(void *_dev) if (first_status == CEC_TX_STATUS_OK) { if (xfers_on_bus[first_idx].adap != dev->cec_rx_adap) cec_received_msg(dev->cec_rx_adap, &first_msg); - for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) - if (xfers_on_bus[first_idx].adap != dev->cec_tx_adap[i]) - cec_received_msg(dev->cec_tx_adap[i], &first_msg); + for (i = 0, j = 0; i < dev->num_inputs; i++) { + unsigned int menu_idx = + dev->input_is_connected_to_output[i]; + + if (dev->input_type[i] != HDMI) + continue; + j++; + if (menu_idx < FIXED_MENU_ITEMS) + continue; + + struct vivid_dev *dev_tx = vivid_ctrl_hdmi_to_output_instance[menu_idx]; + unsigned int output = vivid_ctrl_hdmi_to_output_index[menu_idx]; + + if (!dev_tx) + continue; + + unsigned int hdmi_output = dev_tx->output_to_iface_index[output]; + + if (xfers_on_bus[first_idx].adap != dev_tx->cec_tx_adap[hdmi_output]) + cec_received_msg(dev_tx->cec_tx_adap[hdmi_output], &first_msg); + } } end = ktime_get(); /* @@ -242,21 +277,36 @@ static int vivid_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg) { struct vivid_dev *dev = cec_get_drvdata(adap); + struct vivid_dev *dev_rx = dev; u8 idx = cec_msg_initiator(msg); + u8 output = 0; - spin_lock(&dev->cec_xfers_slock); - dev->xfers[idx].adap = adap; - memcpy(dev->xfers[idx].msg, msg->msg, CEC_MAX_MSG_SIZE); - dev->xfers[idx].len = msg->len; - dev->xfers[idx].sft = CEC_SIGNAL_FREE_TIME_RETRY; + if (dev->cec_rx_adap != adap) { + int i; + + for (i = 0; i < dev->num_hdmi_outputs; i++) + if (dev->cec_tx_adap[i] == adap) + break; + if (i == dev->num_hdmi_outputs) + return -ENONET; + output = dev->hdmi_index_to_output_index[i]; + dev_rx = dev->output_to_input_instance[output]; + if (!dev_rx) + return -ENONET; + } + spin_lock(&dev_rx->cec_xfers_slock); + dev_rx->xfers[idx].adap = adap; + memcpy(dev_rx->xfers[idx].msg, msg->msg, CEC_MAX_MSG_SIZE); + dev_rx->xfers[idx].len = msg->len; + dev_rx->xfers[idx].sft = CEC_SIGNAL_FREE_TIME_RETRY; if (signal_free_time > CEC_SIGNAL_FREE_TIME_RETRY) { - if (idx == dev->last_initiator) - dev->xfers[idx].sft = CEC_SIGNAL_FREE_TIME_NEXT_XFER; + if (idx == dev_rx->last_initiator) + dev_rx->xfers[idx].sft = CEC_SIGNAL_FREE_TIME_NEXT_XFER; else - dev->xfers[idx].sft = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR; + dev_rx->xfers[idx].sft = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR; } - spin_unlock(&dev->cec_xfers_slock); - wake_up_interruptible(&dev->kthread_waitq_cec); + spin_unlock(&dev_rx->cec_xfers_slock); + wake_up_interruptible(&dev_rx->kthread_waitq_cec); return 0; } diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c index 7eb8a0a5d4d3..00e0d08af357 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.c +++ b/drivers/media/test-drivers/vivid/vivid-core.c @@ -190,6 +190,7 @@ struct vivid_dev *vivid_devs[VIVID_MAX_DEVS]; DEFINE_SPINLOCK(hdmi_output_skip_mask_lock); struct workqueue_struct *update_hdmi_ctrls_workqueue; u64 hdmi_to_output_menu_skip_mask; +u64 hdmi_input_update_outputs_mask; struct vivid_dev *vivid_ctrl_hdmi_to_output_instance[MAX_MENU_ITEMS]; unsigned int vivid_ctrl_hdmi_to_output_index[MAX_MENU_ITEMS]; @@ -985,7 +986,6 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst, for (i = 0; i < dev->num_outputs; i++) { dev->output_type[i] = ((output_types[inst] >> i) & 1) ? HDMI : SVID; dev->output_name_counter[i] = out_type_counter[dev->output_type[i]]++; - dev->display_present[i] = true; } dev->has_audio_outputs = out_type_counter[SVID]; if (out_type_counter[HDMI] == 16) { @@ -1418,7 +1418,6 @@ static int vivid_create_queues(struct vivid_dev *dev) static int vivid_create_devnodes(struct platform_device *pdev, struct vivid_dev *dev, int inst, - unsigned int cec_tx_bus_cnt, v4l2_std_id tvnorms_cap, v4l2_std_id tvnorms_out, unsigned in_type_counter[4], @@ -1462,7 +1461,7 @@ static int vivid_create_devnodes(struct platform_device *pdev, return ret; } cec_s_phys_addr(dev->cec_rx_adap, 0, false); - v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI input 0\n", + v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI input\n", dev_name(&dev->cec_rx_adap->devnode.dev)); } #endif @@ -1505,10 +1504,10 @@ static int vivid_create_devnodes(struct platform_device *pdev, #endif #ifdef CONFIG_VIDEO_VIVID_CEC - for (i = 0; i < cec_tx_bus_cnt; i++) { + for (i = 0; i < dev->num_hdmi_outputs; i++) { ret = cec_register_adapter(dev->cec_tx_adap[i], &pdev->dev); if (ret < 0) { - for (; i < cec_tx_bus_cnt; i++) { + for (; i >= 0; i--) { cec_delete_adapter(dev->cec_tx_adap[i]); dev->cec_tx_adap[i] = NULL; } @@ -1516,10 +1515,6 @@ static int vivid_create_devnodes(struct platform_device *pdev, } v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n", dev_name(&dev->cec_tx_adap[i]->devnode.dev), i); - if (i < out_type_counter[HDMI]) - cec_s_phys_addr(dev->cec_tx_adap[i], (i + 1) << 12, false); - else - cec_s_phys_addr(dev->cec_tx_adap[i], 0x1000, false); } #endif @@ -1762,11 +1757,16 @@ static int vivid_create_devnodes(struct platform_device *pdev, static void update_hdmi_ctrls_work_handler(struct work_struct *work) { u64 skip_mask; + u64 update_mask; spin_lock(&hdmi_output_skip_mask_lock); skip_mask = hdmi_to_output_menu_skip_mask; + update_mask = hdmi_input_update_outputs_mask; + hdmi_input_update_outputs_mask = 0; spin_unlock(&hdmi_output_skip_mask_lock); for (int i = 0; i < n_devs && vivid_devs[i]; i++) { + if (update_mask & (1 << i)) + vivid_update_connected_outputs(vivid_devs[i]); for (int j = 0; j < vivid_devs[i]->num_hdmi_inputs; j++) { struct v4l2_ctrl *c = vivid_devs[i]->ctrl_hdmi_to_output[j]; @@ -1808,7 +1808,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) struct vivid_dev *dev; unsigned node_type = node_types[inst]; v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0; - unsigned int cec_tx_bus_cnt = 0; int ret; int i; @@ -1937,8 +1936,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) goto unreg_dev; /* enable/disable interface specific controls */ - if (dev->num_outputs && dev->output_type[0] != HDMI) - v4l2_ctrl_activate(dev->ctrl_display_present, false); if (dev->num_inputs && dev->input_type[0] != HDMI) { v4l2_ctrl_activate(dev->ctrl_dv_timings_signal_mode, false); v4l2_ctrl_activate(dev->ctrl_dv_timings, false); @@ -1994,27 +1991,27 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) } if (dev->has_vid_out) { - for (i = 0; i < dev->num_outputs; i++) { + int j; + + for (i = j = 0; i < dev->num_outputs; i++) { struct cec_adapter *adap; if (dev->output_type[i] != HDMI) continue; - dev->cec_output2bus_map[i] = cec_tx_bus_cnt; - adap = vivid_cec_alloc_adap(dev, cec_tx_bus_cnt, true); + adap = vivid_cec_alloc_adap(dev, j, true); ret = PTR_ERR_OR_ZERO(adap); if (ret < 0) { - for (i = 0; i < dev->num_outputs; i++) - cec_delete_adapter(dev->cec_tx_adap[i]); + while (j--) + cec_delete_adapter(dev->cec_tx_adap[j]); goto unreg_dev; } - dev->cec_tx_adap[cec_tx_bus_cnt] = adap; - cec_tx_bus_cnt++; + dev->cec_tx_adap[j++] = adap; } } - if (dev->cec_rx_adap || cec_tx_bus_cnt) { + if (dev->cec_rx_adap || dev->num_hdmi_outputs) { init_waitqueue_head(&dev->kthread_waitq_cec); dev->kthread_cec = kthread_run(vivid_cec_bus_thread, dev, "vivid_cec-%s", dev->v4l2_dev.name); @@ -2040,7 +2037,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) v4l2_ctrl_handler_setup(&dev->ctrl_hdl_touch_cap); /* finally start creating the device nodes */ - ret = vivid_create_devnodes(pdev, dev, inst, cec_tx_bus_cnt, + ret = vivid_create_devnodes(pdev, dev, inst, tvnorms_cap, tvnorms_out, in_type_counter, out_type_counter); if (ret) diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h index b0c5b7369de5..cc18a3bc6dc0 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.h +++ b/drivers/media/test-drivers/vivid/vivid-core.h @@ -83,7 +83,15 @@ extern unsigned vivid_debug; extern char *vivid_ctrl_hdmi_to_output_strings[1 + MAX_MENU_ITEMS]; /* Menu control skip mask of all HDMI outputs that are in use */ extern u64 hdmi_to_output_menu_skip_mask; -/* Spinlock for access to hdmi_to_output_menu_skip_mask */ +/* + * Bitmask of which vivid instances need to update any connected + * HDMI outputs. + */ +extern u64 hdmi_input_update_outputs_mask; +/* + * Spinlock for access to hdmi_to_output_menu_skip_mask and + * hdmi_input_update_outputs_mask. + */ extern spinlock_t hdmi_output_skip_mask_lock; /* * Workqueue that updates the menu controls whenever the HDMI menu skip mask @@ -283,7 +291,6 @@ struct vivid_dev { bool has_tv_tuner; bool has_touch_cap; - bool can_loop_video; /* Output index (0-MAX_OUTPUTS) to vivid instance of connected input */ struct vivid_dev *output_to_input_instance[MAX_OUTPUTS]; /* Output index (0-MAX_OUTPUTS) to input index (0-MAX_INPUTS) of connected input */ @@ -336,7 +343,6 @@ struct vivid_dev { struct v4l2_ctrl *ctrl_dv_timings_signal_mode; struct v4l2_ctrl *ctrl_dv_timings; }; - struct v4l2_ctrl *ctrl_display_present; struct v4l2_ctrl *ctrl_has_crop_cap; struct v4l2_ctrl *ctrl_has_compose_cap; struct v4l2_ctrl *ctrl_has_scaler_cap; @@ -463,7 +469,6 @@ struct vivid_dev { u8 *scaled_line; u8 *blended_line; unsigned cur_scaled_line; - bool display_present[MAX_OUTPUTS]; /* Output Overlay */ void *fb_vbase_out; @@ -643,11 +648,10 @@ struct vivid_dev { /* CEC */ struct cec_adapter *cec_rx_adap; - struct cec_adapter *cec_tx_adap[MAX_OUTPUTS]; - u8 cec_output2bus_map[MAX_OUTPUTS]; + struct cec_adapter *cec_tx_adap[MAX_HDMI_OUTPUTS]; struct task_struct *kthread_cec; wait_queue_head_t kthread_waitq_cec; - struct vivid_cec_xfer xfers[MAX_OUTPUTS]; + struct vivid_cec_xfer xfers[MAX_OUTPUTS]; spinlock_t cec_xfers_slock; /* read and write cec messages */ u32 cec_sft; /* bus signal free time, in bit periods */ u8 last_initiator; diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.c b/drivers/media/test-drivers/vivid/vivid-ctrls.c index f278bd86e99d..6e6504d04fe4 100644 --- a/drivers/media/test-drivers/vivid/vivid-ctrls.c +++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c @@ -18,7 +18,6 @@ #include "vivid-radio-common.h" #include "vivid-osd.h" #include "vivid-ctrls.h" -#include "vivid-cec.h" #define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000) #define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0) @@ -69,14 +68,12 @@ #define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34) #define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35) #define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36) -#define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37) #define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38) #define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39) #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40) #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41) #define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42) #define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43) -#define VIVID_CID_DISPLAY_PRESENT (VIVID_CID_VIVID_BASE + 44) #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60) #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61) @@ -445,6 +442,33 @@ static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops = { /* Video Capture Controls */ +static void vivid_update_power_present(struct vivid_dev *dev) +{ + unsigned int i, j; + + dev->power_present = 0; + for (i = 0, j = 0; + i < ARRAY_SIZE(dev->dv_timings_signal_mode); i++) { + if (dev->input_type[i] != HDMI) + continue; + /* + * If connected to TPG or HDMI output, and the signal + * mode is not NO_SIGNAL, then there is power present. + */ + if (dev->input_is_connected_to_output[i] != 1 && + dev->dv_timings_signal_mode[i] != NO_SIGNAL) + dev->power_present |= (1 << j); + j++; + } + + __v4l2_ctrl_s_ctrl(dev->ctrl_rx_power_present, + dev->power_present); + + v4l2_ctrl_activate(dev->ctrl_dv_timings, + dev->dv_timings_signal_mode[dev->input] == + SELECTED_DV_TIMINGS); +} + static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) { static const u32 colorspaces[] = { @@ -459,7 +483,7 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) V4L2_COLORSPACE_470_SYSTEM_BG, }; struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap); - unsigned int i, j; + unsigned int i; struct vivid_dev *output_inst = NULL; int index = 0; int hdmi_index, svid_index; @@ -579,25 +603,9 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) dev->dv_timings_signal_mode[dev->input] = dev->ctrl_dv_timings_signal_mode->val; dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val; - - dev->power_present = 0; - for (i = 0, j = 0; - i < ARRAY_SIZE(dev->dv_timings_signal_mode); - i++) - if (dev->input_type[i] == HDMI) { - if (dev->dv_timings_signal_mode[i] != NO_SIGNAL) - dev->power_present |= (1 << j); - j++; - } - __v4l2_ctrl_s_ctrl(dev->ctrl_rx_power_present, - dev->power_present); - - v4l2_ctrl_activate(dev->ctrl_dv_timings, - dev->dv_timings_signal_mode[dev->input] == - SELECTED_DV_TIMINGS); - + vivid_update_power_present(dev); vivid_update_quality(dev); - vivid_send_source_change(dev, HDMI); + vivid_send_input_source_change(dev, dev->input); break; case VIVID_CID_DV_TIMINGS_ASPECT_RATIO: dev->dv_timings_aspect_ratio[dev->input] = ctrl->val; @@ -621,8 +629,11 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) input_index = dev->hdmi_index_to_input_index[hdmi_index]; dev->input_is_connected_to_output[input_index] = ctrl->val; - if (output_inst) + if (output_inst) { output_inst->output_to_input_instance[index] = NULL; + vivid_update_outputs(output_inst); + cec_phys_addr_invalidate(output_inst->cec_tx_adap[index]); + } if (ctrl->val >= FIXED_MENU_ITEMS) { output_inst = vivid_ctrl_hdmi_to_output_instance[ctrl->val]; index = vivid_ctrl_hdmi_to_output_index[ctrl->val]; @@ -635,8 +646,14 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) if (ctrl->val >= FIXED_MENU_ITEMS) hdmi_to_output_menu_skip_mask |= 1ULL << ctrl->val; spin_unlock(&hdmi_output_skip_mask_lock); + vivid_update_power_present(dev); + vivid_update_quality(dev); + vivid_send_input_source_change(dev, dev->hdmi_index_to_input_index[hdmi_index]); if (ctrl->val < FIXED_MENU_ITEMS && ctrl->cur.val < FIXED_MENU_ITEMS) break; + spin_lock(&hdmi_output_skip_mask_lock); + hdmi_input_update_outputs_mask |= 1 << dev->inst; + spin_unlock(&hdmi_output_skip_mask_lock); queue_work(update_hdmi_ctrls_workqueue, &dev->update_hdmi_ctrl_work); break; case VIVID_CID_SVID_IS_CONNECTED_TO_OUTPUT(0) ... VIVID_CID_SVID_IS_CONNECTED_TO_OUTPUT(15): @@ -660,6 +677,8 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) if (ctrl->val >= FIXED_MENU_ITEMS) svid_to_output_menu_skip_mask |= 1ULL << ctrl->val; spin_unlock(&svid_output_skip_mask_lock); + vivid_update_quality(dev); + vivid_send_input_source_change(dev, dev->svid_index_to_input_index[svid_index]); if (ctrl->val < FIXED_MENU_ITEMS && ctrl->cur.val < FIXED_MENU_ITEMS) break; queue_work(update_svid_ctrls_workqueue, &dev->update_svid_ctrl_work); @@ -1026,37 +1045,6 @@ static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = { }; -/* Video Loop Control */ - -static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap); - - switch (ctrl->id) { - case VIVID_CID_LOOP_VIDEO: - dev->loop_video = ctrl->val; - vivid_update_quality(dev); - vivid_send_source_change(dev, SVID); - vivid_send_source_change(dev, HDMI); - break; - } - return 0; -} - -static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = { - .s_ctrl = vivid_loop_cap_s_ctrl, -}; - -static const struct v4l2_ctrl_config vivid_ctrl_loop_video = { - .ops = &vivid_loop_cap_ctrl_ops, - .id = VIVID_CID_LOOP_VIDEO, - .name = "Loop Video", - .type = V4L2_CTRL_TYPE_BOOLEAN, - .max = 1, - .step = 1, -}; - - /* VBI Capture Control */ static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl) @@ -1091,8 +1079,6 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) { struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out); struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; - u32 display_present = 0; - unsigned int i, j, bus_idx; switch (ctrl->id) { case VIVID_CID_HAS_CROP_OUT: @@ -1123,39 +1109,11 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) V4L2_QUANTIZATION_LIM_RANGE : V4L2_QUANTIZATION_DEFAULT; } - if (dev->loop_video) - vivid_send_source_change(dev, HDMI); - break; - case VIVID_CID_DISPLAY_PRESENT: - if (dev->output_type[dev->output] != HDMI) - break; + if (vivid_output_is_connected_to(dev)) { + struct vivid_dev *dev_rx = vivid_output_is_connected_to(dev); - dev->display_present[dev->output] = ctrl->val; - for (i = 0, j = 0; i < dev->num_outputs; i++) - if (dev->output_type[i] == HDMI) - display_present |= - dev->display_present[i] << j++; - - __v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present); - - if (dev->edid_blocks) { - __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, - display_present); - __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, - display_present); + vivid_send_source_change(dev_rx, HDMI); } - - bus_idx = dev->cec_output2bus_map[dev->output]; - if (!dev->cec_tx_adap[bus_idx]) - break; - - if (ctrl->val && dev->edid_blocks) - cec_s_phys_addr(dev->cec_tx_adap[bus_idx], - dev->cec_tx_adap[bus_idx]->phys_addr, - false); - else - cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]); - break; } return 0; @@ -1195,16 +1153,6 @@ static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = { .step = 1, }; -static const struct v4l2_ctrl_config vivid_ctrl_display_present = { - .ops = &vivid_vid_out_ctrl_ops, - .id = VIVID_CID_DISPLAY_PRESENT, - .name = "Display Present", - .type = V4L2_CTRL_TYPE_BOOLEAN, - .max = 1, - .def = 1, - .step = 1, -}; - /* Streaming Controls */ static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl) @@ -1914,21 +1862,13 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL, V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI, 0, V4L2_DV_TX_MODE_HDMI); - dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out, - &vivid_ctrl_display_present, NULL); - dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out, - NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask, - 0, hdmi_output_mask); - dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out, - NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask, - 0, hdmi_output_mask); - dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out, - NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask, - 0, hdmi_output_mask); + dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out, NULL, + V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask, 0, 0); + dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out, NULL, + V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask, 0, 0); + dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out, NULL, + V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask, 0, 0); } - if ((dev->has_vid_cap && dev->has_vid_out) || - (dev->has_vbi_cap && dev->has_vbi_out)) - v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL); if (dev->has_fb) v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_clear_fb, NULL); diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c index 42048727d7ff..669bd96da4c7 100644 --- a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c @@ -142,7 +142,7 @@ static void scale_line(const u8 *src, u8 *dst, unsigned srcw, unsigned dstw, uns * (loop_vid_overlay). Finally calculate the part of the capture buffer that * will receive that overlaid video. */ -static void vivid_precalc_copy_rects(struct vivid_dev *dev) +static void vivid_precalc_copy_rects(struct vivid_dev *dev, struct vivid_dev *out_dev) { /* Framebuffer rectangle */ struct v4l2_rect r_fb = { @@ -150,16 +150,16 @@ static void vivid_precalc_copy_rects(struct vivid_dev *dev) }; /* Overlay window rectangle in framebuffer coordinates */ struct v4l2_rect r_overlay = { - dev->overlay_out_left, dev->overlay_out_top, - dev->compose_out.width, dev->compose_out.height + out_dev->overlay_out_left, out_dev->overlay_out_top, + out_dev->compose_out.width, out_dev->compose_out.height }; - v4l2_rect_intersect(&dev->loop_vid_copy, &dev->crop_cap, &dev->compose_out); + v4l2_rect_intersect(&dev->loop_vid_copy, &dev->crop_cap, &out_dev->compose_out); dev->loop_vid_out = dev->loop_vid_copy; - v4l2_rect_scale(&dev->loop_vid_out, &dev->compose_out, &dev->crop_out); - dev->loop_vid_out.left += dev->crop_out.left; - dev->loop_vid_out.top += dev->crop_out.top; + v4l2_rect_scale(&dev->loop_vid_out, &out_dev->compose_out, &out_dev->crop_out); + dev->loop_vid_out.left += out_dev->crop_out.left; + dev->loop_vid_out.top += out_dev->crop_out.top; dev->loop_vid_cap = dev->loop_vid_copy; v4l2_rect_scale(&dev->loop_vid_cap, &dev->crop_cap, &dev->compose_cap); @@ -176,15 +176,15 @@ static void vivid_precalc_copy_rects(struct vivid_dev *dev) v4l2_rect_intersect(&r_overlay, &r_fb, &r_overlay); /* shift r_overlay to the same origin as compose_out */ - r_overlay.left += dev->compose_out.left - dev->overlay_out_left; - r_overlay.top += dev->compose_out.top - dev->overlay_out_top; + r_overlay.left += out_dev->compose_out.left - out_dev->overlay_out_left; + r_overlay.top += out_dev->compose_out.top - out_dev->overlay_out_top; v4l2_rect_intersect(&dev->loop_vid_overlay, &r_overlay, &dev->loop_vid_copy); dev->loop_fb_copy = dev->loop_vid_overlay; /* shift dev->loop_fb_copy back again to the fb origin */ - dev->loop_fb_copy.left -= dev->compose_out.left - dev->overlay_out_left; - dev->loop_fb_copy.top -= dev->compose_out.top - dev->overlay_out_top; + dev->loop_fb_copy.left -= out_dev->compose_out.left - out_dev->overlay_out_left; + dev->loop_fb_copy.top -= out_dev->compose_out.top - out_dev->overlay_out_top; dev->loop_vid_overlay_cap = dev->loop_vid_overlay; v4l2_rect_scale(&dev->loop_vid_overlay_cap, &dev->crop_cap, &dev->compose_cap); @@ -213,24 +213,25 @@ static void *plane_vaddr(struct tpg_data *tpg, struct vivid_buffer *buf, return vbuf; } -static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, - u8 *vcapbuf, struct vivid_buffer *vid_cap_buf) +static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, + struct vivid_dev *out_dev, unsigned p, + u8 *vcapbuf, struct vivid_buffer *vid_cap_buf) { bool blank = dev->must_blank[vid_cap_buf->vb.vb2_buf.index]; struct tpg_data *tpg = &dev->tpg; struct vivid_buffer *vid_out_buf = NULL; - unsigned vdiv = dev->fmt_out->vdownsampling[p]; + unsigned vdiv = out_dev->fmt_out->vdownsampling[p]; unsigned twopixsize = tpg_g_twopixelsize(tpg, p); unsigned img_width = tpg_hdiv(tpg, p, dev->compose_cap.width); unsigned img_height = dev->compose_cap.height; unsigned stride_cap = tpg->bytesperline[p]; - unsigned stride_out = dev->bytesperline_out[p]; + unsigned stride_out = out_dev->bytesperline_out[p]; unsigned stride_osd = dev->display_byte_stride; unsigned hmax = (img_height * tpg->perc_fill) / 100; u8 *voutbuf; u8 *vosdbuf = NULL; unsigned y; - bool blend = dev->fbuf_out_flags; + bool blend = out_dev->fbuf_out_flags; /* Coarse scaling with Bresenham */ unsigned vid_out_int_part; unsigned vid_out_fract_part; @@ -247,8 +248,8 @@ static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned vid_out_int_part = dev->loop_vid_out.height / dev->loop_vid_cap.height; vid_out_fract_part = dev->loop_vid_out.height % dev->loop_vid_cap.height; - if (!list_empty(&dev->vid_out_active)) - vid_out_buf = list_entry(dev->vid_out_active.next, + if (!list_empty(&out_dev->vid_out_active)) + vid_out_buf = list_entry(out_dev->vid_out_active.next, struct vivid_buffer, list); if (vid_out_buf == NULL) return -ENODATA; @@ -256,8 +257,8 @@ static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned vid_cap_buf->vb.field = vid_out_buf->vb.field; voutbuf = plane_vaddr(tpg, vid_out_buf, p, - dev->bytesperline_out, dev->fmt_out_rect.height); - if (p < dev->fmt_out->buffers) + out_dev->bytesperline_out, out_dev->fmt_out_rect.height); + if (p < out_dev->fmt_out->buffers) voutbuf += vid_out_buf->vb.vb2_buf.planes[p].data_offset; voutbuf += tpg_hdiv(tpg, p, dev->loop_vid_out.left) + (dev->loop_vid_out.top / vdiv) * stride_out; @@ -274,7 +275,7 @@ static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned return 0; } - if (dev->overlay_out_enabled && + if (out_dev->overlay_out_enabled && dev->loop_vid_overlay.width && dev->loop_vid_overlay.height) { vosdbuf = dev->video_vbase; vosdbuf += (dev->loop_fb_copy.left * twopixsize) / 2 + @@ -385,6 +386,7 @@ static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) { + struct vivid_dev *out_dev = NULL; struct tpg_data *tpg = &dev->tpg; unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1; unsigned line_height = 16 / factor; @@ -396,14 +398,6 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) unsigned ms; char str[100]; s32 gain; - bool is_loop = false; - - if (dev->loop_video && dev->can_loop_video && - ((vivid_is_svid_cap(dev) && - !VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) || - (vivid_is_hdmi_cap(dev) && - !VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input])))) - is_loop = true; buf->vb.sequence = dev->vid_cap_seq_count; v4l2_ctrl_s_ctrl(dev->ro_int32, buf->vb.sequence & 0xff); @@ -428,7 +422,34 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) dev->field_cap == V4L2_FIELD_ALTERNATE); tpg_s_perc_fill_blank(tpg, dev->must_blank[buf->vb.vb2_buf.index]); - vivid_precalc_copy_rects(dev); + if (vivid_vid_can_loop(dev) && + ((vivid_is_svid_cap(dev) && + !VIVID_INVALID_SIGNAL(dev->std_signal_mode[dev->input])) || + (vivid_is_hdmi_cap(dev) && + !VIVID_INVALID_SIGNAL(dev->dv_timings_signal_mode[dev->input])))) { + out_dev = vivid_input_is_connected_to(dev); + /* + * If the vivid instance of the output device is different + * from the vivid instance of this input device, then we + * must take care to properly serialize the output device to + * prevent that the buffer we are copying from is being freed. + * + * If the output device is part of the same instance, then the + * lock is already taken and there is no need to take the mutex. + * + * The problem with taking the mutex is that you can get + * deadlocked if instance A locks instance B and vice versa. + * It is not really worth trying to be very smart about this, + * so just try to take the lock, and if you can't, then just + * set out_dev to NULL and you will end up with a single frame + * of Noise (the default test pattern in this case). + */ + if (out_dev && dev != out_dev && !mutex_trylock(&out_dev->mutex)) + out_dev = NULL; + } + + if (out_dev) + vivid_precalc_copy_rects(dev, out_dev); for (p = 0; p < tpg_g_planes(tpg); p++) { void *vbuf = plane_vaddr(tpg, buf, p, @@ -445,10 +466,13 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) vbuf += dev->fmt_cap->data_offset[p]; } tpg_calc_text_basep(tpg, basep, p, vbuf); - if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf)) + if (!out_dev || vivid_copy_buffer(dev, out_dev, p, vbuf, buf)) tpg_fill_plane_buffer(tpg, vivid_get_std_cap(dev), p, vbuf); } + if (out_dev && dev != out_dev) + mutex_unlock(&out_dev->mutex); + dev->must_blank[buf->vb.vb2_buf.index] = false; /* Updates stream time, only update at the start of a new frame. */ diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-cap.c b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c index 3840b3a664ac..f40d68853692 100644 --- a/drivers/media/test-drivers/vivid/vivid-vbi-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c @@ -14,6 +14,7 @@ #include "vivid-kthread-cap.h" #include "vivid-vbi-cap.h" #include "vivid-vbi-gen.h" +#include "vivid-vid-common.h" static void vivid_sliced_vbi_cap_fill(struct vivid_dev *dev, unsigned seqnr) { @@ -23,7 +24,7 @@ static void vivid_sliced_vbi_cap_fill(struct vivid_dev *dev, unsigned seqnr) vivid_vbi_gen_sliced(vbi_gen, is_60hz, seqnr); if (!is_60hz) { - if (dev->loop_video) { + if (vivid_vid_can_loop(dev)) { if (dev->vbi_out_have_wss) { vbi_gen->data[12].data[0] = dev->vbi_out_wss[0]; vbi_gen->data[12].data[1] = dev->vbi_out_wss[1]; @@ -47,7 +48,7 @@ static void vivid_sliced_vbi_cap_fill(struct vivid_dev *dev, unsigned seqnr) break; } } - } else if (dev->loop_video && is_60hz) { + } else if (vivid_vid_can_loop(dev) && is_60hz) { if (dev->vbi_out_have_cc[0]) { vbi_gen->data[0].data[0] = dev->vbi_out_cc[0][0]; vbi_gen->data[0].data[1] = dev->vbi_out_cc[0][1]; diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c index fcbef8b58127..aff15c0e5a73 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c @@ -210,9 +210,6 @@ static int vid_cap_start_streaming(struct vb2_queue *vq, unsigned count) unsigned i; int err; - if (vb2_is_streaming(&dev->vb_vid_out_q)) - dev->can_loop_video = vivid_vid_can_loop(dev); - dev->vid_cap_seq_count = 0; dprintk(dev, 1, "%s\n", __func__); for (i = 0; i < VIDEO_MAX_FRAME; i++) @@ -242,7 +239,6 @@ static void vid_cap_stop_streaming(struct vb2_queue *vq) dprintk(dev, 1, "%s\n", __func__); vivid_stop_generating_vid_cap(dev, &dev->vid_cap_streaming); - dev->can_loop_video = false; } static void vid_cap_buf_request_complete(struct vb2_buffer *vb) @@ -273,7 +269,7 @@ void vivid_update_quality(struct vivid_dev *dev) { unsigned freq_modulus; - if (dev->loop_video && (vivid_is_svid_cap(dev) || vivid_is_hdmi_cap(dev))) { + if (dev->input_is_connected_to_output[dev->input]) { /* * The 'noise' will only be replaced by the actual video * if the output video matches the input video settings. @@ -487,35 +483,35 @@ static enum v4l2_field vivid_field_cap(struct vivid_dev *dev, enum v4l2_field fi static unsigned vivid_colorspace_cap(struct vivid_dev *dev) { - if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) + if (!vivid_input_is_connected_to(dev)) return tpg_g_colorspace(&dev->tpg); return dev->colorspace_out; } static unsigned vivid_xfer_func_cap(struct vivid_dev *dev) { - if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) + if (!vivid_input_is_connected_to(dev)) return tpg_g_xfer_func(&dev->tpg); return dev->xfer_func_out; } static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev) { - if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) + if (!vivid_input_is_connected_to(dev)) return tpg_g_ycbcr_enc(&dev->tpg); return dev->ycbcr_enc_out; } static unsigned int vivid_hsv_enc_cap(struct vivid_dev *dev) { - if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) + if (!vivid_input_is_connected_to(dev)) return tpg_g_hsv_enc(&dev->tpg); return dev->hsv_enc_out; } static unsigned vivid_quantization_cap(struct vivid_dev *dev) { - if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) + if (!vivid_input_is_connected_to(dev)) return tpg_g_quantization(&dev->tpg); return dev->quantization_out; } @@ -1537,13 +1533,65 @@ int vidioc_query_dv_timings(struct file *file, void *_fh, return 0; } +void vivid_update_outputs(struct vivid_dev *dev) +{ + u32 edid_present = 0; + + if (!dev || !dev->num_outputs) + return; + for (unsigned int i = 0, j = 0; i < dev->num_outputs; i++) { + if (dev->output_type[i] != HDMI) + continue; + + struct vivid_dev *dev_rx = dev->output_to_input_instance[i]; + + if (dev_rx && dev_rx->edid_blocks) + edid_present |= 1 << j; + j++; + } + v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, edid_present); + v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, edid_present); + v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, edid_present); +} + +void vivid_update_connected_outputs(struct vivid_dev *dev) +{ + u16 phys_addr = cec_get_edid_phys_addr(dev->edid, dev->edid_blocks * 128, NULL); + + for (unsigned int i = 0, j = 0; i < dev->num_inputs; i++) { + unsigned int menu_idx = + dev->input_is_connected_to_output[i]; + + if (dev->input_type[i] != HDMI) + continue; + j++; + if (menu_idx < FIXED_MENU_ITEMS) + continue; + + struct vivid_dev *dev_tx = vivid_ctrl_hdmi_to_output_instance[menu_idx]; + unsigned int output = vivid_ctrl_hdmi_to_output_index[menu_idx]; + + if (!dev_tx) + continue; + + unsigned int hdmi_output = dev_tx->output_to_iface_index[output]; + + vivid_update_outputs(dev_tx); + if (dev->edid_blocks) { + cec_s_phys_addr(dev_tx->cec_tx_adap[hdmi_output], + v4l2_phys_addr_for_input(phys_addr, j), + false); + } else { + cec_phys_addr_invalidate(dev_tx->cec_tx_adap[hdmi_output]); + } + } +} + int vidioc_s_edid(struct file *file, void *_fh, struct v4l2_edid *edid) { struct vivid_dev *dev = video_drvdata(file); u16 phys_addr; - u32 display_present = 0; - unsigned int i, j; int ret; memset(edid->reserved, 0, sizeof(edid->reserved)); @@ -1552,13 +1600,11 @@ int vidioc_s_edid(struct file *file, void *_fh, if (dev->input_type[edid->pad] != HDMI || edid->start_block) return -EINVAL; if (edid->blocks == 0) { + if (vb2_is_busy(&dev->vb_vid_cap_q)) + return -EBUSY; dev->edid_blocks = 0; - if (dev->num_outputs) { - v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0); - v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0); - } - phys_addr = CEC_PHYS_ADDR_INVALID; - goto set_phys_addr; + vivid_update_connected_outputs(dev); + return 0; } if (edid->blocks > dev->edid_max_blocks) { edid->blocks = dev->edid_max_blocks; @@ -1575,26 +1621,7 @@ int vidioc_s_edid(struct file *file, void *_fh, dev->edid_blocks = edid->blocks; memcpy(dev->edid, edid->edid, edid->blocks * 128); - for (i = 0, j = 0; i < dev->num_outputs; i++) - if (dev->output_type[i] == HDMI) - display_present |= - dev->display_present[i] << j++; - - if (dev->num_outputs) { - v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present); - v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present); - } - -set_phys_addr: - /* TODO: a proper hotplug detect cycle should be emulated here */ - cec_s_phys_addr(dev->cec_rx_adap, phys_addr, false); - - for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) - cec_s_phys_addr(dev->cec_tx_adap[i], - dev->display_present[i] ? - v4l2_phys_addr_for_input(phys_addr, i + 1) : - CEC_PHYS_ADDR_INVALID, - false); + vivid_update_connected_outputs(dev); return 0; } diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.h b/drivers/media/test-drivers/vivid/vivid-vid-cap.h index 949768652d38..7a8daf0af2ca 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.h +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.h @@ -10,6 +10,8 @@ void vivid_update_quality(struct vivid_dev *dev); void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls); +void vivid_update_outputs(struct vivid_dev *dev); +void vivid_update_connected_outputs(struct vivid_dev *dev); enum tpg_video_aspect vivid_get_video_aspect(const struct vivid_dev *dev); extern const v4l2_std_id vivid_standard[]; diff --git a/drivers/media/test-drivers/vivid/vivid-vid-common.c b/drivers/media/test-drivers/vivid/vivid-vid-common.c index a3e8eb90f11b..df7678db67fb 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-common.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-common.c @@ -769,14 +769,55 @@ const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat) return NULL; } +struct vivid_dev *vivid_output_is_connected_to(struct vivid_dev *dev) +{ + struct vivid_dev *input_inst = dev->output_to_input_instance[dev->output]; + + if (!input_inst) + return NULL; + if (input_inst->input != dev->output_to_input_index[dev->output]) + return NULL; + return input_inst; +} + +struct vivid_dev *vivid_input_is_connected_to(struct vivid_dev *dev) +{ + s32 connected_output = dev->input_is_connected_to_output[dev->input]; + + if (connected_output < FIXED_MENU_ITEMS) + return NULL; + struct vivid_dev *output_inst = NULL; + + if (vivid_is_hdmi_cap(dev)) { + output_inst = vivid_ctrl_hdmi_to_output_instance[connected_output]; + if (vivid_ctrl_hdmi_to_output_index[connected_output] != output_inst->output) + return NULL; + return output_inst; + } else if (vivid_is_svid_cap(dev)) { + output_inst = vivid_ctrl_svid_to_output_instance[connected_output]; + if (vivid_ctrl_svid_to_output_index[connected_output] != output_inst->output) + return NULL; + return output_inst; + } else { + return NULL; + } + return output_inst; +} + bool vivid_vid_can_loop(struct vivid_dev *dev) { - if (dev->src_rect.width != dev->sink_rect.width || - dev->src_rect.height != dev->sink_rect.height) + struct vivid_dev *output_inst = vivid_input_is_connected_to(dev); + + if (!output_inst) return false; - if (dev->fmt_cap->fourcc != dev->fmt_out->fourcc) + if (!vb2_is_streaming(&output_inst->vb_vid_out_q)) return false; - if (dev->field_cap != dev->field_out) + if (dev->src_rect.width != output_inst->sink_rect.width || + dev->src_rect.height != output_inst->sink_rect.height) + return false; + if (dev->fmt_cap->fourcc != output_inst->fmt_out->fourcc) + return false; + if (dev->field_cap != output_inst->field_out) return false; /* * While this can be supported, it is just too much work @@ -785,34 +826,34 @@ bool vivid_vid_can_loop(struct vivid_dev *dev) if (dev->field_cap == V4L2_FIELD_SEQ_TB || dev->field_cap == V4L2_FIELD_SEQ_BT) return false; - if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) { - if (!(dev->std_cap[dev->input] & V4L2_STD_525_60) != - !(dev->std_out & V4L2_STD_525_60)) - return false; - return true; - } - if (vivid_is_hdmi_cap(dev) && vivid_is_hdmi_out(dev)) + if (vivid_is_hdmi_cap(dev)) return true; - return false; + if (!(dev->std_cap[dev->input] & V4L2_STD_525_60) != + !(output_inst->std_out & V4L2_STD_525_60)) + return false; + return true; } -void vivid_send_source_change(struct vivid_dev *dev, unsigned type) +void vivid_send_input_source_change(struct vivid_dev *dev, unsigned int input_index) { struct v4l2_event ev = { .type = V4L2_EVENT_SOURCE_CHANGE, .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, }; - unsigned i; + ev.id = input_index; - for (i = 0; i < dev->num_inputs; i++) { - ev.id = i; - if (dev->input_type[i] == type) { - if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap) - v4l2_event_queue(&dev->vid_cap_dev, &ev); - if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap) - v4l2_event_queue(&dev->vbi_cap_dev, &ev); - } - } + if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap) + v4l2_event_queue(&dev->vid_cap_dev, &ev); + if (dev->input_type[input_index] == TV || dev->input_type[input_index] == SVID) + if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap) + v4l2_event_queue(&dev->vbi_cap_dev, &ev); +} + +void vivid_send_source_change(struct vivid_dev *dev, unsigned int type) +{ + for (int i = 0; i < dev->num_inputs; i++) + if (dev->input_type[i] == type) + vivid_send_input_source_change(dev, i); } /* @@ -1036,6 +1077,7 @@ int vidioc_g_edid(struct file *file, void *_fh, struct v4l2_edid *edid) { struct vivid_dev *dev = video_drvdata(file); + struct vivid_dev *dev_rx = dev; struct video_device *vdev = video_devdata(file); struct cec_adapter *adap; unsigned int loc; @@ -1048,31 +1090,33 @@ int vidioc_g_edid(struct file *file, void *_fh, return -EINVAL; adap = dev->cec_rx_adap; } else { - unsigned int bus_idx; - if (edid->pad >= dev->num_outputs) return -EINVAL; if (dev->output_type[edid->pad] != HDMI) return -EINVAL; - if (!dev->display_present[edid->pad]) + dev_rx = dev->output_to_input_instance[edid->pad]; + if (!dev_rx) return -ENODATA; - bus_idx = dev->cec_output2bus_map[edid->pad]; - adap = dev->cec_tx_adap[bus_idx]; + + unsigned int hdmi_output = dev->output_to_iface_index[edid->pad]; + + adap = dev->cec_tx_adap[hdmi_output]; } if (edid->start_block == 0 && edid->blocks == 0) { - edid->blocks = dev->edid_blocks; + edid->blocks = dev_rx->edid_blocks; return 0; } - if (dev->edid_blocks == 0) + if (dev_rx->edid_blocks == 0) return -ENODATA; - if (edid->start_block >= dev->edid_blocks) + if (edid->start_block >= dev_rx->edid_blocks) return -EINVAL; - if (edid->blocks > dev->edid_blocks - edid->start_block) - edid->blocks = dev->edid_blocks - edid->start_block; + if (edid->blocks > dev_rx->edid_blocks - edid->start_block) + edid->blocks = dev_rx->edid_blocks - edid->start_block; - memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128); + memcpy(edid->edid, dev_rx->edid + edid->start_block * 128, edid->blocks * 128); - loc = cec_get_edid_spa_location(dev->edid, dev->edid_blocks * 128); + loc = cec_get_edid_spa_location(dev_rx->edid, + dev_rx->edid_blocks * 128); if (vdev->vfl_dir == VFL_DIR_TX && adap && loc && loc >= edid->start_block * 128 && loc < (edid->start_block + edid->blocks) * 128) { diff --git a/drivers/media/test-drivers/vivid/vivid-vid-common.h b/drivers/media/test-drivers/vivid/vivid-vid-common.h index d908d9725283..c49ac85abaed 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-common.h +++ b/drivers/media/test-drivers/vivid/vivid-vid-common.h @@ -22,8 +22,11 @@ extern const struct v4l2_dv_timings_cap vivid_dv_timings_cap; const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat); +struct vivid_dev *vivid_input_is_connected_to(struct vivid_dev *dev); +struct vivid_dev *vivid_output_is_connected_to(struct vivid_dev *dev); bool vivid_vid_can_loop(struct vivid_dev *dev); -void vivid_send_source_change(struct vivid_dev *dev, unsigned type); +void vivid_send_source_change(struct vivid_dev *dev, unsigned int type); +void vivid_send_input_source_change(struct vivid_dev *dev, unsigned int input_index); int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r); diff --git a/drivers/media/test-drivers/vivid/vivid-vid-out.c b/drivers/media/test-drivers/vivid/vivid-vid-out.c index a299b872c05a..74752e15cba6 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-out.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-out.c @@ -155,9 +155,6 @@ static int vid_out_start_streaming(struct vb2_queue *vq, unsigned count) struct vivid_dev *dev = vb2_get_drv_priv(vq); int err; - if (vb2_is_streaming(&dev->vb_vid_cap_q)) - dev->can_loop_video = vivid_vid_can_loop(dev); - dev->vid_out_seq_count = 0; dprintk(dev, 1, "%s\n", __func__); if (dev->start_streaming_error) { @@ -185,7 +182,6 @@ static void vid_out_stop_streaming(struct vb2_queue *vq) dprintk(dev, 1, "%s\n", __func__); vivid_stop_generating_vid_out(dev, &dev->vid_out_streaming); - dev->can_loop_video = false; } static void vid_out_buf_request_complete(struct vb2_buffer *vb) @@ -562,9 +558,11 @@ int vivid_s_fmt_vid_out(struct file *file, void *priv, dev->xfer_func_out = mp->xfer_func; dev->ycbcr_enc_out = mp->ycbcr_enc; dev->quantization_out = mp->quantization; - if (dev->loop_video) { - vivid_send_source_change(dev, SVID); - vivid_send_source_change(dev, HDMI); + struct vivid_dev *in_dev = vivid_output_is_connected_to(dev); + + if (in_dev) { + vivid_send_source_change(in_dev, SVID); + vivid_send_source_change(in_dev, HDMI); } return 0; } @@ -1014,11 +1012,6 @@ int vidioc_s_output(struct file *file, void *priv, unsigned o) dev->meta_out_dev.tvnorms = dev->vid_out_dev.tvnorms; vivid_update_format_out(dev); - v4l2_ctrl_activate(dev->ctrl_display_present, vivid_is_hdmi_out(dev)); - if (vivid_is_hdmi_out(dev)) - v4l2_ctrl_s_ctrl(dev->ctrl_display_present, - dev->display_present[dev->output]); - return 0; } From patchwork Mon Jun 24 09:53:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dorcas Litunya X-Patchwork-Id: 13709266 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54765136648 for ; Mon, 24 Jun 2024 09:57:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719223042; cv=none; b=VW5T64XgnlaJnvTLJdR3PBpR8y29JHPOf9R6L5PPq0Rso+TYai2X0mPyGOZXlB+ytl0A5KvKPfbf1mNmd9AjOOeCIiDLpxUhpOZb761xDZXU0hV/QtRBBe4t7bmDuXzhzw8OvbN1mVt7hmBGT/TeoRRl//NtFEj7cT0PXSVvCmM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719223042; c=relaxed/simple; bh=9Il19TztdfXyRoKrswHodEJ+VKwzT0MEaQtGa0maJ9I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WxYtHBjpQr9/ZtLteMfdEuVgLSczBoO3lCvZvvUgNR6VQsfbgUrUqh/zSPUrdNJsWC7FXQdhsdoiPdTIIl5BVKFeyPWJKLIJMFAr/f8KviCKnfd2yCT1HSP5omhnLNKDm3NIaOHBCTMsy3dfkFnVhLVsjgzuUWrkqkc1DeqKBEo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hInH4rlg; arc=none smtp.client-ip=209.85.128.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hInH4rlg" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-42138eadf64so34951415e9.3 for ; Mon, 24 Jun 2024 02:57:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719223038; x=1719827838; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QjmAUQlI0yN8wHAFxugwKKhltzjfu3xepdY0Ohl71K0=; b=hInH4rlgbUOWpPm47TOl6WGHQwovvcMIxHUG+69c7bFxjY9Dhj2m1tPqGY6F0aJy2r gVCIlgVewx2WruKJsuYAcbtTFcILkRWNcFmddjptM8ACEZcgNrflXZqOqMS3XPF89LT1 1xzp2z0tMPrZHl/vtzM4ERxGxg5UYUZuaiDYZBWm6Vn8JPiGeFld/c+6coHQnc9h7YnB NyACBckpjzN0/2vfirIjbZQ6luliCIZCUVdvVWj+agM767rLzxl0C6utWVm2hpfg+2/h aEeUmymOF3G9+4AcBuil12niY6oghemgKLj/vA90Eo9SY3MHiy4jysdrzbyPD/u8+Kxj LVXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719223038; x=1719827838; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QjmAUQlI0yN8wHAFxugwKKhltzjfu3xepdY0Ohl71K0=; b=GJHOZ5YwN1affvK8kt4UrxQTuRyp4X8XSaSOBPEtD/k0zpGRLJn3BGIzhZPD5h4gaC QwNU9tS4TwnN9Nh03ZLG2uAdCRPqozxjln2UhtlAdwDgBO8WqbkgIggiEUw8bRnSd6nP blxYM13t1XM0XPjizov+WxQem7Gd+ZxAxezVIFGhAHY1AN1W6SkuKbgRVnzLET8hLvz0 xYIHo0SfmfQDWs1+u6bZB5xaGpCCBU951fh0ufI5vDXAN7jXHtUb6RKEU7fcjyoSv33D E5/Zjei+6wnhU8ji68EwagqSztThcoK83s3iVOgmdegLDyh8I2jVsNn6Ae3O3DSyT3o6 /Qmg== X-Gm-Message-State: AOJu0Yx1P4gb5CQFakRwYBh9Va9z5pPnoFVTZHovmH4ph+Prz2y3IiEs cGpE7Il3C2GWobJMA6ToccdLnQmYYP9BI0oa9puSZUe1+gcunlPv8YwlEFg= X-Google-Smtp-Source: AGHT+IGqvdRz0hA24pIOIUtxXlEHh3LB6ZFprCT3o9yTpNFg7lZlVxuqFJAodUaqCjgA427pVjEXZA== X-Received: by 2002:a05:600c:3b9c:b0:424:8d33:5c45 with SMTP id 5b1f17b1804b1-4248d335d0emr26045605e9.30.1719223038412; Mon, 24 Jun 2024 02:57:18 -0700 (PDT) Received: from localhost.localdomain ([105.163.2.38]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-424817b5ca0sm128258475e9.24.2024.06.24.02.57.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 02:57:18 -0700 (PDT) From: Dorcas Anono Litunya To: linux-media@vger.kernel.org Cc: anonolitunya@gmail.com, jaffe1@gmail.com Subject: [PATCH 10/10] documentation: media: vivid: Update documentation on vivid loopback support Date: Mon, 24 Jun 2024 12:53:06 +0300 Message-Id: <20240624095300.745567-11-anonolitunya@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624095300.745567-1-anonolitunya@gmail.com> References: <20240624095300.745567-1-anonolitunya@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Modify section "Video and Sliced VBI Looping" in Documentation to explain the vivid loopback support for video across multiple vivid instances. Previous documentation is out-of-date as it was explaining looping in a single vivid instance only. Also, in "Some Future Improvements" the item "Add support to loop from a specific output to a specific input across vivid instances" can be dropped since that's now implemented. Signed-off-by: Dorcas Anono Litunya --- Documentation/admin-guide/media/vivid.rst | 52 +++++++++++++---------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst index 29481241d7cb..1306f19ecb5a 100644 --- a/Documentation/admin-guide/media/vivid.rst +++ b/Documentation/admin-guide/media/vivid.rst @@ -1135,27 +1135,33 @@ Metadata Capture Controls if set, then the generated metadata stream contains Source Clock information. -Video and Sliced VBI Looping ----------------------------- - -The vivid driver supports looping of video output to video input, and VBI -output to VBI input. For video/VBI looping this emulates as if a cable was -hooked up between the output and input connector. So video and VBI looping -is only supported between S-Video and HDMI inputs and outputs. -VBI is only valid for S-Video as it makes no sense for HDMI. - -Looping is currently supported only between devices created by the same -vivid driver instance. - -The way to enable video/VBI looping is currently fairly crude. A 'Loop Video' -control is available in the "Vivid" control class of the video -capture and VBI capture devices. When checked the video looping will be enabled. -Once enabled any video S-Video or HDMI input will show a static test pattern -until the video output has started. At that time the video output will be -looped to the video input provided that: - -- the input type matches the output type. So the HDMI input cannot receive - video from the S-Video output. +Video, Sliced VBI and HDMI CEC Looping +-------------------------------------- + +Video Looping functionality is supported for devices created by the same +vivid driver instance, as well as across multiple instances of the vivid driver. +The vivid driver supports looping of video and Sliced VBI data between an S-Video output +and an S-Video input. It also supports looping of video and HDMI CEC data between an +HDMI output and an HDMI input. + +To enable looping, set the 'HDMI/S-Video XXX-N Is Connected To' control(s) to select +whether an input uses the Test Pattern Generator, or is disconnected, or is connected +to an output. An input can be connected to an output from any vivid instance. +The inputs and outputs are numbered XXX-N where XXX is the vivid instance number +(see module option n_devs). If there is only one vivid instance (the default), then +XXX will be 000. And N is the Nth S-Video/HDMI input or output of that instance. +If vivid is loaded without module options, then you can connect the S-Video 000-0 input +to the S-Video 000-0 output, or the HDMI 000-0 input to the HDMI 000-0 output. +This is the equivalent of connecting or disconnecting a cable between an input and an +output in a physical device. + +If an 'HDMI/S-Video XXX-N Is Connected To' control selected an output, then the video +output will be looped to the video input provided that: + +- the currently selected input matches the input indicated by the control name. + +- in the vivid instance of the output connector, the currently selected output matches + the output indicated by the control's value. - the video resolution of the video input must match that of the video output. So it is not possible to loop a 50 Hz (720x576) S-Video output to a 60 Hz @@ -1182,6 +1188,8 @@ looped to the video input provided that: "DV Timings Signal Mode" for the HDMI input should be configured so that a valid signal is passed to the video input. +If any condition is not valid, then the 'Noise' test pattern is shown. + The framerates do not have to match, although this might change in the future. By default you will see the OSD text superimposed on top of the looped video. @@ -1344,8 +1352,6 @@ Just as a reminder and in no particular order: - Add ARGB888 overlay support: better testing of the alpha channel - Improve pixel aspect support in the tpg code by passing a real v4l2_fract - Use per-queue locks and/or per-device locks to improve throughput -- Add support to loop from a specific output to a specific input across - vivid instances - The SDR radio should use the same 'frequencies' for stations as the normal radio receiver, and give back noise if the frequency doesn't match up with a station frequency