From patchwork Sat Feb 24 18:55:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Scheller X-Patchwork-Id: 10240465 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 3EB86602A0 for ; Sat, 24 Feb 2018 18:55:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 322E129BE3 for ; Sat, 24 Feb 2018 18:55:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 26C9D29BFC; Sat, 24 Feb 2018 18:55:55 +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 777BA29BE3 for ; Sat, 24 Feb 2018 18:55:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751472AbeBXSzu (ORCPT ); Sat, 24 Feb 2018 13:55:50 -0500 Received: from mail-wr0-f194.google.com ([209.85.128.194]:42229 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751464AbeBXSzn (ORCPT ); Sat, 24 Feb 2018 13:55:43 -0500 Received: by mail-wr0-f194.google.com with SMTP id k9so17230217wre.9 for ; Sat, 24 Feb 2018 10:55:42 -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=Ao/dprs9Hdt4CFSqa4MijXlJ2bu0geFSFPjX5Y/KF/IFrDccaDIhPzSX0z0b/oPNaK FzeN8aXDRliZc7vo54Pkgea6PvC1SSzUp8vgytNPyNeJwQzoLPS176vZSdyBlz2iMsP9 LKDTn5Kfxs6cw3vgUmjePZQC1DNxg4yQK66+DFSNWnfvIIp4WrrcOGP0VTHAvjhdGDeM ZRMbmxicZDuf/mv4p6c7A/NmBwkWPP54FG8UKuvNimsiGhUdmLwuwewe2vDWqNYSzhfS +hfPv9qautYIrKXPwYg1ot+MjUcQRSgGqolSuQgjyV1VShN8vQuQWAlhsYN6N+oA+aMb Uzow== 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=UlSNmSltQnpHx+iOXGL3W/nkMab2iyzi6rqAs40AgKkSYrJHWz7fE7U2YPzNpbHwvn BzWGbtIYoxpuHuwfa1WViNs6J4EJlHRV+CMTf/h0iRJGKAUsXJNec0ausMon2cebPlpb MNAgcsgNDOROrEwyrE7oFPn3+EmB0kw1rkG6DsLCJt1lSV8WMJhFrm3AaJE6ZnATHSMI Vy4cTt8DIhlNTpOmesoEdJxz+8YoT5OkdEAf1SNEw0cH/2Y3ZvMG8TLVy+PM1RYiWjpJ MqtfmTzuqbGJ6/R+zSxlHuhqPZOualCZ6745qNYb8wOYehpv2N393pUA05dKgO9Wdy0M K+Tw== X-Gm-Message-State: APf1xPA8Om3UmY3XpcEbMxYaEkVrJOS84H684cD9I2SdF8av7D+Y1oyl PiTm3dELx3SN3lXrDI1Fy7T9zw== X-Google-Smtp-Source: AH8x226YxWhnsIBpZfVDOkq+GyeoBVGCywLoZb0GdiCh5h5M+MLiVFXRvJKam/qGiStM6WJotAC16w== X-Received: by 10.223.141.200 with SMTP id o66mr4910864wrb.39.1519498541804; Sat, 24 Feb 2018 10:55:41 -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 3sm526270wry.29.2018.02.24.10.55.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 24 Feb 2018 10:55:41 -0800 (PST) From: Daniel Scheller To: linux-media@vger.kernel.org, mchehab@kernel.org, mchehab@s-opensource.com Subject: [PATCH 05/12] [media] ngene: add XO2 module support Date: Sat, 24 Feb 2018 19:55:27 +0100 Message-Id: <20180224185534.13792-6-d.scheller.oss@gmail.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180224185534.13792-1-d.scheller.oss@gmail.com> References: <20180224185534.13792-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,