Received: by 2002:a05:6358:701b:b0:131:369:b2a3 with SMTP id 27csp2774077rwo; Mon, 24 Jul 2023 00:36:07 -0700 (PDT) X-Google-Smtp-Source: APBJJlGk6EBmbu6BrrlOBBqb20ytIuBpiYkCk0530AlpKcmsQ4a8Ie51pUOg5b/2wpR2B1ONckTw X-Received: by 2002:aa7:c911:0:b0:522:3a1d:c233 with SMTP id b17-20020aa7c911000000b005223a1dc233mr476503edt.11.1690184167618; Mon, 24 Jul 2023 00:36:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690184167; cv=none; d=google.com; s=arc-20160816; b=c7FkG4KA2W8V3Nj4wK+1NGtbozFF2SIztsIhRW/8PwWuYHrgzBG2RKVPufviW+Sn8E oXts8swBpFtgs3v9CtHPziJE9x/f03eWJb/yChuCv7KBba8x1cOCn+HZc3swS6XCMBU1 yScscZr3CH2eASv/1bnkkT0ioVzL8Wmiat8EME+SkRxaZ4S3qgPjQTplGWF4abtB05WV blq2fMlWEsIzL5Z+OENidYkWphjpoc3puogNO/MGWcRQ41O1hfEcuDGM86wyV+3ODHYX ddNALTqXvR6ir65Tq4fcoclRy2DGABmvSc/QcRpGTE5JTbxKPKsTmdfRUOhi/ET8e1Cn dGAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:subject :from:references:cc:to:content-language:user-agent:mime-version:date :message-id:sender:dkim-signature; bh=uttUN14iWZAVwdUtiFQbCYLT5h2OxzYs9j6/m7eS71s=; fh=qYQGZ48FMgeqKSntd4V9bDyuK+2BtQ6z4dvliof6ND0=; b=AgpPc3qypvULibRe+PMSTQg3ks8Z4RnWbwLjVl3nrIjKDloWGd+slIe8eMMDZxNeMx D+f4CPPSlXjcSAZ7/o6+VX/CaZOBv5/p7pzKmGSbMBPJ6iJgFJvD2DOLrbP1XEkQ0N+5 6tgybRlgLRbn48FphdwWULV9AKbUTAIwy7R6aBBCN0tCr60d8mRUttMUA3Up26K2OZLZ dMbIwTZIoX6B1347/Gr7cDjqvxvoiELsSKGRt5F3oOuw1awgGR9arFg0ZiT+7Yi57VNW otCxAyZbQFyh46Ab/6Va10gOW6/cNkr0GQ5kXsbRBtryi3Mu9LHHpMn/GngmpNX85YhO CVyg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b=szzG+Z+f; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b11-20020aa7df8b000000b0051e19396481si5939476edy.11.2023.07.24.00.35.42; Mon, 24 Jul 2023 00:36:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b=szzG+Z+f; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229937AbjGXG4v (ORCPT + 99 others); Mon, 24 Jul 2023 02:56:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229547AbjGXG4t (ORCPT ); Mon, 24 Jul 2023 02:56:49 -0400 Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23E93D2; Sun, 23 Jul 2023 23:56:48 -0700 (PDT) Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-6686a05bc66so2435710b3a.1; Sun, 23 Jul 2023 23:56:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1690181807; x=1690786607; h=content-transfer-encoding:in-reply-to:subject:from:references:cc:to :content-language:user-agent:mime-version:date:message-id:sender :from:to:cc:subject:date:message-id:reply-to; bh=uttUN14iWZAVwdUtiFQbCYLT5h2OxzYs9j6/m7eS71s=; b=szzG+Z+fQJXuKNJvXJA0/QLUCQZSg3pgnuNnno3pVZ8vmu6K9Sy1WztXZXio0pyLNM Lky+HiQVEs7DD8X8n4D8O7puTnqRXJfBK0dTmk+B5Vu9PTY73A2qym6pV+ybmKUsJnJ3 9ujY6Vrgp1HEmUq2N4jlkACfkdtF0ad43YpZyGvH00JuXBO6djqO6HvsddathObzEX2B EL9MXLhO7/ELQnSkkgiidRYUQ4Mn9pBcUT4HsFkgoos0EmlBx6/lcAhARJemLtjtyssS FF7Fgj8hkBmT6oblSigx5+S1fjYcH8h9ojPg+hBLXcM6IFe+ixlkrbNTsqXOa3g/29Zf AlUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690181807; x=1690786607; h=content-transfer-encoding:in-reply-to:subject:from:references:cc:to :content-language:user-agent:mime-version:date:message-id:sender :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=uttUN14iWZAVwdUtiFQbCYLT5h2OxzYs9j6/m7eS71s=; b=daseMkvmVDz6JLpvpRJ2b386QjcS+f1w0K49inByv9F04+Q7Pf4JQb3PX5RoHqFdqQ qt2pnDYdINSjLil5ww/gyAz9m+XHWtNXQXssoIxd6jUgB+4nAq9ToiSC3XJ1p0qPFrIC 4QOp85MMisVSl013tVauxOGJdDBAhnzYQcw5tLSqQmpPzhsvhukbrBY9L6kGdU1haaF7 jnkL9U/2Cgmhx67JrDY0RnED6tXBQ8ZiJiG/NIPBjcXstSU6Ra0ugQUldU9K+cPmyieX EeBUKAcm54jE2y2zXgh8EQlvl173Bf7ufuc4XgkaNvaiZaZxYFpQcKHqOiQU7RrVfd4W trWw== X-Gm-Message-State: ABy/qLYRCFXaY8Zl0zvCfcOfghT06NAxmTQPLyID4i6KNWFWB9gfno8J toP0l9sNu5+K4Yp0JdDe4b2L/xyr19k= X-Received: by 2002:a05:6a00:c94:b0:67a:6af6:5171 with SMTP id a20-20020a056a000c9400b0067a6af65171mr8219196pfv.13.1690181807448; Sun, 23 Jul 2023 23:56:47 -0700 (PDT) Received: from ?IPV6:2600:1700:e321:62f0:329c:23ff:fee3:9d7c? ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id v26-20020aa7809a000000b006749c22d079sm6876369pff.167.2023.07.23.23.56.46 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 23 Jul 2023 23:56:46 -0700 (PDT) Sender: Guenter Roeck Message-ID: <5a657620-c4f8-9e87-b849-601aa5bf1729@roeck-us.net> Date: Sun, 23 Jul 2023 23:56:45 -0700 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 Content-Language: en-US To: Delphine_CC_Chiu/WYHQ/Wiwynn Cc: "patrick@stwcx.xyz" , Jean Delvare , Rob Herring , Krzysztof Kozlowski , "linux-i2c@vger.kernel.org" , "linux-hwmon@vger.kernel.org" , "devicetree@vger.kernel.org" , "linux-kernel@vger.kernel.org" References: <20230424101352.28117-1-Delphine_CC_Chiu@Wiwynn.com> <20230424101352.28117-3-Delphine_CC_Chiu@Wiwynn.com> From: Guenter Roeck Subject: Re: [PATCH v1 2/2] hwmon: pmbus: Add ltc4286 driver In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, NICE_REPLY_A,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 7/23/23 23:03, Delphine_CC_Chiu/WYHQ/Wiwynn wrote: >> -----Original Message----- >> From: Guenter Roeck On Behalf Of Guenter Roeck >> Sent: Monday, April 24, 2023 10:14 PM >> To: Delphine_CC_Chiu/WYHQ/Wiwynn >> Cc: patrick@stwcx.xyz; Jean Delvare ; Rob Herring >> ; Krzysztof Kozlowski >> ; linux-i2c@vger.kernel.org; >> linux-hwmon@vger.kernel.org; devicetree@vger.kernel.org; >> linux-kernel@vger.kernel.org >> Subject: Re: [PATCH v1 2/2] hwmon: pmbus: Add ltc4286 driver >> >> Security Reminder: Please be aware that this email is sent by an external >> sender. >> >> On Mon, Apr 24, 2023 at 06:13:50PM +0800, Delphine CC Chiu wrote: >>> Add support for ltc4286 driver >> >> The patch does not add support for a driver, it adds support for a chip. > Add a driver to support ltc4286 chip > >> >>> >>> Signed-off-by: Delphine CC Chiu >>> --- >>> drivers/hwmon/pmbus/Kconfig | 9 +++ >>> drivers/hwmon/pmbus/Makefile | 1 + >>> drivers/hwmon/pmbus/ltc4286.c | 142 >>> ++++++++++++++++++++++++++++++++++ >> >> Documentation is missing. > Documentation is in patch one ([PATCH v1 1/2] dt-bindings: hwmon: Add lltc ltc4286 driver bindings) > Documentation/hwmon/ltc4286.rst is expected in this patch and not as part of the bindings. The bindings do not document the driver, they document the chip bindings. >> >>> 3 files changed, 152 insertions(+) >>> create mode 100644 drivers/hwmon/pmbus/ltc4286.c >>> >>> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig >>> index 59d9a7430499..1230d910d681 100644 >>> --- a/drivers/hwmon/pmbus/Kconfig >>> +++ b/drivers/hwmon/pmbus/Kconfig >>> @@ -218,6 +218,15 @@ config SENSORS_LTC3815 >>> This driver can also be built as a module. If so, the module will >>> be called ltc3815. >>> >>> +config SENSORS_LTC4286 >>> + bool "Linear Technologies LTC4286" >> >> Analog Devices ? > We will revise to "Analog Devices LTC4286" > >> >>> + help >>> + If you say yes here you get hardware monitoring support for Linear >>> + Technology LTC4286. >>> + >>> + This driver can also be built as a module. If so, the module will >>> + be called ltc4286. >>> + >>> config SENSORS_MAX15301 >>> tristate "Maxim MAX15301" >>> help >>> diff --git a/drivers/hwmon/pmbus/Makefile >>> b/drivers/hwmon/pmbus/Makefile index 3ae019916267..540265539580 >> 100644 >>> --- a/drivers/hwmon/pmbus/Makefile >>> +++ b/drivers/hwmon/pmbus/Makefile >>> @@ -23,6 +23,7 @@ obj-$(CONFIG_SENSORS_LM25066) += >> lm25066.o >>> obj-$(CONFIG_SENSORS_LT7182S) += lt7182s.o >>> obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o >>> obj-$(CONFIG_SENSORS_LTC3815) += ltc3815.o >>> +obj-$(CONFIG_SENSORS_LTC4286) += ltc4286.o >>> obj-$(CONFIG_SENSORS_MAX15301) += max15301.o >>> obj-$(CONFIG_SENSORS_MAX16064) += max16064.o >>> obj-$(CONFIG_SENSORS_MAX16601) += max16601.o >>> diff --git a/drivers/hwmon/pmbus/ltc4286.c >>> b/drivers/hwmon/pmbus/ltc4286.c new file mode 100644 index >>> 000000000000..474f4ec9107c >>> --- /dev/null >>> +++ b/drivers/hwmon/pmbus/ltc4286.c >>> @@ -0,0 +1,142 @@ >>> +// SPDX-License-Identifier: GPL-2.0-or-later >>> +/* >>> + * Hardware monitoring driver for LTC4286 Hot-Swap Controller >>> + * >>> + * Copyright (c) 2023 Linear Technology >> >> Really ? > We will remove the copyright declaration as it was false reference from other drivers > Chip vendor doesn't support this driver, so we implement it for our own use and contribute it as Wiwynn is a system manufacturer, our server products use this chip. > >> >>> + */ >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include "pmbus.h" >>> + >>> +// LTC4286 register >> >> Please no C++ comments in the code. > We will revise to /* LTC4286 register */ > >> >>> +#define LTC4286_MFR_CONFIG1 (0xF2) >> >> Unnecessary ( ) > We will revise to #define LTC4286_MFR_CONFIG1 0xF2 > >> >>> + >>> +// LTC4286 configuration >>> +#define VRANGE_SELECT (1 << 1) >> >> #defineDEFINEvalue, please. Also, please use BIT() macros where >> appropriate. > We will revise to below. > #define VRANGE_SELECT_BIT BIT(1) > >>> + >>> +#define LTC4286_MFR_ID_SIZE 3 >>> + >>> +enum chips { ltc4286, ltc4287 }; >> >> There is no LTC4287 according to information available in public. >> It has not even be announced. >> >> Besides, the above enum is not really used anywhere and therefore has zero >> value. Maybe the LTC4287 is not yet released. Even then, there is no value >> listing it here because its parameters seem to be identical to LTC4286. > It has been announced on Analog Devices website. No, it has not. > Please refer to this link: https://www.analog.com/en/products/ltc2487.html#product-overview > enum chips { ltc4286 = 0, ltc4287 }; > Use in v1 line 118 to list chip index instead of hardcoding > ltc2487 is _not_ ltc4287. ^^ ^^ Sure, a Google search for LTC4287 returns a link to LTC2487 (!) as first response, but LTC2487 is an ADC and has nothing but the manufacturer in common with LTC4286. LTC4286 High Power Positive Hot-Swap Controller with Power Monitor via PMBus LTC2487 16-Bit 2-/4-Channel ∆Σ ADC with PGA, Easy Drive and I2C Interface I _really_ do not understand what you are trying to do here or why. >> >>> + >>> +static struct pmbus_driver_info ltc4286_info = { >>> + .pages = 1, >>> + .format[PSC_VOLTAGE_IN] = direct, >>> + .format[PSC_VOLTAGE_OUT] = direct, >>> + .format[PSC_CURRENT_OUT] = direct, >>> + .format[PSC_POWER] = direct, >>> + .format[PSC_TEMPERATURE] = direct, >>> + .m[PSC_VOLTAGE_IN] = 32, >>> + .b[PSC_VOLTAGE_IN] = 0, >>> + .R[PSC_VOLTAGE_IN] = 1, >>> + .m[PSC_VOLTAGE_OUT] = 32, >>> + .b[PSC_VOLTAGE_OUT] = 0, >>> + .R[PSC_VOLTAGE_OUT] = 1, >>> + .m[PSC_CURRENT_OUT] = 1024, >>> + .b[PSC_CURRENT_OUT] = 0, >>> + .R[PSC_CURRENT_OUT] = 3 - 6, >> >> This needs explanation. > We will add comments as below > /* Initialize the MBR as default settings which is referred to LTC4286 datasheet(March 22, 2022 version) table 3 page 16 */ > That does not explain "3 - 6". >> >>> + .m[PSC_POWER] = 1, >>> + .b[PSC_POWER] = 0, >>> + .R[PSC_POWER] = 4 - 6, >> >> This needs explanation. > We will add comments as below > /* To support small shunt resistor value */ > That does not explain "4 - 6". >> >>> + .m[PSC_TEMPERATURE] = 1, >>> + .b[PSC_TEMPERATURE] = 273.15, >> >> Assigning a float to an int doesn't make much sense. > We will revise to .b[PSC_TEMPERATURE] = 273, > However the value for this MBR is 273.15 in datasheet > We use 273 due to pmbus code limitation > >> >>> + .R[PSC_TEMPERATURE] = 0, >>> + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | >> PMBUS_HAVE_IOUT | >>> + PMBUS_HAVE_PIN | PMBUS_HAVE_TEMP, >> >> The chip does have a number of status registers. > We will add status registers here > >> >>> +}; >>> + >>> +static int ltc4286_probe(struct i2c_client *client, >>> + const struct i2c_device_id *id) { >>> + int ret; >>> + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; >>> + struct device *dev = &client->dev; >>> + struct pmbus_driver_info *info; >>> + u32 rsense; >>> + >>> + ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, >> block_buffer); >>> + if (ret < 0) { >>> + dev_err(&client->dev, "failed to read manufacturer >>> + id\n"); >> >> Kind of pointless to declare a local 'dev' variable and not use it. > We will drop it > >> >>> + return ret; >>> + } >>> + >>> + /* Refer to ltc4286 datasheet page 20 >>> + * the default manufacturer id is LTC >> >> Why "default" ? > We will revise to > /* > * Refer to ltc4286 datasheet page 20 > * the manufacturer id is LTC > */ > >> >>> + */ >> >> Please use standard multi-line comments. > We will revise to > /* > * Refer to ltc4286 datasheet page 20 > * the manufacturer id is LTC > */ > >> >>> + if (ret != LTC4286_MFR_ID_SIZE || >>> + strncmp(block_buffer, "LTC", LTC4286_MFR_ID_SIZE)) { >>> + dev_err(&client->dev, "unsupported manufacturer id\n"); >>> + return -ENODEV; >>> + } >>> + >>> + ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, >> block_buffer); >>> + if (ret < 0) { >>> + dev_err(&client->dev, "failed to read manufacturer >> model\n"); >>> + return ret; >>> + } >> >> Why read the model if you don't do anything with it ? > We will add comaprision here. > for (mid = ltc4286_id; mid->name[0]; mid++) { > if (!strncasecmp(mid->name, block_buffer, strlen(mid->name))) > break; > } > >> >>> + >>> + ret = of_property_read_u32(client->dev.of_node, >> "rsense-micro-ohms", >>> + &rsense); >>> + if (ret < 0) >>> + return ret; >>> + >>> + if (rsense == 0) >>> + return -EINVAL; >>> + >> >> There should be a default for systems not supporting devicetree. > After confirming with vendor, they said there is no default rsesne for this chip > The value for rsense depends on hardware engineer in each manufacturer > The _driver_ needs a default. >> >>> + info = <c4286_info; >>> + >>> + /* Default of VRANGE_SELECT = 1 */ >>> + if (device_property_read_bool(dev, "vrange_select_25p6")) { >>> + /* Setup MFR1 CONFIG register bit 1 VRANGE_SELECT */ >>> + ret = i2c_smbus_read_word_data(client, >> LTC4286_MFR_CONFIG1); >>> + if (ret < 0) { >>> + dev_err(&client->dev, >>> + "failed to read manufacturer >> configuration one\n"); >>> + return ret; >>> + } >>> + >>> + ret &= ~VRANGE_SELECT; /* VRANGE_SELECT = 0, 25.6V */ >>> + i2c_smbus_write_word_data(client, >> LTC4286_MFR_CONFIG1, >>> + ret); >> >> Error check missing. > ret = i2c_smbus_write_word_data(client, LTC4286_MFR_CONFIG1, ret); > if (ret < 0) { > dev_err(&client->dev, "failed to set vrange\n"); > return ret; > } > >> >>> + >>> + info->m[PSC_VOLTAGE_IN] = 128; >>> + info->m[PSC_VOLTAGE_OUT] = 128; >>> + info->m[PSC_POWER] = 4 * rsense; >>> + } else { >>> + info->m[PSC_POWER] = rsense; >> >> This just takes the current configuration, and assumes it is the default. >> That may not be correct. The chip may have been configured by the BIOS, or >> manually. > The MBR values are based on hardware design, so it must be set in initial stage > >> >>> + } >>> + >> >> The code assumes that there is only a single chip in the system, or that the >> configuration of all chips is identical. This is not necessarily correct. > If there are more than one LTC4286 or LTC4287 chips, user can add the configuration for different chips in dts file > "info" is a pointer to a static variable. info = <c4286_info; In this context, what you are saying above does not make sense. The second chip's configuration will override the first chip's configuration. info->m[PSC_POWER] = 4 * rsense; ... No, sorry, this still does not make sense. >> >>> + info->m[PSC_CURRENT_OUT] = 1024 * rsense; >>> + >>> + return pmbus_do_probe(client, info); } >>> + >>> +static const struct i2c_device_id ltc4286_id[] = { { "ltc4286", ltc4286 }, >>> + { "ltc4287", >> ltc4287 >>> +}, >> >> Even if LTC4287 existed, assigning the ID here ... > So do you recommend us to put this enum (enum chips { ltc4286, ltc4287 };) here? > >> >>> + {} }; >>> +MODULE_DEVICE_TABLE(i2c, ltc4286_id); >>> + >>> +static const struct of_device_id ltc4286_of_match[] = { >>> + { .compatible = "lltc,ltc4286" }, >>> + { .compatible = "lltc,ltc4287" }, >> >> ... but not here defeats having it in the first place. > So do you recommend us to not put this enum (enum chips { ltc4286, ltc4287 };) here? > Please read my comment. I am saying that it does not make sense to provide the chip ID to i2c_device_id but not in of_device_id. Either add it do both if needed or not at all. I am not telling which one, I am just asking for consistency. However, as mentioned earlier, according to your code the chips supposedly have identical functionality. Separate chip IDs (ltc4286 and ltc4287) therefore seem unnecessary (not even counting the fact that ltc4287 still does not seem to exist). >> >>> + {} >>> +}; >> >> MODULE_DEVOCE_TABLE() missing. > In v1 line 120 > >> >>> + >>> +/* This is the driver that will be inserted */ >> >> Useless comment > We will drop it. > >> >>> +static struct i2c_driver ltc4286_driver = { >>> + .driver = { >>> + .name = "ltc4286", >>> + .of_match_table = ltc4286_of_match, >>> + }, >>> + .probe = ltc4286_probe, >>> + .id_table = ltc4286_id, >>> +}; >>> + >>> +module_i2c_driver(ltc4286_driver); >>> + >>> +MODULE_AUTHOR("Delphine CC Chiu >> "); >>> +MODULE_DESCRIPTION("PMBUS driver for LTC4286 and compatibles"); >>> +MODULE_LICENSE("GPL"); >>> -- >>> 2.17.1 >>>