get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.2/patches/814912/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 814912,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/814912/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-i2c/patch/20170918130346.3886-2-jjj@gmx.de/",
    "project": {
        "id": 35,
        "url": "http://patchwork.ozlabs.org/api/1.2/projects/35/?format=api",
        "name": "Linux I2C development",
        "link_name": "linux-i2c",
        "list_id": "linux-i2c.vger.kernel.org",
        "list_email": "linux-i2c@vger.kernel.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170918130346.3886-2-jjj@gmx.de>",
    "list_archive_url": null,
    "date": "2017-09-18T13:03:46",
    "name": "[v4,2/2] add w1_ds28e17 driver for the DS28E17 Onewire to I2C master bridge",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "04bb5b133f5181fb52d6b0478365d31cbe84d624",
    "submitter": {
        "id": 69487,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/69487/?format=api",
        "name": "Jan Kandziora",
        "email": "jjj@gmx.de"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-i2c/patch/20170918130346.3886-2-jjj@gmx.de/mbox/",
    "series": [
        {
            "id": 3640,
            "url": "http://patchwork.ozlabs.org/api/1.2/series/3640/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-i2c/list/?series=3640",
            "date": "2017-09-18T13:03:45",
            "name": "[v4,1/2] wire: export w1_touch_bit",
            "version": 4,
            "mbox": "http://patchwork.ozlabs.org/series/3640/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/814912/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/814912/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linux-i2c-owner@vger.kernel.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=linux-i2c-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xwmRb6J5Qz9s7F\n\tfor <incoming@patchwork.ozlabs.org>;\n\tMon, 18 Sep 2017 23:04:11 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1754623AbdIRNEJ (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tMon, 18 Sep 2017 09:04:09 -0400",
            "from mout.gmx.net ([212.227.17.20]:62950 \"EHLO mout.gmx.net\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1753030AbdIRNDx (ORCPT <rfc822;linux-i2c@vger.kernel.org>);\n\tMon, 18 Sep 2017 09:03:53 -0400",
            "from janskasten.janskasten.localdomain ([79.242.230.231]) by\n\tmail.gmx.com (mrgmx102 [212.227.17.168]) with ESMTPSA (Nemesis) id\n\t0La2Xx-1d8GDe25Vd-00lpjW; Mon, 18 Sep 2017 15:03:48 +0200"
        ],
        "From": "Jan Kandziora <jjj@gmx.de>",
        "To": "GregKH <greg@kroah.com>, LKML <linux-kernel@vger.kernel.org>",
        "Cc": "Evgeniy Polyakov <zbr@ioremap.net>, Linux-I2C <linux-i2c@vger.kernel.org>",
        "Subject": "[PATCH v4 2/2] add w1_ds28e17 driver for the DS28E17 Onewire to I2C\n\tmaster bridge",
        "Date": "Mon, 18 Sep 2017 15:03:46 +0200",
        "Message-Id": "<20170918130346.3886-2-jjj@gmx.de>",
        "X-Mailer": "git-send-email 2.13.3",
        "In-Reply-To": "<20170918130346.3886-1-jjj@gmx.de>",
        "References": "<20170918130346.3886-1-jjj@gmx.de>",
        "X-Provags-ID": "V03:K0:jvWk/I+k4nlN0NIr+DHobNHtpv8hKq88qTA5rWQ+qWvqmyY4SFg\n\tYkR/AMn0fvCCkW1SWzjYX6JdykOTtMFXhriSe09no6VOEzoVozFwo/MwePOTz1ba3IGE+Qv\n\t/Ev+dK8Fr/94BIGfsCa9Ri0AH6B5Un+qckruQgyS4+i5/2xOJ02/LvV6QhdyXtXTxqoJBS3\n\tPcZ0OZ5tL0p5Cs2CXAZcA==",
        "X-UI-Out-Filterresults": "notjunk:1; V01:K0:+iNK6xR3gZ0=:gvgBvdptQ3jYZy+5xfh7OV\n\trfTh9BzoIGSg/f/b+Jzxi7Hr2DKWRe02X4YmIMv9wU1bZRYVGK5VzfGDQuFF+5Z3xNbJZJPPl\n\tpXB39pPDXTwzjd0Tke9f/jzUmK10mb/Fq2J6Nmmbtzoqu+zaO6rWpLVjP4WNJytHEWNbvqTj1\n\t3zvWnL9cyldR0oexekkxRiPv6z4vnknAGusvp2Z2CerVmfPymudWR/1fl/9gfwWAibtWV/9Va\n\tk7aqxt6QuhnwsLoI9xJ9plynWgmiVfL/WZk/A1R2CzSPezfUCBzkoagaAmaiLjilYa/VOnU7J\n\tRDTvvHpQfQ41nuUSk5hMGLDy/YMCvclzLCHKBYruEQQCTWqjYX+IJux6KAAISgc0SREd5VicM\n\tDrBkS+LbDc+mw7V3SZR1lg11yjlKsSL8kJGnKt3VPkWbedMiWZiXXXNSMnae+hWhflAYotALG\n\tHKmEmomWPMhTYByrwScY541kMxAv/wFjjI1vhHmwiT3tEqGKtPtUCteOcUbCyj8ij6pFaKek0\n\tcFtmwFzulx66abxpY6hsPHxvNxzmm29bFtQnHqWPkHrta2wMg4AJL/sFMu3D/wB3icgCHTLbu\n\tKuxXfpdfQhYdCSj+lCRstzm6J1Nz3XY9B77tqwsMcCsemjc302siEVWLxbgcBElau7Y7ANRw8\n\tXM/UaI+BnPLDMAvQtvPTcabby1cdJ9EXwvNfpU3WOnucxmlwX4BlAMj7lg8I0n1XKHOPaVKjc\n\tpYb4QdLz4W1BvCAqwTOrQk3efkeYAizb9eU1m+OZ203FM91nWTe8jTbs9nD9LRSQQbBHBjli9\n\tNnI69bQLi73BekEIXTVDC2TN0UJ9A==",
        "Sender": "linux-i2c-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<linux-i2c.vger.kernel.org>",
        "X-Mailing-List": "linux-i2c@vger.kernel.org"
    },
    "content": "This subpatch adds a driver for the DS28E17 Onewire to I2C master bridge.\n\nSigned-off-by: Jan Kandziora <jjj@gmx.de>\n---\nChanges in v4 against v3 in this subpatch:\n  - adapted to linux-4.12.0\n\nChanges in v3 against v2 in this subpatch:\n  - fixed a bug in using the i2c_adapter_quirks structure\n\nChanges in v2 against v1 in this subpatch:\n  - added error handling in w1_f19_error()\n  - added struct i2c_adapter_quirks\n  - removed unnecessary checks of I2C address and read count\n  - cleaned up error codes\n    + EOPNOTSUPP for read/write count == 0\n    + ETIMEDOUT for busy timeout\n    + ENXIO for no reply of I2C slave\n    + EAGAIN for I2C invalid start condition\n    + EIO for all w1 errors\n  - devm_kzalloc() instead of kzalloc()\n  - i2c speed to be set as 100, 400, 900 instead of 0, 1, 2\n  - added driver parameter documentation\n  - added sysfs documentation\n  - Kconfig fixed\n\n Documentation/ABI/testing/sysfs-driver-w1_ds28e17 |  21 +\n Documentation/w1/slaves/00-INDEX                  |   2 +\n Documentation/w1/slaves/w1_ds28e17                |  68 ++\n drivers/w1/slaves/Kconfig                         |  15 +\n drivers/w1/slaves/Makefile                        |   1 +\n drivers/w1/slaves/w1_ds28e17.c                    | 772 ++++++++++++++++++++++\n drivers/w1/w1_family.h                            |   1 +\n 7 files changed, 880 insertions(+)\n create mode 100644 Documentation/ABI/testing/sysfs-driver-w1_ds28e17\n create mode 100644 Documentation/w1/slaves/w1_ds28e17\n create mode 100644 drivers/w1/slaves/w1_ds28e17.c",
    "diff": "diff --git a/Documentation/ABI/testing/sysfs-driver-w1_ds28e17 b/Documentation/ABI/testing/sysfs-driver-w1_ds28e17\nnew file mode 100644\nindex 0000000..b97b101\n--- /dev/null\n+++ b/Documentation/ABI/testing/sysfs-driver-w1_ds28e17\n@@ -0,0 +1,21 @@\n+What:\t\t/sys/bus/w1/devices/19-<id>/speed\n+Date:\t\tJul 2016\n+KernelVersion:\t4.7\n+Contact:\tJan Kandziora <jjj@gmx.de>\n+Description:\tWhen written, this file sets the I2C speed on the connected\n+\t\tDS28E17 chip. When read, it reads the current setting from\n+\t\tthe DS28E17 chip.\n+\t\tValid values: 100, 400, 900 [kBaud].\n+\t\tDefault 100, can be set by w1_ds28e17.speed= module parameter.\n+Users:\t\tw1_ds28e17 driver\n+\n+What:\t\t/sys/bus/w1/devices/19-<id>/stretch\n+Date:\t\tJul 2016\n+KernelVersion:\t4.7\n+Contact:\tJan Kandziora <jjj@gmx.de>\n+Description:\tWhen written, this file sets the multiplier used to calculate\n+\t\tthe busy timeout for I2C operations on the connected DS28E17\n+\t\tchip. When read, returns the current setting.\n+\t\tValid values: 1 to 9.\n+\t\tDefault 1, can be set by w1_ds28e17.stretch= module parameter.\n+Users:\t\tw1_ds28e17 driver\ndiff --git a/Documentation/w1/slaves/00-INDEX b/Documentation/w1/slaves/00-INDEX\nindex 8d76718..68946f8 100644\n--- a/Documentation/w1/slaves/00-INDEX\n+++ b/Documentation/w1/slaves/00-INDEX\n@@ -10,3 +10,5 @@ w1_ds2438\n \t- The Maxim/Dallas Semiconductor ds2438 smart battery monitor.\n w1_ds28e04\n \t- The Maxim/Dallas Semiconductor ds28e04 eeprom.\n+w1_ds28e17\n+\t- The Maxim/Dallas Semiconductor ds28e17 1-Wire-to-I2C Master Bridge.\ndiff --git a/Documentation/w1/slaves/w1_ds28e17 b/Documentation/w1/slaves/w1_ds28e17\nnew file mode 100644\nindex 0000000..e82e16e\n--- /dev/null\n+++ b/Documentation/w1/slaves/w1_ds28e17\n@@ -0,0 +1,68 @@\n+Kernel driver w1_ds28e17\n+========================\n+\n+Supported chips:\n+  * Maxim DS28E17 1-Wire-to-I2C Master Bridge\n+\n+supported family codes:\n+\tW1_FAMILY_DS28E17\t0x19\n+\n+Author: Jan Kandziora <jjj@gmx.de>\n+\n+\n+Description\n+-----------\n+The DS28E17 is a Onewire slave device which acts as an I2C bus master.\n+\n+This driver creates a new I2C bus for any DS28E17 device detected. I2C buses\n+come and go as the DS28E17 devices come and go. I2C slave devices connected to\n+a DS28E17 can be accessed by the kernel or userspace tools as if they were\n+connected to a \"native\" I2C bus master.\n+\n+\n+An udev rule like the following\n+-------------------------------------------------------------------------------\n+SUBSYSTEM==\"i2c-dev\", KERNEL==\"i2c-[0-9]*\", ATTRS{name}==\"w1-19-*\", \\\n+        SYMLINK+=\"i2c-$attr{name}\"\n+-------------------------------------------------------------------------------\n+may be used to create stable /dev/i2c- entries based on the unique id of the\n+DS28E17 chip.\n+\n+\n+Driver parameters are:\n+\n+speed:\n+\tThis sets up the default I2C speed a DS28E17 get configured for as soon\n+\tit is connected. The power-on default\tof the DS28E17 is 400kBaud, but\n+\tchips may come and go on the Onewire bus without being de-powered and\n+\tas soon the \"w1_ds28e17\" driver notices a freshly connected, or\n+\treconnected DS28E17 device on the Onewire bus, it will re-apply this\n+\tsetting.\n+\n+\tValid values are 100, 400, 900 [kBaud]. Any other value means to leave\n+\talone the current DS28E17 setting on detect. The default value is 100.\n+\n+stretch:\n+\tThis sets up the default stretch value used for freshly connected\n+\tDS28E17 devices. It is a multiplier used on the calculation of the busy\n+\twait time for an I2C transfer. This is to account for I2C slave devices\n+\twhich make heavy use of the I2C clock stretching feature and thus, the\n+\tneeded timeout cannot be pre-calculated correctly. As the w1_ds28e17\n+\tdriver checks the DS28E17's busy flag in a loop after the precalculated\n+\twait time, it should be hardly needed to tweak this setting.\n+\n+\tLeave it at 1 unless you get ETIMEDOUT errors and a \"w1_slave_driver\n+\t19-00000002dbd8: busy timeout\" in the kernel log.\n+\n+\tValid values are 1 to 9. The default is 1.\n+\n+\n+The driver creates sysfs files /sys/bus/w1/devices/19-<id>/speed and\n+/sys/bus/w1/devices/19-<id>/stretch for each device, preloaded with the default\n+settings from the driver parameters. They may be changed anytime. In addition a\n+directory /sys/bus/w1/devices/19-<id>/i2c-<nnn> for the I2C bus master sysfs\n+structure is created.\n+\n+\n+See https://github.com/ianka/w1_ds28e17 for even more information.\n+\ndiff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig\nindex fb68465..b94c55c 100644\n--- a/drivers/w1/slaves/Kconfig\n+++ b/drivers/w1/slaves/Kconfig\n@@ -140,6 +140,21 @@ config W1_SLAVE_DS28E04\n \n \t  If you are unsure, say N.\n \n+config W1_SLAVE_DS28E17\n+\ttristate \"1-wire-to-I2C master bridge (DS28E17)\"\n+\tselect CRC16\n+\tdepends on I2C\n+\thelp\n+\t  Say Y here if you want to use the DS28E17 1-wire-to-I2C master bridge.\n+\t  For each DS28E17 detected, a new I2C adapter is created within the\n+\t  kernel. I2C devices on that bus can be configured to be used by the\n+\t  kernel and userspace tools as on any other \"native\" I2C bus.\n+\n+\t  This driver is also available as a module. If so, the module\n+\t  will be called w1_ds28e17.\n+\n+\t  If you are unsure, say N.\n+\n config W1_SLAVE_BQ27000\n \ttristate \"BQ27000 slave support\"\n \thelp\ndiff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile\nindex 54c63e4..5ec927b 100644\n--- a/drivers/w1/slaves/Makefile\n+++ b/drivers/w1/slaves/Makefile\n@@ -17,3 +17,4 @@ obj-$(CONFIG_W1_SLAVE_DS2780)\t+= w1_ds2780.o\n obj-$(CONFIG_W1_SLAVE_DS2781)\t+= w1_ds2781.o\n obj-$(CONFIG_W1_SLAVE_BQ27000)\t+= w1_bq27000.o\n obj-$(CONFIG_W1_SLAVE_DS28E04)\t+= w1_ds28e04.o\n+obj-$(CONFIG_W1_SLAVE_DS28E17)\t+= w1_ds28e17.o\ndiff --git a/drivers/w1/slaves/w1_ds28e17.c b/drivers/w1/slaves/w1_ds28e17.c\nnew file mode 100644\nindex 0000000..3e217e9\n--- /dev/null\n+++ b/drivers/w1/slaves/w1_ds28e17.c\n@@ -0,0 +1,772 @@\n+/*\n+ *\tw1_ds28e17.c - w1 family 19 (DS28E17) driver\n+ *\n+ * Copyright (c) 2016 Jan Kandziora <jjj@gmx.de>\n+ *\n+ * This source code is licensed under the GNU General Public License,\n+ * Version 2. See the file COPYING for more details.\n+ */\n+\n+#include <linux/crc16.h>\n+#include <linux/delay.h>\n+#include <linux/device.h>\n+#include <linux/i2c.h>\n+#include <linux/kernel.h>\n+#include <linux/module.h>\n+#include <linux/moduleparam.h>\n+#include <linux/slab.h>\n+#include <linux/types.h>\n+#include <linux/uaccess.h>\n+\n+#define CRC16_INIT 0\n+\n+#include \"../w1.h\"\n+#include \"../w1_int.h\"\n+#include \"../w1_family.h\"\n+\n+\n+/* Module setup. */\n+MODULE_LICENSE(\"GPL v2\");\n+MODULE_AUTHOR(\"Jan Kandziora <jjj@gmx.de>\");\n+MODULE_DESCRIPTION(\"w1 family 19 driver for DS28E17, 1-wire to I2C master bridge\");\n+MODULE_ALIAS(\"w1-family-\" __stringify(W1_FAMILY_DS28E17));\n+\n+\n+/* Default I2C speed to be set when a DS28E17 is detected. */\n+static int i2c_speed = 100;\n+module_param_named(speed, i2c_speed, int, (S_IRUSR | S_IWUSR));\n+MODULE_PARM_DESC(speed, \"Default I2C speed to be set when a DS28E17 is detected\");\n+\n+/* Default I2C stretch value to be set when a DS28E17 is detected. */\n+static char i2c_stretch = 1;\n+module_param_named(stretch, i2c_stretch, byte, (S_IRUSR | S_IWUSR));\n+MODULE_PARM_DESC(stretch, \"Default I2C stretch value to be set when a DS28E17 is detected\");\n+\n+/* DS28E17 device command codes. */\n+#define W1_F19_WRITE_DATA_WITH_STOP      0x4B\n+#define W1_F19_WRITE_DATA_NO_STOP        0x5A\n+#define W1_F19_WRITE_DATA_ONLY           0x69\n+#define W1_F19_WRITE_DATA_ONLY_WITH_STOP 0x78\n+#define W1_F19_READ_DATA_WITH_STOP       0x87\n+#define W1_F19_WRITE_READ_DATA_WITH_STOP 0x2D\n+#define W1_F19_WRITE_CONFIGURATION       0xD2\n+#define W1_F19_READ_CONFIGURATION        0xE1\n+#define W1_F19_ENABLE_SLEEP_MODE         0x1E\n+#define W1_F19_READ_DEVICE_REVISION      0xC4\n+\n+/* DS28E17 status bits */\n+#define W1_F19_STATUS_CRC     0x01\n+#define W1_F19_STATUS_ADDRESS 0x02\n+#define W1_F19_STATUS_START   0x08\n+\n+/*\n+ * Maximum number of I2C bytes to transfer within one CRC16 protected onewire\n+ * command.\n+ * */\n+#define W1_F19_WRITE_DATA_LIMIT 255\n+\n+/* Maximum number of I2C bytes to read with one onewire command. */\n+#define W1_F19_READ_DATA_LIMIT 255\n+\n+/* Constants for calculating the busy sleep. */\n+#define W1_F19_BUSY_TIMEBASES { 90, 23, 10 }\n+#define W1_F19_BUSY_GRATUITY  1000\n+\n+/* Number of checks for the busy flag before timeout. */\n+#define W1_F19_BUSY_CHECKS 1000\n+\n+\n+/* Slave specific data. */\n+struct w1_f19_data {\n+\tu8 speed;\n+\tu8 stretch;\n+\tstruct i2c_adapter adapter;\n+};\n+\n+\n+/* Wait a while until the busy flag clears. */\n+static int w1_f19_i2c_busy_wait(struct w1_slave *sl, size_t count)\n+{\n+\tconst unsigned long timebases[3] = W1_F19_BUSY_TIMEBASES;\n+\tstruct w1_f19_data *data = sl->family_data;\n+\tunsigned int checks;\n+\n+\t/* Check the busy flag first in any case.*/\n+\tif (w1_touch_bit(sl->master, 1) == 0)\n+\t\treturn 0;\n+\n+\t/*\n+\t * Do a generously long sleep in the beginning,\n+\t * as we have to wait at least this time for all\n+\t * the I2C bytes at the given speed to be transferred.\n+\t */\n+\tusleep_range(timebases[data->speed] * (data->stretch) * count,\n+\t\ttimebases[data->speed] * (data->stretch) * count\n+\t\t+ W1_F19_BUSY_GRATUITY);\n+\n+\t/* Now continusly check the busy flag sent by the DS28E17. */\n+\tchecks = W1_F19_BUSY_CHECKS;\n+\twhile ((checks--) > 0) {\n+\t\t/* Return success if the busy flag is cleared. */\n+\t\tif (w1_touch_bit(sl->master, 1) == 0)\n+\t\t\treturn 0;\n+\n+\t\t/* Wait one non-streched byte timeslot. */\n+\t\tudelay(timebases[data->speed]);\n+\t}\n+\n+\t/* Timeout. */\n+\tdev_warn(&sl->dev, \"busy timeout\\n\");\n+\treturn -ETIMEDOUT;\n+}\n+\n+\n+/* Utility function: result. */\n+static size_t w1_f19_error(struct w1_slave *sl, u8 w1_buf[])\n+{\n+\t/* Warnings. */\n+\tif (w1_buf[0] & W1_F19_STATUS_CRC)\n+\t\tdev_warn(&sl->dev, \"crc16 mismatch\\n\");\n+\tif (w1_buf[0] & W1_F19_STATUS_ADDRESS)\n+\t\tdev_warn(&sl->dev, \"i2c device not responding\\n\");\n+\tif ((w1_buf[0] & (W1_F19_STATUS_CRC | W1_F19_STATUS_ADDRESS)) == 0\n+\t\t\t&& w1_buf[1] != 0) {\n+\t\tdev_warn(&sl->dev, \"i2c short write, %d bytes not acknowledged\\n\",\n+\t\t\tw1_buf[1]);\n+\t}\n+\n+\t/* Check error conditions. */\n+\tif (w1_buf[0] & W1_F19_STATUS_ADDRESS)\n+\t\treturn -ENXIO;\n+\tif (w1_buf[0] & W1_F19_STATUS_START)\n+\t\treturn -EAGAIN;\n+\tif (w1_buf[0] != 0 || w1_buf[1] != 0)\n+\t\treturn -EIO;\n+\n+\t/* All ok. */\n+\treturn 0;\n+}\n+\n+\n+/* Utility function: write data to I2C slave, single chunk. */\n+static int __w1_f19_i2c_write(struct w1_slave *sl,\n+\tconst u8 *command, size_t command_count,\n+\tconst u8 *buffer, size_t count)\n+{\n+\tu16 crc;\n+\tint error;\n+\tu8 w1_buf[2];\n+\n+\t/* Send command and I2C data to DS28E17. */\n+\tcrc = crc16(CRC16_INIT, command, command_count);\n+\tw1_write_block(sl->master, command, command_count);\n+\n+\tw1_buf[0] = count;\n+\tcrc = crc16(crc, w1_buf, 1);\n+\tw1_write_8(sl->master, w1_buf[0]);\n+\n+\tcrc = crc16(crc, buffer, count);\n+\tw1_write_block(sl->master, buffer, count);\n+\n+\tw1_buf[0] = ~(crc & 0xFF);\n+\tw1_buf[1] = ~((crc >> 8) & 0xFF);\n+\tw1_write_block(sl->master, w1_buf, 2);\n+\n+\t/* Wait until busy flag clears (or timeout). */\n+\tif (w1_f19_i2c_busy_wait(sl, count + 1) < 0)\n+\t\treturn -ETIMEDOUT;\n+\n+\t/* Read status from DS28E17. */\n+\tw1_read_block(sl->master, w1_buf, 2);\n+\n+\t/* Check error conditions. */\n+\terror = w1_f19_error(sl, w1_buf);\n+\tif (error < 0)\n+\t\treturn error;\n+\n+\t/* Return number of bytes written. */\n+\treturn count;\n+}\n+\n+\n+/* Write data to I2C slave. */\n+static int w1_f19_i2c_write(struct w1_slave *sl, u16 i2c_address,\n+\tconst u8 *buffer, size_t count, bool stop)\n+{\n+\tint result;\n+\tint remaining = count;\n+\tconst u8 *p;\n+\tu8 command[2];\n+\n+\t/* Check input. */\n+\tif (count == 0)\n+\t\treturn -EOPNOTSUPP;\n+\n+\t/* Check whether we need multiple commands. */\n+\tif (count <= W1_F19_WRITE_DATA_LIMIT) {\n+\t\t/*\n+\t\t * Small data amount. Data can be sent with\n+\t\t * a single onewire command.\n+\t\t */\n+\n+\t\t/* Send all data to DS28E17. */\n+\t\tcommand[0] = (stop ? W1_F19_WRITE_DATA_WITH_STOP\n+\t\t\t: W1_F19_WRITE_DATA_NO_STOP);\n+\t\tcommand[1] = i2c_address << 1;\n+\t\tresult = __w1_f19_i2c_write(sl, command, 2, buffer, count);\n+\t} else {\n+\t\t/* Large data amount. Data has to be sent in multiple chunks. */\n+\n+\t\t/* Send first chunk to DS28E17. */\n+\t\tp = buffer;\n+\t\tcommand[0] = W1_F19_WRITE_DATA_NO_STOP;\n+\t\tcommand[1] = i2c_address << 1;\n+\t\tresult = __w1_f19_i2c_write(sl, command, 2, p,\n+\t\t\tW1_F19_WRITE_DATA_LIMIT);\n+\t\tif (result < 0)\n+\t\t\treturn result;\n+\n+\t\t/* Resume to same DS28E17. */\n+\t\tif (w1_reset_resume_command(sl->master))\n+\t\t\treturn -EIO;\n+\n+\t\t/* Next data chunk. */\n+\t\tp += W1_F19_WRITE_DATA_LIMIT;\n+\t\tremaining -= W1_F19_WRITE_DATA_LIMIT;\n+\n+\t\twhile (remaining > W1_F19_WRITE_DATA_LIMIT) {\n+\t\t\t/* Send intermediate chunk to DS28E17. */\n+\t\t\tcommand[0] = W1_F19_WRITE_DATA_ONLY;\n+\t\t\tresult = __w1_f19_i2c_write(sl, command, 1, p,\n+\t\t\t\t\tW1_F19_WRITE_DATA_LIMIT);\n+\t\t\tif (result < 0)\n+\t\t\t\treturn result;\n+\n+\t\t\t/* Resume to same DS28E17. */\n+\t\t\tif (w1_reset_resume_command(sl->master))\n+\t\t\t\treturn -EIO;\n+\n+\t\t\t/* Next data chunk. */\n+\t\t\tp += W1_F19_WRITE_DATA_LIMIT;\n+\t\t\tremaining -= W1_F19_WRITE_DATA_LIMIT;\n+\t\t}\n+\n+\t\t/* Send final chunk to DS28E17. */\n+\t\tcommand[0] = (stop ? W1_F19_WRITE_DATA_ONLY_WITH_STOP\n+\t\t\t: W1_F19_WRITE_DATA_ONLY);\n+\t\tresult = __w1_f19_i2c_write(sl, command, 1, p, remaining);\n+\t}\n+\n+\treturn result;\n+}\n+\n+\n+/* Read data from I2C slave. */\n+static int w1_f19_i2c_read(struct w1_slave *sl, u16 i2c_address,\n+\tu8 *buffer, size_t count)\n+{\n+\tu16 crc;\n+\tint error;\n+\tu8 w1_buf[5];\n+\n+\t/* Check input. */\n+\tif (count == 0)\n+\t\treturn -EOPNOTSUPP;\n+\n+\t/* Send command to DS28E17. */\n+\tw1_buf[0] = W1_F19_READ_DATA_WITH_STOP;\n+\tw1_buf[1] = i2c_address << 1 | 0x01;\n+\tw1_buf[2] = count;\n+\tcrc = crc16(CRC16_INIT, w1_buf, 3);\n+\tw1_buf[3] = ~(crc & 0xFF);\n+\tw1_buf[4] = ~((crc >> 8) & 0xFF);\n+\tw1_write_block(sl->master, w1_buf, 5);\n+\n+\t/* Wait until busy flag clears (or timeout). */\n+\tif (w1_f19_i2c_busy_wait(sl, count + 1) < 0)\n+\t\treturn -ETIMEDOUT;\n+\n+\t/* Read status from DS28E17. */\n+\tw1_buf[0] = w1_read_8(sl->master);\n+\tw1_buf[1] = 0;\n+\n+\t/* Check error conditions. */\n+\terror = w1_f19_error(sl, w1_buf);\n+\tif (error < 0)\n+\t\treturn error;\n+\n+\t/* Read received I2C data from DS28E17. */\n+\treturn w1_read_block(sl->master, buffer, count);\n+}\n+\n+\n+/* Write to, then read data from I2C slave. */\n+static int w1_f19_i2c_write_read(struct w1_slave *sl, u16 i2c_address,\n+\tconst u8 *wbuffer, size_t wcount, u8 *rbuffer, size_t rcount)\n+{\n+\tu16 crc;\n+\tint error;\n+\tu8 w1_buf[3];\n+\n+\t/* Check input. */\n+\tif (wcount == 0 || rcount == 0)\n+\t\treturn -EOPNOTSUPP;\n+\n+\t/* Send command and I2C data to DS28E17. */\n+\tw1_buf[0] = W1_F19_WRITE_READ_DATA_WITH_STOP;\n+\tw1_buf[1] = i2c_address << 1;\n+\tw1_buf[2] = wcount;\n+\tcrc = crc16(CRC16_INIT, w1_buf, 3);\n+\tw1_write_block(sl->master, w1_buf, 3);\n+\n+\tcrc = crc16(crc, wbuffer, wcount);\n+\tw1_write_block(sl->master, wbuffer, wcount);\n+\n+\tw1_buf[0] = rcount;\n+\tcrc = crc16(crc, w1_buf, 1);\n+\tw1_buf[1] = ~(crc & 0xFF);\n+\tw1_buf[2] = ~((crc >> 8) & 0xFF);\n+\tw1_write_block(sl->master, w1_buf, 3);\n+\n+\t/* Wait until busy flag clears (or timeout). */\n+\tif (w1_f19_i2c_busy_wait(sl, wcount + rcount + 2) < 0)\n+\t\treturn -ETIMEDOUT;\n+\n+\t/* Read status from DS28E17. */\n+\tw1_read_block(sl->master, w1_buf, 2);\n+\n+\t/* Check error conditions. */\n+\terror = w1_f19_error(sl, w1_buf);\n+\tif (error < 0)\n+\t\treturn error;\n+\n+\t/* Read received I2C data from DS28E17. */\n+\treturn w1_read_block(sl->master, rbuffer, rcount);\n+}\n+\n+\n+/* Do an I2C master transfer. */\n+static int w1_f19_i2c_master_transfer(struct i2c_adapter *adapter,\n+\tstruct i2c_msg *msgs, int num)\n+{\n+\tstruct w1_slave *sl = (struct w1_slave *) adapter->algo_data;\n+\tint i = 0;\n+\tint result = 0;\n+\n+\t/* Start onewire transaction. */\n+\tmutex_lock(&sl->master->bus_mutex);\n+\n+\t/* Select DS28E17. */\n+\tif (w1_reset_select_slave(sl)) {\n+\t\ti = -EIO;\n+\t\tgoto error;\n+\t}\n+\n+\t/* Loop while there are still messages to transfer. */\n+\twhile (i < num) {\n+\t\t/*\n+\t\t * Check for special case: Small write followed\n+\t\t * by read to same I2C device.\n+\t\t */\n+\t\tif (i < (num-1)\n+\t\t\t&& msgs[i].addr == msgs[i+1].addr\n+\t\t\t&& !(msgs[i].flags & I2C_M_RD)\n+\t\t\t&& (msgs[i+1].flags & I2C_M_RD)\n+\t\t\t&& (msgs[i].len <= W1_F19_WRITE_DATA_LIMIT)) {\n+\t\t\t/*\n+\t\t\t * The DS28E17 has a combined transfer\n+\t\t\t * for small write+read.\n+\t\t\t */\n+\t\t\tresult = w1_f19_i2c_write_read(sl, msgs[i].addr,\n+\t\t\t\tmsgs[i].buf, msgs[i].len,\n+\t\t\t\tmsgs[i+1].buf, msgs[i+1].len);\n+\t\t\tif (result < 0) {\n+\t\t\t\ti = result;\n+\t\t\t\tgoto error;\n+\t\t\t}\n+\n+\t\t\t/*\n+\t\t\t * Check if we should interpret the read data\n+\t\t\t * as a length byte. The DS28E17 unfortunately\n+\t\t\t * has no read without stop, so we can just do\n+\t\t\t * another simple read in that case.\n+\t\t\t */\n+\t\t\tif (msgs[i+1].flags & I2C_M_RECV_LEN) {\n+\t\t\t\tresult = w1_f19_i2c_read(sl, msgs[i+1].addr,\n+\t\t\t\t\t&(msgs[i+1].buf[1]), msgs[i+1].buf[0]);\n+\t\t\t\tif (result < 0) {\n+\t\t\t\t\ti = result;\n+\t\t\t\t\tgoto error;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\t/* Eat up read message, too. */\n+\t\t\ti++;\n+\t\t} else if (msgs[i].flags & I2C_M_RD) {\n+\t\t\t/* Read transfer. */\n+\t\t\tresult = w1_f19_i2c_read(sl, msgs[i].addr,\n+\t\t\t\tmsgs[i].buf, msgs[i].len);\n+\t\t\tif (result < 0) {\n+\t\t\t\ti = result;\n+\t\t\t\tgoto error;\n+\t\t\t}\n+\n+\t\t\t/*\n+\t\t\t * Check if we should interpret the read data\n+\t\t\t * as a length byte. The DS28E17 unfortunately\n+\t\t\t * has no read without stop, so we can just do\n+\t\t\t * another simple read in that case.\n+\t\t\t */\n+\t\t\tif (msgs[i].flags & I2C_M_RECV_LEN) {\n+\t\t\t\tresult = w1_f19_i2c_read(sl,\n+\t\t\t\t\tmsgs[i].addr,\n+\t\t\t\t\t&(msgs[i].buf[1]),\n+\t\t\t\t\tmsgs[i].buf[0]);\n+\t\t\t\tif (result < 0) {\n+\t\t\t\t\ti = result;\n+\t\t\t\t\tgoto error;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t} else {\n+\t\t\t/*\n+\t\t\t * Write transfer.\n+\t\t\t * Stop condition only for last\n+\t\t\t * transfer.\n+\t\t\t */\n+\t\t\tresult = w1_f19_i2c_write(sl,\n+\t\t\t\tmsgs[i].addr,\n+\t\t\t\tmsgs[i].buf,\n+\t\t\t\tmsgs[i].len,\n+\t\t\t\ti == (num-1));\n+\t\t\tif (result < 0) {\n+\t\t\t\ti = result;\n+\t\t\t\tgoto error;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* Next message. */\n+\t\ti++;\n+\n+\t\t/* Are there still messages to send/receive? */\n+\t\tif (i < num) {\n+\t\t\t/* Yes. Resume to same DS28E17. */\n+\t\t\tif (w1_reset_resume_command(sl->master)) {\n+\t\t\t\ti = -EIO;\n+\t\t\t\tgoto error;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+error:\n+\t/* End onewire transaction. */\n+\tmutex_unlock(&sl->master->bus_mutex);\n+\n+\t/* Return number of messages processed or error. */\n+\treturn i;\n+}\n+\n+\n+/* Get I2C adapter functionality. */\n+static u32 w1_f19_i2c_functionality(struct i2c_adapter *adapter)\n+{\n+\t/*\n+\t * Plain I2C functions only.\n+\t * SMBus is emulated by the kernel's I2C layer.\n+\t * No \"I2C_FUNC_SMBUS_QUICK\"\n+\t * No \"I2C_FUNC_SMBUS_READ_BLOCK_DATA\"\n+\t * No \"I2C_FUNC_SMBUS_BLOCK_PROC_CALL\"\n+\t */\n+\treturn I2C_FUNC_I2C |\n+\t\tI2C_FUNC_SMBUS_BYTE |\n+\t\tI2C_FUNC_SMBUS_BYTE_DATA |\n+\t\tI2C_FUNC_SMBUS_WORD_DATA |\n+\t\tI2C_FUNC_SMBUS_PROC_CALL |\n+\t\tI2C_FUNC_SMBUS_WRITE_BLOCK_DATA |\n+\t\tI2C_FUNC_SMBUS_I2C_BLOCK |\n+\t\tI2C_FUNC_SMBUS_PEC;\n+}\n+\n+\n+/* I2C adapter quirks. */\n+static const struct i2c_adapter_quirks w1_f19_i2c_adapter_quirks = {\n+\t.max_read_len = W1_F19_READ_DATA_LIMIT,\n+};\n+\n+/* I2C algorithm. */\n+static const struct i2c_algorithm w1_f19_i2c_algorithm = {\n+\t.master_xfer    = w1_f19_i2c_master_transfer,\n+\t.functionality  = w1_f19_i2c_functionality,\n+};\n+\n+\n+/* Read I2C speed from DS28E17. */\n+static int w1_f19_get_i2c_speed(struct w1_slave *sl)\n+{\n+\tstruct w1_f19_data *data = sl->family_data;\n+\tint result = -EIO;\n+\n+\t/* Start onewire transaction. */\n+\tmutex_lock(&sl->master->bus_mutex);\n+\n+\t/* Select slave. */\n+\tif (w1_reset_select_slave(sl))\n+\t\tgoto error;\n+\n+\t/* Read slave configuration byte. */\n+\tw1_write_8(sl->master, W1_F19_READ_CONFIGURATION);\n+\tresult = w1_read_8(sl->master);\n+\tif (result < 0 || result > 2) {\n+\t\tresult = -EIO;\n+\t\tgoto error;\n+\t}\n+\n+\t/* Update speed in slave specific data. */\n+\tdata->speed = result;\n+\n+error:\n+\t/* End onewire transaction. */\n+\tmutex_unlock(&sl->master->bus_mutex);\n+\n+\treturn result;\n+}\n+\n+\n+/* Set I2C speed on DS28E17. */\n+static int __w1_f19_set_i2c_speed(struct w1_slave *sl, u8 speed)\n+{\n+\tstruct w1_f19_data *data = sl->family_data;\n+\tconst int i2c_speeds[3] = { 100, 400, 900 };\n+\tu8 w1_buf[2];\n+\n+\t/* Select slave. */\n+\tif (w1_reset_select_slave(sl))\n+\t\treturn -EIO;\n+\n+\tw1_buf[0] = W1_F19_WRITE_CONFIGURATION;\n+\tw1_buf[1] = speed;\n+\tw1_write_block(sl->master, w1_buf, 2);\n+\n+\t/* Update speed in slave specific data. */\n+\tdata->speed = speed;\n+\n+\tdev_info(&sl->dev, \"i2c speed set to %d kBaud\\n\", i2c_speeds[speed]);\n+\n+\treturn 0;\n+}\n+\n+static int w1_f19_set_i2c_speed(struct w1_slave *sl, u8 speed)\n+{\n+\tint result;\n+\n+\t/* Start onewire transaction. */\n+\tmutex_lock(&sl->master->bus_mutex);\n+\n+\t/* Set I2C speed on DS28E17. */\n+\tresult = __w1_f19_set_i2c_speed(sl, speed);\n+\n+\t/* End onewire transaction. */\n+\tmutex_unlock(&sl->master->bus_mutex);\n+\n+\treturn result;\n+}\n+\n+\n+/* Sysfs attributes. */\n+\n+/* I2C speed attribute for a single chip. */\n+static ssize_t speed_show(struct device *dev, struct device_attribute *attr,\n+\t\t\t     char *buf)\n+{\n+\tstruct w1_slave *sl = dev_to_w1_slave(dev);\n+\tint result;\n+\n+\t/* Read current speed from slave. Updates data->speed. */\n+\tresult = w1_f19_get_i2c_speed(sl);\n+\tif (result < 0)\n+\t\treturn result;\n+\n+\t/* Return current speed value. */\n+\treturn sprintf(buf, \"%d\\n\", result);\n+}\n+\n+static ssize_t speed_store(struct device *dev, struct device_attribute *attr,\n+\t\t\t      const char *buf, size_t count)\n+{\n+\tstruct w1_slave *sl = dev_to_w1_slave(dev);\n+\tint error;\n+\n+\t/* Valid values are: \"100\", \"400\", \"900\" */\n+\tif (count < 3 || count > 4 || !buf)\n+\t\treturn -EINVAL;\n+\tif (count == 4 && buf[3] != '\\n')\n+\t\treturn -EINVAL;\n+\tif (buf[1] != '0' || buf[2] != '0')\n+\t\treturn -EINVAL;\n+\n+\t/* Set speed on slave. */\n+\tswitch (buf[0]) {\n+\tcase '1':\n+\t\terror = w1_f19_set_i2c_speed(sl, 0);\n+\t\tbreak;\n+\tcase '4':\n+\t\terror = w1_f19_set_i2c_speed(sl, 1);\n+\t\tbreak;\n+\tcase '9':\n+\t\terror = w1_f19_set_i2c_speed(sl, 2);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (error < 0)\n+\t\treturn error;\n+\n+\t/* Return bytes written. */\n+\treturn count;\n+}\n+\n+static DEVICE_ATTR_RW(speed);\n+\n+\n+/* Busy stretch attribute for a single chip. */\n+static ssize_t stretch_show(struct device *dev, struct device_attribute *attr,\n+\t\t\t     char *buf)\n+{\n+\tstruct w1_slave *sl = dev_to_w1_slave(dev);\n+\tstruct w1_f19_data *data = sl->family_data;\n+\n+\t/* Return current stretch value. */\n+\treturn sprintf(buf, \"%d\\n\", data->stretch);\n+}\n+\n+static ssize_t stretch_store(struct device *dev, struct device_attribute *attr,\n+\t\t\t      const char *buf, size_t count)\n+{\n+\tstruct w1_slave *sl = dev_to_w1_slave(dev);\n+\tstruct w1_f19_data *data = sl->family_data;\n+\n+\t/* Valid values are '1' to '9' */\n+\tif (count < 1 || count > 2 || !buf)\n+\t\treturn -EINVAL;\n+\tif (count == 2 && buf[1] != '\\n')\n+\t\treturn -EINVAL;\n+\tif (buf[0] < '1' || buf[0] > '9')\n+\t\treturn -EINVAL;\n+\n+\t/* Set busy stretch value. */\n+\tdata->stretch = buf[0] & 0x0F;\n+\n+\t/* Return bytes written. */\n+\treturn count;\n+}\n+\n+static DEVICE_ATTR_RW(stretch);\n+\n+\n+/* All attributes. */\n+static struct attribute *w1_f19_attrs[] = {\n+\t&dev_attr_speed.attr,\n+\t&dev_attr_stretch.attr,\n+\tNULL,\n+};\n+\n+static const struct attribute_group w1_f19_group = {\n+\t.attrs\t\t= w1_f19_attrs,\n+};\n+\n+static const struct attribute_group *w1_f19_groups[] = {\n+\t&w1_f19_group,\n+\tNULL,\n+};\n+\n+\n+/* Slave add and remove functions. */\n+static int w1_f19_add_slave(struct w1_slave *sl)\n+{\n+\tstruct w1_f19_data *data = NULL;\n+\n+\t/* Allocate memory for slave specific data. */\n+\tdata = devm_kzalloc(&sl->dev, sizeof(*data), GFP_KERNEL);\n+\tif (!data)\n+\t\treturn -ENOMEM;\n+\tsl->family_data = data;\n+\n+\t/* Setup default I2C speed on slave. */\n+\tswitch (i2c_speed) {\n+\tcase 100:\n+\t\t__w1_f19_set_i2c_speed(sl, 0);\n+\t\tbreak;\n+\tcase 400:\n+\t\t__w1_f19_set_i2c_speed(sl, 1);\n+\t\tbreak;\n+\tcase 900:\n+\t\t__w1_f19_set_i2c_speed(sl, 2);\n+\t\tbreak;\n+\tdefault:\n+\t\t/*\n+\t\t * A i2c_speed module parameter of anything else\n+\t\t * than 100, 400, 900 means not to touch the\n+\t\t * speed of the DS28E17.\n+\t\t * We assume 400kBaud, the power-on value.\n+\t\t */\n+\t\tdata->speed = 1;\n+\t}\n+\n+\t/*\n+\t * Setup default busy stretch\n+\t * configuration for the DS28E17.\n+\t */\n+\tdata->stretch = i2c_stretch;\n+\n+\t/* Setup I2C adapter. */\n+\tdata->adapter.owner      = THIS_MODULE;\n+\tdata->adapter.algo       = &w1_f19_i2c_algorithm;\n+\tdata->adapter.algo_data  = sl;\n+\tstrcpy(data->adapter.name, \"w1-\");\n+\tstrcat(data->adapter.name, sl->name);\n+\tdata->adapter.dev.parent = &sl->dev;\n+\tdata->adapter.quirks     = &w1_f19_i2c_adapter_quirks;\n+\n+\treturn i2c_add_adapter(&data->adapter);\n+}\n+\n+static void w1_f19_remove_slave(struct w1_slave *sl)\n+{\n+\tstruct w1_f19_data *family_data = sl->family_data;\n+\n+\t/* Delete I2C adapter. */\n+\ti2c_del_adapter(&family_data->adapter);\n+\n+\t/* Free slave specific data. */\n+\tdevm_kfree(&sl->dev, family_data);\n+\tsl->family_data = NULL;\n+}\n+\n+\n+/* Declarations within the w1 subsystem. */\n+static struct w1_family_ops w1_f19_fops = {\n+\t.add_slave = w1_f19_add_slave,\n+\t.remove_slave = w1_f19_remove_slave,\n+\t.groups = w1_f19_groups,\n+};\n+\n+static struct w1_family w1_family_19 = {\n+\t.fid = W1_FAMILY_DS28E17,\n+\t.fops = &w1_f19_fops,\n+};\n+\n+\n+/* Module init and remove functions. */\n+static int __init w1_f19_init(void)\n+{\n+\treturn w1_register_family(&w1_family_19);\n+}\n+\n+static void __exit w1_f19_fini(void)\n+{\n+\tw1_unregister_family(&w1_family_19);\n+}\n+\n+module_init(w1_f19_init);\n+module_exit(w1_f19_fini);\n+\ndiff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h\nindex 869a3ff..f675638 100644\n--- a/drivers/w1/w1_family.h\n+++ b/drivers/w1/w1_family.h\n@@ -25,6 +25,7 @@\n #define W1_FAMILY_SMEM_81\t0x81\n #define W1_FAMILY_DS2405\t0x05\n #define W1_THERM_DS18S20 \t0x10\n+#define W1_FAMILY_DS28E17\t0x19\n #define W1_FAMILY_DS28E04\t0x1C\n #define W1_COUNTER_DS2423\t0x1D\n #define W1_THERM_DS1822  \t0x22\n",
    "prefixes": [
        "v4",
        "2/2"
    ]
}