From patchwork Fri Jan 25 17:43:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Shearman X-Patchwork-Id: 1031218 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="SdoDfxjG"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43mRGh2C8hz9sBn for ; Sat, 26 Jan 2019 04:44:12 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726362AbfAYRoL (ORCPT ); Fri, 25 Jan 2019 12:44:11 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:45153 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726321AbfAYRoK (ORCPT ); Fri, 25 Jan 2019 12:44:10 -0500 Received: by mail-wr1-f67.google.com with SMTP id t6so11155198wrr.12 for ; Fri, 25 Jan 2019 09:44:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=KGE2ZT4u8LfVeZrlN5+8DBZ9ggROqUQmW0ipo/ekayI=; b=SdoDfxjGfUXRpZvFtEkXCZ0OQmwvzQn1oQs7xkmm9efKo9yP0YDd1ww4ggiTVIXd4w oDWbZFWLS+kEmuQxhHxqlTuqnJ83xXgcEJiynv5lqjEttYmgLxrTpieW1NOMGPjkGUiz X2DNDgfDFOtjASx6/9ofgnsTHq9vhzkir7tlUquGrqHv1G0PW7jJpv+qpyroPyWvNbOO jue4vRCoKV76br4WMz/GM50UWlJpMn92dwBNWGQfJrttQtcJaQVwz/dibozbmrYmICww /LDKbQWGp2rXLLjqD41Cbr7kehjTGeCTYz2nSTRjCul+E6U++26u6CaQvv+uM41cMgxK pqSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=KGE2ZT4u8LfVeZrlN5+8DBZ9ggROqUQmW0ipo/ekayI=; b=Szu470DKvYLC7G0WrXEzC4pyMsSHEqCuEHJjuFPmJT6BrHsKqukdrutMGEY5M64dzL wC9ZSC7cz6S1w4rRdaa4FAEpWmne6xdn+bb+vdYNthaE9sa4k37c4+LvSdQg4TlSzuJP hnEfGALc+ctx7rNvmaKTM+tY+ckzeFx+Ghn65hgHuYDMiGXeW6l0JRUl63oRxpyIH+0r NzpiBpMe3M/hzFW9X/PY6+hCq+VPtg5GspVKJb2VyXycv3D2HyYy4dUmy/Zl+VuSCusP tZwGIFdN8NstrJPaYGJLrtdGf3eLssqEZtB8QU+th5HfnXyldzcW6MV8wHb801NOHnqS xUGg== X-Gm-Message-State: AJcUuke91jz7UqZss/91cxnu1Igh/u8gSItbQpr3v8jDTUBHBc6UrxTM L+JkTSKVx+QpiKhZHvFgM9g= X-Google-Smtp-Source: ALg8bN41gbPOM1edD/RJQprdZ26ApbMqshsRCi+MLolSvgaBdr7uscvnXDpZ92+n0g/i4crsOMR42w== X-Received: by 2002:adf:e3c8:: with SMTP id k8mr12431748wrm.83.1548438248806; Fri, 25 Jan 2019 09:44:08 -0800 (PST) Received: from uks1.vyatta.net ([137.221.143.78]) by smtp.gmail.com with ESMTPSA id l20sm224200343wrb.93.2019.01.25.09.44.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 25 Jan 2019 09:44:08 -0800 (PST) From: Robert Shearman To: Peter Rosin Cc: linux-i2c@vger.kernel.org, Robert Shearman Subject: [PATCH] i2c: mux: pca954x: allow management of device deselect mask via sysfs Date: Fri, 25 Jan 2019 17:43:40 +0000 Message-Id: <20190125174340.15058-1-robertshearman@gmail.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org From: Robert Shearman The behaviour, by default, to not deselect after each transfer is unsafe when there is a device with an address that conflicts with another device on another pca954x mux on the same parent bus, and it may not be convenient to use the platform data or devicetree to set the deselect mux, e.g. when running on x86_64 when ACPI is used to discover most of the device hierarchy. Therefore, provide the ability to set the device deselect mask using sysfs as a complement to the method of instantiating the device via sysfs. Signed-off-by: Robert Shearman --- drivers/i2c/muxes/i2c-mux-pca954x.c | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index bfabf985e830..a425223c5c87 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -263,6 +263,40 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) return pca954x_reg_write(muxc->parent, client, data->last_chan); } +static ssize_t deselect_mask_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + + return sprintf(buf, "0x%x\n", data->deselect); +} + +static ssize_t deselect_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + unsigned int val; + int ret; + + ret = kstrtouint(buf, 0, &val); + if (ret < 0) + return ret; + + if (val >= 1 << data->chip->nchans) + return -EINVAL; + + data->deselect = val; + return count; +} + +static DEVICE_ATTR_RW(deselect_mask); + static irqreturn_t pca954x_irq_handler(int irq, void *dev_id) { struct pca954x *data = dev_id; @@ -329,8 +363,11 @@ static int pca954x_irq_setup(struct i2c_mux_core *muxc) static void pca954x_cleanup(struct i2c_mux_core *muxc) { struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; int c, irq; + device_remove_file(&client->dev, &dev_attr_deselect_mask); + if (data->irq) { for (c = 0; c < data->chip->nchans; c++) { irq = irq_find_mapping(data->irq, c); @@ -453,6 +490,10 @@ static int pca954x_probe(struct i2c_client *client, goto fail_cleanup; } + ret = device_create_file(dev, &dev_attr_deselect_mask); + if (ret) + goto fail_cleanup; + dev_info(dev, "registered %d multiplexed busses for I2C %s %s\n", num, data->chip->muxtype == pca954x_ismux ? "mux" : "switch", client->name);