From patchwork Thu Sep 25 05:08:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Schwarzott X-Patchwork-Id: 4973021 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D37EE9F402 for ; Thu, 25 Sep 2014 05:08:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0B11A2027D for ; Thu, 25 Sep 2014 05:08:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 117AE202A1 for ; Thu, 25 Sep 2014 05:08:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752089AbaIYFIc (ORCPT ); Thu, 25 Sep 2014 01:08:32 -0400 Received: from smtp.gentoo.org ([140.211.166.183]:43854 "EHLO smtp.gentoo.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751895AbaIYFIa (ORCPT ); Thu, 25 Sep 2014 01:08:30 -0400 Received: from gauss.fritz.box (aftr-88-217-181-51.dynamic.mnet-online.de [88.217.181.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: zzam) by smtp.gentoo.org (Postfix) with ESMTPSA id E4ACF3401D9; Thu, 25 Sep 2014 05:08:28 +0000 (UTC) From: Matthias Schwarzott To: linux-media@vger.kernel.org, mchehab@osg.samsung.com Cc: Matthias Schwarzott Subject: [PATCH 10/12] cx231xx: register i2c mux adapters for master1 and use as I2C_1 and I2C_3 Date: Thu, 25 Sep 2014 07:08:02 +0200 Message-Id: <1411621684-8295-10-git-send-email-zzam@gentoo.org> X-Mailer: git-send-email 2.1.1 In-Reply-To: <1411621684-8295-1-git-send-email-zzam@gentoo.org> References: <1411621684-8295-1-git-send-email-zzam@gentoo.org> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Matthias Schwarzott Reviewed-by: Antti Palosaari --- drivers/media/usb/cx231xx/Kconfig | 1 + drivers/media/usb/cx231xx/cx231xx-core.c | 5 ++++ drivers/media/usb/cx231xx/cx231xx-i2c.c | 45 ++++++++++++++++++++++++++++++-- drivers/media/usb/cx231xx/cx231xx.h | 4 +++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig index 569aa29..173c0e2 100644 --- a/drivers/media/usb/cx231xx/Kconfig +++ b/drivers/media/usb/cx231xx/Kconfig @@ -7,6 +7,7 @@ config VIDEO_CX231XX select VIDEOBUF_VMALLOC select VIDEO_CX25840 select VIDEO_CX2341X + select I2C_MUX ---help--- This is a video4linux driver for Conexant 231xx USB based TV cards. diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 180103e..c8a6d20 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -1300,6 +1300,9 @@ int cx231xx_dev_init(struct cx231xx *dev) cx231xx_i2c_register(&dev->i2c_bus[1]); cx231xx_i2c_register(&dev->i2c_bus[2]); + cx231xx_i2c_mux_register(dev, 0); + cx231xx_i2c_mux_register(dev, 1); + /* init hardware */ /* Note : with out calling set power mode function, afe can not be set up correctly */ @@ -1414,6 +1417,8 @@ EXPORT_SYMBOL_GPL(cx231xx_dev_init); void cx231xx_dev_uninit(struct cx231xx *dev) { /* Un Initialize I2C bus */ + cx231xx_i2c_mux_unregister(dev, 1); + cx231xx_i2c_mux_unregister(dev, 0); cx231xx_i2c_unregister(&dev->i2c_bus[2]); cx231xx_i2c_unregister(&dev->i2c_bus[1]); cx231xx_i2c_unregister(&dev->i2c_bus[0]); diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index a8c0f90..848aec2 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -552,17 +553,57 @@ int cx231xx_i2c_unregister(struct cx231xx_i2c *bus) return 0; } +/* + * cx231xx_i2c_mux_select() + * switch i2c master number 1 between port1 and port3 + */ +static int cx231xx_i2c_mux_select(struct i2c_adapter *adap, + void *mux_priv, u32 chan_id) +{ + struct cx231xx *dev = mux_priv; + + return cx231xx_enable_i2c_port_3(dev, chan_id); +} + +int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no) +{ + struct i2c_adapter *i2c_parent = &dev->i2c_bus[1].i2c_adap; + /* what is the correct mux_dev? */ + struct device *mux_dev = &dev->udev->dev; + + dev->i2c_mux_adap[mux_no] = i2c_add_mux_adapter(i2c_parent, + mux_dev, + dev /* mux_priv */, + 0, + mux_no /* chan_id */, + 0 /* class */, + &cx231xx_i2c_mux_select, + NULL); + + if (!dev->i2c_mux_adap[mux_no]) + cx231xx_warn("%s: i2c mux %d register FAILED\n", + dev->name, mux_no); + + return 0; +} + +void cx231xx_i2c_mux_unregister(struct cx231xx *dev, int mux_no) +{ + i2c_del_mux_adapter(dev->i2c_mux_adap[mux_no]); + dev->i2c_mux_adap[mux_no] = NULL; +} + struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port) { switch (i2c_port) { case I2C_0: return &dev->i2c_bus[0].i2c_adap; case I2C_1: - return &dev->i2c_bus[1].i2c_adap; + return dev->i2c_mux_adap[0]; case I2C_2: return &dev->i2c_bus[2].i2c_adap; case I2C_3: - return &dev->i2c_bus[1].i2c_adap; + return dev->i2c_mux_adap[1]; default: return NULL; } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index cefeb30..9234cd7 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -627,6 +627,8 @@ struct cx231xx { /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ struct cx231xx_i2c i2c_bus[3]; + struct i2c_adapter *i2c_mux_adap[2]; + unsigned int xc_fw_load_done:1; unsigned int port_3_switch_enabled:1; /* locks */ @@ -754,6 +756,8 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev); void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port); int cx231xx_i2c_register(struct cx231xx_i2c *bus); int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); +int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no); +void cx231xx_i2c_mux_unregister(struct cx231xx *dev, int mux_no); struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port); /* Internal block control functions */