From patchwork Sun Feb 25 12:31:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Scheller X-Patchwork-Id: 10240849 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9F5A1603B4 for ; Sun, 25 Feb 2018 12:31:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 91DC629CBE for ; Sun, 25 Feb 2018 12:31:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 86EBD29CE4; Sun, 25 Feb 2018 12:31:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD9F229CBE for ; Sun, 25 Feb 2018 12:31:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751794AbeBYMbz (ORCPT ); Sun, 25 Feb 2018 07:31:55 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:55530 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751761AbeBYMbt (ORCPT ); Sun, 25 Feb 2018 07:31:49 -0500 Received: by mail-wm0-f65.google.com with SMTP id q83so12559466wme.5 for ; Sun, 25 Feb 2018 04:31:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=zNq4M2rcRbSPWI1TxJa7bRa33/va3/+h9tL74k5jz48=; b=qeDm43d1h6Q03HoxF1cpIXRlXqf2BjwQTljO+vtVx3Aah8JCYBgQcMXQsulNSfsWPd vvDVHLFx1ZDp3hcQRMseCePyOTpihtyldD9j9L3tYRjRc7ucLdhH95yM3IJ5G1tgHUPp YJM6lfIHT2LRLBc7hxTlWGNRFJt0UThLmMJyZmbCoVtrAFUCV3e96MDYIgJNdH6W/V2a AYIFvOuNsT5vh2zZasfS+q6u2pjAdk/YNm+UORbWqI4Vqj6wACtn6uebwwNgjGhIlQy2 OT6wDv7YSNUtTPLTjJx6h4WaxOUdnByCgDCzLBnPbQhosrZtAi41CAwz82pgNdUFVULf EoAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=zNq4M2rcRbSPWI1TxJa7bRa33/va3/+h9tL74k5jz48=; b=GDZcs7Wc2ZbpFDYuXJi1Y3K8hi91qysDROdzrLObzupmDVDAOy++bCfPSXHa++e3Bx 9boGgcJjvvgLDsup9GyWk4p12ZncD8WDOvnJDxTv5yXCYIoGXTd+Fx/nFdsxEvbsqU6C fPTEtQwIb2G9FNvsgV39ny1+9AVu+R4tj4Y1o75IMG5kiIoSgqlwt8pDGahGCtMUcwRY 22HDLoUeeUfntnwYeFFS1b8X7q4gXUkNPp5s7qRqyoOefF6j+MQdz+saAdqGmtUveBj6 5imFfqmc5VmFHDCNpLjEAl831NoudNaERui9zXz2+kisKoPu7+az4X3tRAHEjnedbd4Y wA4A== X-Gm-Message-State: APf1xPDfNUae44r0K7MlHzn8QPiPY9uoN4Gg3I4KYTZUn+0O8cRfcP9K PkDGWuY6U6LqVxo1ucAfQlZ6AA== X-Google-Smtp-Source: AG47ELsdLpJ/yQ4Bp2AJWHMT6DrpCGjnQaC1bKqe2rzf3eeNhRUFL5lrrX0JO+wUAU86dFktBFyeSA== X-Received: by 10.28.156.215 with SMTP id f206mr6403611wme.131.1519561907849; Sun, 25 Feb 2018 04:31:47 -0800 (PST) Received: from dvbdev.wuest.de (ip-84-118-193-200.unity-media.net. [84.118.193.200]) by smtp.gmail.com with ESMTPSA id y34sm15304779wry.19.2018.02.25.04.31.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 25 Feb 2018 04:31:47 -0800 (PST) From: Daniel Scheller To: linux-media@vger.kernel.org, mchehab@kernel.org, mchehab@s-opensource.com Subject: [PATCH v2 05/12] [media] ngene: add XO2 module support Date: Sun, 25 Feb 2018 13:31:33 +0100 Message-Id: <20180225123140.19486-6-d.scheller.oss@gmail.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180225123140.19486-1-d.scheller.oss@gmail.com> References: <20180225123140.19486-1-d.scheller.oss@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Daniel Scheller Detect and initialise modules equipped with XO2 interfaces (Lattice MachXO2). This requires a few more I2C transfer functions which this adds aswell. Defines for the different possible (available) module types are added to ngene.h. The support for the actual tuners contained on these addon modules is kept separate from this commit and is being added with the next commits. The xo2names array is temporarily marked __maybe_unused to silence a corresponding compiler warning at this stage. Signed-off-by: Daniel Scheller --- drivers/media/pci/ngene/ngene-cards.c | 144 +++++++++++++++++++++++++++++++++- drivers/media/pci/ngene/ngene.h | 12 +++ 2 files changed, 155 insertions(+), 1 deletion(-) diff --git a/drivers/media/pci/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c index 7ec5f68b1ec7..05b8e56999ec 100644 --- a/drivers/media/pci/ngene/ngene-cards.c +++ b/drivers/media/pci/ngene/ngene-cards.c @@ -50,6 +50,32 @@ /* I2C transfer functions used for demod/tuner probing***********************/ /****************************************************************************/ +static int i2c_io(struct i2c_adapter *adapter, u8 adr, + u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) +{ + struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, + .buf = wbuf, .len = wlen }, + {.addr = adr, .flags = I2C_M_RD, + .buf = rbuf, .len = rlen } }; + return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; +} + +static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) +{ + struct i2c_msg msg = {.addr = adr, .flags = 0, + .buf = data, .len = len}; + + return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; +} + +static int i2c_write_reg(struct i2c_adapter *adap, u8 adr, + u8 reg, u8 val) +{ + u8 msg[2] = {reg, val}; + + return i2c_write(adap, adr, msg, 2); +} + static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) { struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, @@ -78,6 +104,12 @@ static int i2c_read_regs(struct i2c_adapter *adapter, return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; } + +static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) +{ + return i2c_read_regs(adapter, adr, reg, val, 1); +} + /****************************************************************************/ /* Demod/tuner attachment ***************************************************/ /****************************************************************************/ @@ -390,12 +422,98 @@ static int demod_attach_drxk(struct ngene_channel *chan, return 0; } +/****************************************************************************/ +/* XO2 related lists and functions ******************************************/ +/****************************************************************************/ + +static char __maybe_unused *xo2names[] = { + "DUAL DVB-S2", + "DUAL DVB-C/T/T2", + "DUAL DVB-ISDBT", + "DUAL DVB-C/C2/T/T2", + "DUAL ATSC", + "DUAL DVB-C/C2/T/T2/I", +}; + +static int init_xo2(struct ngene_channel *chan, struct i2c_adapter *i2c) +{ + struct device *pdev = &chan->dev->pci_dev->dev; + u8 addr = 0x10; + u8 val, data[2]; + int res; + + res = i2c_read_regs(i2c, addr, 0x04, data, 2); + if (res < 0) + return res; + + if (data[0] != 0x01) { + dev_info(pdev, "Invalid XO2 on channel %d\n", chan->number); + return -1; + } + + i2c_read_reg(i2c, addr, 0x08, &val); + if (val != 0) { + i2c_write_reg(i2c, addr, 0x08, 0x00); + msleep(100); + } + /* Enable tuner power, disable pll, reset demods */ + i2c_write_reg(i2c, addr, 0x08, 0x04); + usleep_range(2000, 3000); + /* Release demod resets */ + i2c_write_reg(i2c, addr, 0x08, 0x07); + + /* + * speed: 0=55,1=75,2=90,3=104 MBit/s + * Note: The ngene hardware must be run at 75 MBit/s compared + * to more modern ddbridge hardware which runs at 90 MBit/s, + * else there will be issues with the data transport and non- + * working secondary/slave demods/tuners. + */ + i2c_write_reg(i2c, addr, 0x09, 1); + + i2c_write_reg(i2c, addr, 0x0a, 0x01); + i2c_write_reg(i2c, addr, 0x0b, 0x01); + + usleep_range(2000, 3000); + /* Start XO2 PLL */ + i2c_write_reg(i2c, addr, 0x08, 0x87); + + return 0; +} + +static int port_has_xo2(struct i2c_adapter *i2c, u8 *type, u8 *id) +{ + u8 probe[1] = { 0x00 }, data[4]; + u8 addr = 0x10; + + *type = NGENE_XO2_TYPE_NONE; + + if (i2c_io(i2c, addr, probe, 1, data, 4)) + return 0; + if (data[0] == 'D' && data[1] == 'F') { + *id = data[2]; + *type = NGENE_XO2_TYPE_DUOFLEX; + return 1; + } + if (data[0] == 'C' && data[1] == 'I') { + *id = data[2]; + *type = NGENE_XO2_TYPE_CI; + return 1; + } + return 0; +} + +/****************************************************************************/ +/* Probing and port/channel handling ****************************************/ +/****************************************************************************/ + static int cineS2_probe(struct ngene_channel *chan) { struct device *pdev = &chan->dev->pci_dev->dev; struct i2c_adapter *i2c; struct stv090x_config *fe_conf; u8 buf[3]; + u8 xo2_type, xo2_id; struct i2c_msg i2c_msg = { .flags = 0, .buf = buf }; int rc; @@ -405,7 +523,31 @@ static int cineS2_probe(struct ngene_channel *chan) else i2c = &chan->dev->channel[1].i2c_adapter; - if (port_has_stv0900(i2c, chan->number)) { + if (port_has_xo2(i2c, &xo2_type, &xo2_id)) { + xo2_id >>= 2; + dev_dbg(pdev, "XO2 on channel %d (type %d, id %d)\n", + chan->number, xo2_type, xo2_id); + + switch (xo2_type) { + case NGENE_XO2_TYPE_DUOFLEX: + if (chan->number & 1) + dev_dbg(pdev, + "skipping XO2 init on odd channel %d", + chan->number); + else + init_xo2(chan, i2c); + + /* TODO: implement support for XO2 module types */ + dev_warn(pdev, "XO2 not supported\n"); + return -ENODEV; + case NGENE_XO2_TYPE_CI: + dev_info(pdev, "DuoFlex CI modules not supported\n"); + return -ENODEV; + default: + dev_info(pdev, "Unsupported XO2 module type\n"); + return -ENODEV; + } + } else if (port_has_stv0900(i2c, chan->number)) { chan->demod_type = DEMOD_TYPE_STV090X; fe_conf = chan->dev->card_info->fe_config[chan->number]; /* demod found, attach it */ diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h index 1b88a9aa7aac..72195f6552b3 100644 --- a/drivers/media/pci/ngene/ngene.h +++ b/drivers/media/pci/ngene/ngene.h @@ -55,6 +55,18 @@ #define DEMOD_TYPE_DRXK 1 #define DEMOD_TYPE_STV0367 2 +#define DEMOD_TYPE_XO2 32 +#define DEMOD_TYPE_STV0910 (DEMOD_TYPE_XO2 + 0) +#define DEMOD_TYPE_SONY_CT2 (DEMOD_TYPE_XO2 + 1) +#define DEMOD_TYPE_SONY_ISDBT (DEMOD_TYPE_XO2 + 2) +#define DEMOD_TYPE_SONY_C2T2 (DEMOD_TYPE_XO2 + 3) +#define DEMOD_TYPE_ST_ATSC (DEMOD_TYPE_XO2 + 4) +#define DEMOD_TYPE_SONY_C2T2I (DEMOD_TYPE_XO2 + 5) + +#define NGENE_XO2_TYPE_NONE 0 +#define NGENE_XO2_TYPE_DUOFLEX 1 +#define NGENE_XO2_TYPE_CI 2 + enum STREAM { STREAM_VIDEOIN1 = 0, /* ITU656 or TS Input */ STREAM_VIDEOIN2,