From patchwork Sat Feb 15 12:25:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11383841 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1B9001580 for ; Sat, 15 Feb 2020 12:26:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F058E2073A for ; Sat, 15 Feb 2020 12:26:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="rQ4mC7RT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725953AbgBOM0F (ORCPT ); Sat, 15 Feb 2020 07:26:05 -0500 Received: from mail-pl1-f195.google.com ([209.85.214.195]:46962 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725937AbgBOM0F (ORCPT ); Sat, 15 Feb 2020 07:26:05 -0500 Received: by mail-pl1-f195.google.com with SMTP id y8so4889913pll.13 for ; Sat, 15 Feb 2020 04:26:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=A2U7OTQ3FtscG5Eao9pmn65OIcmgrXJt6TiWaVZ36Z8=; b=rQ4mC7RTHz/3n2Jo/vbisXbz/InUSspc3YTDr5+Z2wmR8wi1zH7jz76zTrmuH3aWq3 jjN/zvYrnlC9n+hVwXR8N+uSB/bygIuwiEjXBpghQw2d5IMKFOQAMMnmgTDZeWI3B1Rz C1f1u8gxqGGJ5oMtnPX8pbKUNEOL+y7TsT2k/c0xTjT0NO5hCrTD6IgG1F8rgvFl3/xL t/GPwj0kAz/SW6o84x/Mt8Z2XL0Yqv9SexFFzNI+U0CI3Kxilf2PX1/AGx8sqI1TsHRy ZsKNXK5ezop9HgzuAaU2bIOUx04i6e7NNxjBCrEgH8adBDKsmgyfdOtBHU9mRtjWlt/4 CpzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=A2U7OTQ3FtscG5Eao9pmn65OIcmgrXJt6TiWaVZ36Z8=; b=fjh8C0X4lDzptLZqET3pTZ70fImHXI9gNsEJ4HvxjAC5rdfSVfsdWuNQuv+gAP3rss x+h2tzzrpC4wDfvdcrr2C0Nc2E+/B9BVly0bcKLi/LNdVAs1p1/B/tJpJJXfjdAnb4RA dBBIt2x2XuUKlcxVsPQCfB39xnH9b3RrS9v1c0pBZVs1sWl3WceS2og4/4svu4LITKGO 8XCQrgX61d+H7QV8x4dAejwYGiBDah/3n2WA0CQFvLraM54/GhLh5rKyGFMFAGwLls7+ 0Baeu635+56sykf8Ou8YH/a6Es/xHvOxiA206lwbkAuFaLz65/HZFqBJ+Oes+ijnQQLz tdxg== X-Gm-Message-State: APjAAAVViR8yS/NHxxpMcytwAWMWYXoJypWlxjwXo0A8lri/fK1WjWrI fEzUqEBkfNmKtTtSTplrZrjBD5/Z X-Google-Smtp-Source: APXvYqy2vbNnRCO7bKzD5+uqYg0Wyt2J6J13/JMz7AL1vFkiTnvlfG8IthHq5Gh0cXYcHs7w/gs3zg== X-Received: by 2002:a17:902:740c:: with SMTP id g12mr8271187pll.166.1581769564587; Sat, 15 Feb 2020 04:26:04 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id s206sm10791620pfs.100.2020.02.15.04.26.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Feb 2020 04:26:04 -0800 (PST) From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck , Vadim Pasternak Subject: [PATCH 1/8] hwmon: (pmbus) Add IC_DEVICE_ID and IC_DEVICE_REV command definitions Date: Sat, 15 Feb 2020 04:25:55 -0800 Message-Id: <20200215122602.14245-1-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Recent PMBus versions added IC_DEVICE_ID and IC_DEVICE_REV commands as additional means to identify the chip. Add command definitions to pmbus.h include file. Cc: Vadim Pasternak Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index 13b34bd67f23..cbc47af732c2 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h @@ -119,6 +119,9 @@ enum pmbus_regs { PMBUS_MFR_DATE = 0x9D, PMBUS_MFR_SERIAL = 0x9E, + PMBUS_IC_DEVICE_ID = 0xAD, + PMBUS_IC_DEVICE_REV = 0xAE, + /* * Virtual registers. * Useful to support attributes which are not supported by standard PMBus From patchwork Sat Feb 15 12:25:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11383843 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 671031580 for ; Sat, 15 Feb 2020 12:26:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2E97B2082F for ; Sat, 15 Feb 2020 12:26:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ozzBLIX+" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725977AbgBOM0I (ORCPT ); Sat, 15 Feb 2020 07:26:08 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:38078 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725937AbgBOM0I (ORCPT ); Sat, 15 Feb 2020 07:26:08 -0500 Received: by mail-pf1-f195.google.com with SMTP id x185so6419364pfc.5 for ; Sat, 15 Feb 2020 04:26:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ul4CF0duXZESNZdurZEkg7+R6i9VPUKre68+wWSoDQc=; b=ozzBLIX++84OgAr1hLH2tB32bVmxJNJAXMOEyfXQJiLIilHVmDitLF6VYIxr+h+Hep ZtVR0zSoWBu/En1/nablZVE7op54eTf3/FUR49LRoSBY465AIUMXUeNuheviFrVDEB8d m3ds/Y4Pv0AOavYR2XLouAMDFDeOjVDt5ocUOXpoFlcQTaVpY62wBDW9aiC7Lo0BAOSY iH2lKs40t6OIvZum3cyJiYN3cWQWPig4GPZtP0E0ucmDpzZIL78a9xh7dYpLm4dHvFtH 1VUNTF+swa2ymKHp6gH4a4iFlD7axZ5jVbqFq+YlBeT6LivIrH4IYromud367BiTES3h jhMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=Ul4CF0duXZESNZdurZEkg7+R6i9VPUKre68+wWSoDQc=; b=sU71vNRoGppaqvCNFHi/6SeqgDGTWyWhMUTm1/l/zowh8q7fESIvyILe3WDX6y/RuY CGH8h816sSTNrFy7e98YjZvnO94sNXyuEm/xPQm0tF7Y2ereLdC0BeGzc9wmIXV9x2mT 593oiT/0ad5iy3CjTgAvYjLFhPo4OzYo6j9kHCzICJpmyzGNw+Rgn8TpKECHfv5ZvLnS HcWGFvmg5x0+plaeUE9cHA2akGYqfbpR1alGTyFiKvCi4db1lSy6q3CmHh0J4uRYIfFC PXJ3pbEQaMBV2dPSgHOwQzCON2gv/cY20mVn1rjy7wBf0ijKnW5g+uEdZZPOv5Ug3tIj aL6w== X-Gm-Message-State: APjAAAW5SWziKChsoyKGxRVY+VanP4nM9MjHpZHvT5roMOaKuTTb1Koa 9+a0nAPGkQF16bs4ghKvjTZX0IqK X-Google-Smtp-Source: APXvYqwuSgi+fTQwm60SQIcsc+uqPOj+8ZyvWsmDGZ5EY9tAIz0OuHjU8TW8rYF+mpAJY9wdF34AzQ== X-Received: by 2002:a63:5c0e:: with SMTP id q14mr8611343pgb.313.1581769566123; Sat, 15 Feb 2020 04:26:06 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id q4sm10936430pfl.175.2020.02.15.04.26.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Feb 2020 04:26:05 -0800 (PST) From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck , Vadim Pasternak Subject: [PATCH 2/8] hwmon: (pmbus) Add 'phase' parameter where needed for multi-phase support Date: Sat, 15 Feb 2020 04:25:56 -0800 Message-Id: <20200215122602.14245-2-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200215122602.14245-1-linux@roeck-us.net> References: <20200215122602.14245-1-linux@roeck-us.net> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org In preparation for multi-phase support, add 'phase' parameter to read_word and set_page functions. Actual multi-phase support will be added in a subsequent patch. Cc: Vadim Pasternak Signed-off-by: Guenter Roeck --- Documentation/hwmon/pmbus-core.rst | 22 +++++++++++------ drivers/hwmon/pmbus/adm1275.c | 37 ++++++++++++++++++---------- drivers/hwmon/pmbus/ibm-cffps.c | 15 ++++++------ drivers/hwmon/pmbus/ir35221.c | 23 +++++++++++------- drivers/hwmon/pmbus/isl68137.c | 3 ++- drivers/hwmon/pmbus/lm25066.c | 39 ++++++++++++++++++------------ drivers/hwmon/pmbus/ltc2978.c | 36 ++++++++++++++++----------- drivers/hwmon/pmbus/ltc3815.c | 20 +++++++++------ drivers/hwmon/pmbus/max16064.c | 7 +++--- drivers/hwmon/pmbus/max20730.c | 3 ++- drivers/hwmon/pmbus/max31785.c | 6 ++--- drivers/hwmon/pmbus/max34440.c | 25 ++++++++++--------- drivers/hwmon/pmbus/max8688.c | 17 +++++++------ drivers/hwmon/pmbus/pmbus.c | 4 +-- drivers/hwmon/pmbus/pmbus.h | 11 ++++++--- drivers/hwmon/pmbus/pmbus_core.c | 36 ++++++++++++++++----------- drivers/hwmon/pmbus/ucd9000.c | 2 +- drivers/hwmon/pmbus/zl6100.c | 5 ++-- 18 files changed, 189 insertions(+), 122 deletions(-) diff --git a/Documentation/hwmon/pmbus-core.rst b/Documentation/hwmon/pmbus-core.rst index 92515c446fe3..501b37b0610d 100644 --- a/Documentation/hwmon/pmbus-core.rst +++ b/Documentation/hwmon/pmbus-core.rst @@ -162,9 +162,12 @@ Read byte from page , register . :: - int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int phase, + int reg); -Read word from page , register . +Read word from page , phase , register . If the chip does not +support multiple phases, the phase parameter can be ignored. If the chip +supports multiple phases, a phase value of 0xff indicates all phases. :: @@ -201,16 +204,21 @@ is mandatory. :: - int pmbus_set_page(struct i2c_client *client, u8 page); + int pmbus_set_page(struct i2c_client *client, u8 page, u8 phase); -Set PMBus page register to for subsequent commands. +Set PMBus page register to and for subsequent commands. +If the chip does not support multiple phases, the phase parameter is +ignored. Otherwise, a phase value of 0xff selects all phases. :: - int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); + int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 phase, + u8 reg); -Read word data from , . Similar to i2c_smbus_read_word_data(), but -selects page first. +Read word data from , , . Similar to +i2c_smbus_read_word_data(), but selects page and phase first. If the chip does +not support multiple phases, the phase parameter is ignored. Otherwise, a phase +value of 0xff selects all phases. :: diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 5caa37fbfc18..e25f541227da 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -226,7 +226,8 @@ static int adm1275_write_pmon_config(const struct adm1275_data *data, return ret; } -static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) +static int adm1275_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); const struct adm1275_data *data = to_adm1275_data(info); @@ -239,58 +240,68 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, int reg) case PMBUS_IOUT_UC_FAULT_LIMIT: if (!data->have_uc_fault) return -ENXIO; - ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1275_IOUT_WARN2_LIMIT); break; case PMBUS_IOUT_OC_FAULT_LIMIT: if (!data->have_oc_fault) return -ENXIO; - ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1275_IOUT_WARN2_LIMIT); break; case PMBUS_VOUT_OV_WARN_LIMIT: if (data->have_vout) return -ENODATA; - ret = pmbus_read_word_data(client, 0, + ret = pmbus_read_word_data(client, 0, 0xff, ADM1075_VAUX_OV_WARN_LIMIT); break; case PMBUS_VOUT_UV_WARN_LIMIT: if (data->have_vout) return -ENODATA; - ret = pmbus_read_word_data(client, 0, + ret = pmbus_read_word_data(client, 0, 0xff, ADM1075_VAUX_UV_WARN_LIMIT); break; case PMBUS_READ_VOUT: if (data->have_vout) return -ENODATA; - ret = pmbus_read_word_data(client, 0, ADM1075_READ_VAUX); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1075_READ_VAUX); break; case PMBUS_VIRT_READ_IOUT_MIN: if (!data->have_iout_min) return -ENXIO; - ret = pmbus_read_word_data(client, 0, ADM1293_IOUT_MIN); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1293_IOUT_MIN); break; case PMBUS_VIRT_READ_IOUT_MAX: - ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1275_PEAK_IOUT); break; case PMBUS_VIRT_READ_VOUT_MAX: - ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VOUT); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1275_PEAK_VOUT); break; case PMBUS_VIRT_READ_VIN_MAX: - ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1275_PEAK_VIN); break; case PMBUS_VIRT_READ_PIN_MIN: if (!data->have_pin_min) return -ENXIO; - ret = pmbus_read_word_data(client, 0, ADM1293_PIN_MIN); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1293_PIN_MIN); break; case PMBUS_VIRT_READ_PIN_MAX: if (!data->have_pin_max) return -ENXIO; - ret = pmbus_read_word_data(client, 0, ADM1276_PEAK_PIN); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1276_PEAK_PIN); break; case PMBUS_VIRT_READ_TEMP_MAX: if (!data->have_temp_max) return -ENXIO; - ret = pmbus_read_word_data(client, 0, ADM1278_PEAK_TEMP); + ret = pmbus_read_word_data(client, 0, 0xff, + ADM1278_PEAK_TEMP); break; case PMBUS_VIRT_RESET_IOUT_HISTORY: case PMBUS_VIRT_RESET_VOUT_HISTORY: diff --git a/drivers/hwmon/pmbus/ibm-cffps.c b/drivers/hwmon/pmbus/ibm-cffps.c index 3795fe55b84f..b9bfa43f2508 100644 --- a/drivers/hwmon/pmbus/ibm-cffps.c +++ b/drivers/hwmon/pmbus/ibm-cffps.c @@ -148,7 +148,7 @@ static ssize_t ibm_cffps_debugfs_read(struct file *file, char __user *buf, struct ibm_cffps *psu = to_psu(idxp, idx); char data[I2C_SMBUS_BLOCK_MAX + 2] = { 0 }; - pmbus_set_page(psu->client, 0); + pmbus_set_page(psu->client, 0, 0xff); switch (idx) { case CFFPS_DEBUGFS_INPUT_HISTORY: @@ -247,7 +247,7 @@ static ssize_t ibm_cffps_debugfs_write(struct file *file, switch (idx) { case CFFPS_DEBUGFS_ON_OFF_CONFIG: - pmbus_set_page(psu->client, 0); + pmbus_set_page(psu->client, 0, 0xff); rc = simple_write_to_buffer(&data, 1, ppos, buf, count); if (rc <= 0) @@ -325,13 +325,13 @@ static int ibm_cffps_read_byte_data(struct i2c_client *client, int page, } static int ibm_cffps_read_word_data(struct i2c_client *client, int page, - int reg) + int phase, int reg) { int rc, mfr; switch (reg) { case PMBUS_STATUS_WORD: - rc = pmbus_read_word_data(client, page, reg); + rc = pmbus_read_word_data(client, page, phase, reg); if (rc < 0) return rc; @@ -348,7 +348,8 @@ static int ibm_cffps_read_word_data(struct i2c_client *client, int page, rc |= PB_STATUS_OFF; break; case PMBUS_VIRT_READ_VMON: - rc = pmbus_read_word_data(client, page, CFFPS_12VCS_VOUT_CMD); + rc = pmbus_read_word_data(client, page, phase, + CFFPS_12VCS_VOUT_CMD); break; default: rc = -ENODATA; @@ -379,7 +380,7 @@ static int ibm_cffps_led_brightness_set(struct led_classdev *led_cdev, dev_dbg(&psu->client->dev, "LED brightness set: %d. Command: %d.\n", brightness, next_led_state); - pmbus_set_page(psu->client, 0); + pmbus_set_page(psu->client, 0, 0xff); rc = i2c_smbus_write_byte_data(psu->client, CFFPS_SYS_CONFIG_CMD, next_led_state); @@ -401,7 +402,7 @@ static int ibm_cffps_led_blink_set(struct led_classdev *led_cdev, dev_dbg(&psu->client->dev, "LED blink set.\n"); - pmbus_set_page(psu->client, 0); + pmbus_set_page(psu->client, 0, 0xff); rc = i2c_smbus_write_byte_data(psu->client, CFFPS_SYS_CONFIG_CMD, CFFPS_LED_BLINK); diff --git a/drivers/hwmon/pmbus/ir35221.c b/drivers/hwmon/pmbus/ir35221.c index 0d878bcd6d26..3eea3e006a96 100644 --- a/drivers/hwmon/pmbus/ir35221.c +++ b/drivers/hwmon/pmbus/ir35221.c @@ -21,37 +21,42 @@ #define IR35221_MFR_IOUT_VALLEY 0xcb #define IR35221_MFR_TEMP_VALLEY 0xcc -static int ir35221_read_word_data(struct i2c_client *client, int page, int reg) +static int ir35221_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { int ret; switch (reg) { case PMBUS_VIRT_READ_VIN_MAX: - ret = pmbus_read_word_data(client, page, IR35221_MFR_VIN_PEAK); + ret = pmbus_read_word_data(client, page, phase, + IR35221_MFR_VIN_PEAK); break; case PMBUS_VIRT_READ_VOUT_MAX: - ret = pmbus_read_word_data(client, page, IR35221_MFR_VOUT_PEAK); + ret = pmbus_read_word_data(client, page, phase, + IR35221_MFR_VOUT_PEAK); break; case PMBUS_VIRT_READ_IOUT_MAX: - ret = pmbus_read_word_data(client, page, IR35221_MFR_IOUT_PEAK); + ret = pmbus_read_word_data(client, page, phase, + IR35221_MFR_IOUT_PEAK); break; case PMBUS_VIRT_READ_TEMP_MAX: - ret = pmbus_read_word_data(client, page, IR35221_MFR_TEMP_PEAK); + ret = pmbus_read_word_data(client, page, phase, + IR35221_MFR_TEMP_PEAK); break; case PMBUS_VIRT_READ_VIN_MIN: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, IR35221_MFR_VIN_VALLEY); break; case PMBUS_VIRT_READ_VOUT_MIN: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, IR35221_MFR_VOUT_VALLEY); break; case PMBUS_VIRT_READ_IOUT_MIN: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, IR35221_MFR_IOUT_VALLEY); break; case PMBUS_VIRT_READ_TEMP_MIN: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, IR35221_MFR_TEMP_VALLEY); break; default: diff --git a/drivers/hwmon/pmbus/isl68137.c b/drivers/hwmon/pmbus/isl68137.c index 515596c92fe1..a95835a96014 100644 --- a/drivers/hwmon/pmbus/isl68137.c +++ b/drivers/hwmon/pmbus/isl68137.c @@ -49,7 +49,8 @@ static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client, * enabling AVS control is the workaround. */ if (op_val == ISL68137_VOUT_AVS) { - rc = pmbus_read_word_data(client, page, PMBUS_VOUT_COMMAND); + rc = pmbus_read_word_data(client, page, 0xff, + PMBUS_VOUT_COMMAND); if (rc < 0) return rc; diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index 05fce86f1f81..9e4cf0800186 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c @@ -211,7 +211,8 @@ struct lm25066_data { #define to_lm25066_data(x) container_of(x, struct lm25066_data, info) -static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) +static int lm25066_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); const struct lm25066_data *data = to_lm25066_data(info); @@ -219,7 +220,7 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) switch (reg) { case PMBUS_VIRT_READ_VMON: - ret = pmbus_read_word_data(client, 0, LM25066_READ_VAUX); + ret = pmbus_read_word_data(client, 0, 0xff, LM25066_READ_VAUX); if (ret < 0) break; /* Adjust returned value to match VIN coefficients */ @@ -244,33 +245,40 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) } break; case PMBUS_READ_IIN: - ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN); + ret = pmbus_read_word_data(client, 0, 0xff, + LM25066_MFR_READ_IIN); break; case PMBUS_READ_PIN: - ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_PIN); + ret = pmbus_read_word_data(client, 0, 0xff, + LM25066_MFR_READ_PIN); break; case PMBUS_IIN_OC_WARN_LIMIT: - ret = pmbus_read_word_data(client, 0, + ret = pmbus_read_word_data(client, 0, 0xff, LM25066_MFR_IIN_OC_WARN_LIMIT); break; case PMBUS_PIN_OP_WARN_LIMIT: - ret = pmbus_read_word_data(client, 0, + ret = pmbus_read_word_data(client, 0, 0xff, LM25066_MFR_PIN_OP_WARN_LIMIT); break; case PMBUS_VIRT_READ_VIN_AVG: - ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VIN); + ret = pmbus_read_word_data(client, 0, 0xff, + LM25066_READ_AVG_VIN); break; case PMBUS_VIRT_READ_VOUT_AVG: - ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VOUT); + ret = pmbus_read_word_data(client, 0, 0xff, + LM25066_READ_AVG_VOUT); break; case PMBUS_VIRT_READ_IIN_AVG: - ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_IIN); + ret = pmbus_read_word_data(client, 0, 0xff, + LM25066_READ_AVG_IIN); break; case PMBUS_VIRT_READ_PIN_AVG: - ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_PIN); + ret = pmbus_read_word_data(client, 0, 0xff, + LM25066_READ_AVG_PIN); break; case PMBUS_VIRT_READ_PIN_MAX: - ret = pmbus_read_word_data(client, 0, LM25066_READ_PIN_PEAK); + ret = pmbus_read_word_data(client, 0, 0xff, + LM25066_READ_PIN_PEAK); break; case PMBUS_VIRT_RESET_PIN_HISTORY: ret = 0; @@ -288,13 +296,14 @@ static int lm25066_read_word_data(struct i2c_client *client, int page, int reg) return ret; } -static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) +static int lm25056_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { int ret; switch (reg) { case PMBUS_VIRT_VMON_UV_WARN_LIMIT: - ret = pmbus_read_word_data(client, 0, + ret = pmbus_read_word_data(client, 0, 0xff, LM25056_VAUX_UV_WARN_LIMIT); if (ret < 0) break; @@ -302,7 +311,7 @@ static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) ret = DIV_ROUND_CLOSEST(ret * 293, 6140); break; case PMBUS_VIRT_VMON_OV_WARN_LIMIT: - ret = pmbus_read_word_data(client, 0, + ret = pmbus_read_word_data(client, 0, 0xff, LM25056_VAUX_OV_WARN_LIMIT); if (ret < 0) break; @@ -310,7 +319,7 @@ static int lm25056_read_word_data(struct i2c_client *client, int page, int reg) ret = DIV_ROUND_CLOSEST(ret * 293, 6140); break; default: - ret = lm25066_read_word_data(client, page, reg); + ret = lm25066_read_word_data(client, page, phase, reg); break; } return ret; diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index f01f4887fb2e..50b8c6f91d66 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c @@ -151,7 +151,8 @@ static int ltc_wait_ready(struct i2c_client *client) return -ETIMEDOUT; } -static int ltc_read_word_data(struct i2c_client *client, int page, int reg) +static int ltc_read_word_data(struct i2c_client *client, int page, int phase, + int reg) { int ret; @@ -159,7 +160,7 @@ static int ltc_read_word_data(struct i2c_client *client, int page, int reg) if (ret < 0) return ret; - return pmbus_read_word_data(client, page, reg); + return pmbus_read_word_data(client, page, 0xff, reg); } static int ltc_read_byte_data(struct i2c_client *client, int page, int reg) @@ -202,7 +203,7 @@ static int ltc_get_max(struct ltc2978_data *data, struct i2c_client *client, { int ret; - ret = ltc_read_word_data(client, page, reg); + ret = ltc_read_word_data(client, page, 0xff, reg); if (ret >= 0) { if (lin11_to_val(ret) > lin11_to_val(*pmax)) *pmax = ret; @@ -216,7 +217,7 @@ static int ltc_get_min(struct ltc2978_data *data, struct i2c_client *client, { int ret; - ret = ltc_read_word_data(client, page, reg); + ret = ltc_read_word_data(client, page, 0xff, reg); if (ret >= 0) { if (lin11_to_val(ret) < lin11_to_val(*pmin)) *pmin = ret; @@ -238,7 +239,8 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page, &data->vin_max); break; case PMBUS_VIRT_READ_VOUT_MAX: - ret = ltc_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK); + ret = ltc_read_word_data(client, page, 0xff, + LTC2978_MFR_VOUT_PEAK); if (ret >= 0) { /* * VOUT is 16 bit unsigned with fixed exponent, @@ -269,7 +271,8 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page, return ret; } -static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg) +static int ltc2978_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); struct ltc2978_data *data = to_ltc2978_data(info); @@ -281,7 +284,8 @@ static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg) &data->vin_min); break; case PMBUS_VIRT_READ_VOUT_MIN: - ret = ltc_read_word_data(client, page, LTC2978_MFR_VOUT_MIN); + ret = ltc_read_word_data(client, page, phase, + LTC2978_MFR_VOUT_MIN); if (ret >= 0) { /* * VOUT_MIN is known to not be supported on some lots @@ -314,7 +318,8 @@ static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg) return ret; } -static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg) +static int ltc2974_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); struct ltc2978_data *data = to_ltc2978_data(info); @@ -333,13 +338,14 @@ static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg) ret = 0; break; default: - ret = ltc2978_read_word_data(client, page, reg); + ret = ltc2978_read_word_data(client, page, phase, reg); break; } return ret; } -static int ltc2975_read_word_data(struct i2c_client *client, int page, int reg) +static int ltc2975_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); struct ltc2978_data *data = to_ltc2978_data(info); @@ -367,13 +373,14 @@ static int ltc2975_read_word_data(struct i2c_client *client, int page, int reg) ret = 0; break; default: - ret = ltc2978_read_word_data(client, page, reg); + ret = ltc2978_read_word_data(client, page, phase, reg); break; } return ret; } -static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) +static int ltc3880_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); struct ltc2978_data *data = to_ltc2978_data(info); @@ -405,7 +412,8 @@ static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) return ret; } -static int ltc3883_read_word_data(struct i2c_client *client, int page, int reg) +static int ltc3883_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); struct ltc2978_data *data = to_ltc2978_data(info); @@ -420,7 +428,7 @@ static int ltc3883_read_word_data(struct i2c_client *client, int page, int reg) ret = 0; break; default: - ret = ltc3880_read_word_data(client, page, reg); + ret = ltc3880_read_word_data(client, page, phase, reg); break; } return ret; diff --git a/drivers/hwmon/pmbus/ltc3815.c b/drivers/hwmon/pmbus/ltc3815.c index b83a18a58364..3036263e0a66 100644 --- a/drivers/hwmon/pmbus/ltc3815.c +++ b/drivers/hwmon/pmbus/ltc3815.c @@ -55,7 +55,7 @@ static int ltc3815_write_byte(struct i2c_client *client, int page, u8 reg) * LTC3815 does not support the CLEAR_FAULTS command. * Emulate it by clearing the status register. */ - ret = pmbus_read_word_data(client, 0, PMBUS_STATUS_WORD); + ret = pmbus_read_word_data(client, 0, 0xff, PMBUS_STATUS_WORD); if (ret > 0) { pmbus_write_word_data(client, 0, PMBUS_STATUS_WORD, ret); @@ -69,25 +69,31 @@ static int ltc3815_write_byte(struct i2c_client *client, int page, u8 reg) return ret; } -static int ltc3815_read_word_data(struct i2c_client *client, int page, int reg) +static int ltc3815_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { int ret; switch (reg) { case PMBUS_VIRT_READ_VIN_MAX: - ret = pmbus_read_word_data(client, page, LTC3815_MFR_VIN_PEAK); + ret = pmbus_read_word_data(client, page, phase, + LTC3815_MFR_VIN_PEAK); break; case PMBUS_VIRT_READ_VOUT_MAX: - ret = pmbus_read_word_data(client, page, LTC3815_MFR_VOUT_PEAK); + ret = pmbus_read_word_data(client, page, phase, + LTC3815_MFR_VOUT_PEAK); break; case PMBUS_VIRT_READ_TEMP_MAX: - ret = pmbus_read_word_data(client, page, LTC3815_MFR_TEMP_PEAK); + ret = pmbus_read_word_data(client, page, phase, + LTC3815_MFR_TEMP_PEAK); break; case PMBUS_VIRT_READ_IOUT_MAX: - ret = pmbus_read_word_data(client, page, LTC3815_MFR_IOUT_PEAK); + ret = pmbus_read_word_data(client, page, phase, + LTC3815_MFR_IOUT_PEAK); break; case PMBUS_VIRT_READ_IIN_MAX: - ret = pmbus_read_word_data(client, page, LTC3815_MFR_IIN_PEAK); + ret = pmbus_read_word_data(client, page, phase, + LTC3815_MFR_IIN_PEAK); break; case PMBUS_VIRT_RESET_VOUT_HISTORY: case PMBUS_VIRT_RESET_VIN_HISTORY: diff --git a/drivers/hwmon/pmbus/max16064.c b/drivers/hwmon/pmbus/max16064.c index b3e7b8d2e69d..288e93f74c28 100644 --- a/drivers/hwmon/pmbus/max16064.c +++ b/drivers/hwmon/pmbus/max16064.c @@ -15,17 +15,18 @@ #define MAX16064_MFR_VOUT_PEAK 0xd4 #define MAX16064_MFR_TEMPERATURE_PEAK 0xd6 -static int max16064_read_word_data(struct i2c_client *client, int page, int reg) +static int max16064_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { int ret; switch (reg) { case PMBUS_VIRT_READ_VOUT_MAX: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX16064_MFR_VOUT_PEAK); break; case PMBUS_VIRT_READ_TEMP_MAX: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX16064_MFR_TEMPERATURE_PEAK); break; case PMBUS_VIRT_RESET_VOUT_HISTORY: diff --git a/drivers/hwmon/pmbus/max20730.c b/drivers/hwmon/pmbus/max20730.c index 294e2212f61e..c0bb05487e0e 100644 --- a/drivers/hwmon/pmbus/max20730.c +++ b/drivers/hwmon/pmbus/max20730.c @@ -85,7 +85,8 @@ static u32 max_current[][5] = { [max20743] = { 18900, 24100, 29200, 34100 }, }; -static int max20730_read_word_data(struct i2c_client *client, int page, int reg) +static int max20730_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); const struct max20730_data *data = to_max20730_data(info); diff --git a/drivers/hwmon/pmbus/max31785.c b/drivers/hwmon/pmbus/max31785.c index 254b0f98c755..d9aa5c873d21 100644 --- a/drivers/hwmon/pmbus/max31785.c +++ b/drivers/hwmon/pmbus/max31785.c @@ -72,7 +72,7 @@ static int max31785_read_long_data(struct i2c_client *client, int page, cmdbuf[0] = reg; - rc = pmbus_set_page(client, page); + rc = pmbus_set_page(client, page, 0xff); if (rc < 0) return rc; @@ -110,7 +110,7 @@ static int max31785_get_pwm_mode(struct i2c_client *client, int page) if (config < 0) return config; - command = pmbus_read_word_data(client, page, PMBUS_FAN_COMMAND_1); + command = pmbus_read_word_data(client, page, 0xff, PMBUS_FAN_COMMAND_1); if (command < 0) return command; @@ -126,7 +126,7 @@ static int max31785_get_pwm_mode(struct i2c_client *client, int page) } static int max31785_read_word_data(struct i2c_client *client, int page, - int reg) + int phase, int reg) { u32 val; int rv; diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c index 5c63a6600729..18b4e071067f 100644 --- a/drivers/hwmon/pmbus/max34440.c +++ b/drivers/hwmon/pmbus/max34440.c @@ -41,7 +41,8 @@ struct max34440_data { #define to_max34440_data(x) container_of(x, struct max34440_data, info) -static int max34440_read_word_data(struct i2c_client *client, int page, int reg) +static int max34440_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { int ret; const struct pmbus_driver_info *info = pmbus_get_driver_info(client); @@ -49,44 +50,44 @@ static int max34440_read_word_data(struct i2c_client *client, int page, int reg) switch (reg) { case PMBUS_VIRT_READ_VOUT_MIN: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX34440_MFR_VOUT_MIN); break; case PMBUS_VIRT_READ_VOUT_MAX: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX34440_MFR_VOUT_PEAK); break; case PMBUS_VIRT_READ_IOUT_AVG: if (data->id != max34446 && data->id != max34451) return -ENXIO; - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX34446_MFR_IOUT_AVG); break; case PMBUS_VIRT_READ_IOUT_MAX: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX34440_MFR_IOUT_PEAK); break; case PMBUS_VIRT_READ_POUT_AVG: if (data->id != max34446) return -ENXIO; - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX34446_MFR_POUT_AVG); break; case PMBUS_VIRT_READ_POUT_MAX: if (data->id != max34446) return -ENXIO; - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX34446_MFR_POUT_PEAK); break; case PMBUS_VIRT_READ_TEMP_AVG: if (data->id != max34446 && data->id != max34460 && data->id != max34461) return -ENXIO; - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX34446_MFR_TEMPERATURE_AVG); break; case PMBUS_VIRT_READ_TEMP_MAX: - ret = pmbus_read_word_data(client, page, + ret = pmbus_read_word_data(client, page, phase, MAX34440_MFR_TEMPERATURE_PEAK); break; case PMBUS_VIRT_RESET_POUT_HISTORY: @@ -159,14 +160,14 @@ static int max34440_read_byte_data(struct i2c_client *client, int page, int reg) int mfg_status; if (page >= 0) { - ret = pmbus_set_page(client, page); + ret = pmbus_set_page(client, page, 0xff); if (ret < 0) return ret; } switch (reg) { case PMBUS_STATUS_IOUT: - mfg_status = pmbus_read_word_data(client, 0, + mfg_status = pmbus_read_word_data(client, 0, 0xff, PMBUS_STATUS_MFR_SPECIFIC); if (mfg_status < 0) return mfg_status; @@ -176,7 +177,7 @@ static int max34440_read_byte_data(struct i2c_client *client, int page, int reg) ret |= PB_IOUT_OC_FAULT; break; case PMBUS_STATUS_TEMPERATURE: - mfg_status = pmbus_read_word_data(client, 0, + mfg_status = pmbus_read_word_data(client, 0, 0xff, PMBUS_STATUS_MFR_SPECIFIC); if (mfg_status < 0) return mfg_status; diff --git a/drivers/hwmon/pmbus/max8688.c b/drivers/hwmon/pmbus/max8688.c index bc5f4cb6450e..643ccfc05106 100644 --- a/drivers/hwmon/pmbus/max8688.c +++ b/drivers/hwmon/pmbus/max8688.c @@ -28,7 +28,8 @@ #define MAX8688_STATUS_OT_FAULT BIT(13) #define MAX8688_STATUS_OT_WARNING BIT(14) -static int max8688_read_word_data(struct i2c_client *client, int page, int reg) +static int max8688_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { int ret; @@ -37,13 +38,15 @@ static int max8688_read_word_data(struct i2c_client *client, int page, int reg) switch (reg) { case PMBUS_VIRT_READ_VOUT_MAX: - ret = pmbus_read_word_data(client, 0, MAX8688_MFR_VOUT_PEAK); + ret = pmbus_read_word_data(client, 0, 0xff, + MAX8688_MFR_VOUT_PEAK); break; case PMBUS_VIRT_READ_IOUT_MAX: - ret = pmbus_read_word_data(client, 0, MAX8688_MFR_IOUT_PEAK); + ret = pmbus_read_word_data(client, 0, 0xff, + MAX8688_MFR_IOUT_PEAK); break; case PMBUS_VIRT_READ_TEMP_MAX: - ret = pmbus_read_word_data(client, 0, + ret = pmbus_read_word_data(client, 0, 0xff, MAX8688_MFR_TEMPERATURE_PEAK); break; case PMBUS_VIRT_RESET_VOUT_HISTORY: @@ -94,7 +97,7 @@ static int max8688_read_byte_data(struct i2c_client *client, int page, int reg) switch (reg) { case PMBUS_STATUS_VOUT: - mfg_status = pmbus_read_word_data(client, 0, + mfg_status = pmbus_read_word_data(client, 0, 0xff, MAX8688_MFG_STATUS); if (mfg_status < 0) return mfg_status; @@ -108,7 +111,7 @@ static int max8688_read_byte_data(struct i2c_client *client, int page, int reg) ret |= PB_VOLTAGE_OV_FAULT; break; case PMBUS_STATUS_IOUT: - mfg_status = pmbus_read_word_data(client, 0, + mfg_status = pmbus_read_word_data(client, 0, 0xff, MAX8688_MFG_STATUS); if (mfg_status < 0) return mfg_status; @@ -120,7 +123,7 @@ static int max8688_read_byte_data(struct i2c_client *client, int page, int reg) ret |= PB_IOUT_OC_FAULT; break; case PMBUS_STATUS_TEMPERATURE: - mfg_status = pmbus_read_word_data(client, 0, + mfg_status = pmbus_read_word_data(client, 0, 0xff, MAX8688_MFG_STATUS); if (mfg_status < 0) return mfg_status; diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c index 51e8312b6c2d..6d384e8ee1db 100644 --- a/drivers/hwmon/pmbus/pmbus.c +++ b/drivers/hwmon/pmbus/pmbus.c @@ -102,10 +102,10 @@ static int pmbus_identify(struct i2c_client *client, int page; for (page = 1; page < PMBUS_PAGES; page++) { - if (pmbus_set_page(client, page) < 0) + if (pmbus_set_page(client, page, 0xff) < 0) break; } - pmbus_set_page(client, 0); + pmbus_set_page(client, 0, 0xff); info->pages = page; } else { info->pages = 1; diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index cbc47af732c2..27c7ae0ffa6b 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h @@ -418,7 +418,8 @@ struct pmbus_driver_info { * the standard register. */ int (*read_byte_data)(struct i2c_client *client, int page, int reg); - int (*read_word_data)(struct i2c_client *client, int page, int reg); + int (*read_word_data)(struct i2c_client *client, int page, int phase, + int reg); int (*write_word_data)(struct i2c_client *client, int page, int reg, u16 word); int (*write_byte)(struct i2c_client *client, int page, u8 value); @@ -457,9 +458,11 @@ extern const struct regulator_ops pmbus_regulator_ops; /* Function declarations */ void pmbus_clear_cache(struct i2c_client *client); -int pmbus_set_page(struct i2c_client *client, int page); -int pmbus_read_word_data(struct i2c_client *client, int page, u8 reg); -int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, u16 word); +int pmbus_set_page(struct i2c_client *client, int page, int phase); +int pmbus_read_word_data(struct i2c_client *client, int page, int phase, + u8 reg); +int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, + u16 word); int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg); int pmbus_write_byte(struct i2c_client *client, int page, u8 value); int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index d9c17feb7b4a..9343ca7d4069 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -146,7 +146,7 @@ void pmbus_clear_cache(struct i2c_client *client) } EXPORT_SYMBOL_GPL(pmbus_clear_cache); -int pmbus_set_page(struct i2c_client *client, int page) +int pmbus_set_page(struct i2c_client *client, int page, int phase) { struct pmbus_data *data = i2c_get_clientdata(client); int rv; @@ -177,7 +177,7 @@ int pmbus_write_byte(struct i2c_client *client, int page, u8 value) { int rv; - rv = pmbus_set_page(client, page); + rv = pmbus_set_page(client, page, 0xff); if (rv < 0) return rv; @@ -208,7 +208,7 @@ int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, { int rv; - rv = pmbus_set_page(client, page); + rv = pmbus_set_page(client, page, 0xff); if (rv < 0) return rv; @@ -286,11 +286,11 @@ int pmbus_update_fan(struct i2c_client *client, int page, int id, } EXPORT_SYMBOL_GPL(pmbus_update_fan); -int pmbus_read_word_data(struct i2c_client *client, int page, u8 reg) +int pmbus_read_word_data(struct i2c_client *client, int page, int phase, u8 reg) { int rv; - rv = pmbus_set_page(client, page); + rv = pmbus_set_page(client, page, phase); if (rv < 0) return rv; @@ -320,14 +320,15 @@ static int pmbus_read_virt_reg(struct i2c_client *client, int page, int reg) * _pmbus_read_word_data() is similar to pmbus_read_word_data(), but checks if * a device specific mapping function exists and calls it if necessary. */ -static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg) +static int _pmbus_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { struct pmbus_data *data = i2c_get_clientdata(client); const struct pmbus_driver_info *info = data->info; int status; if (info->read_word_data) { - status = info->read_word_data(client, page, reg); + status = info->read_word_data(client, page, phase, reg); if (status != -ENODATA) return status; } @@ -335,14 +336,20 @@ static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg) if (reg >= PMBUS_VIRT_BASE) return pmbus_read_virt_reg(client, page, reg); - return pmbus_read_word_data(client, page, reg); + return pmbus_read_word_data(client, page, phase, reg); +} + +/* Same as above, but without phase parameter, for use in check functions */ +static int __pmbus_read_word_data(struct i2c_client *client, int page, int reg) +{ + return _pmbus_read_word_data(client, page, 0xff, reg); } int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg) { int rv; - rv = pmbus_set_page(client, page); + rv = pmbus_set_page(client, page, 0xff); if (rv < 0) return rv; @@ -354,7 +361,7 @@ int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, u8 value) { int rv; - rv = pmbus_set_page(client, page); + rv = pmbus_set_page(client, page, 0xff); if (rv < 0) return rv; @@ -440,7 +447,7 @@ static int pmbus_get_fan_rate(struct i2c_client *client, int page, int id, have_rpm = !!(config & pmbus_fan_rpm_mask[id]); if (want_rpm == have_rpm) - return pmbus_read_word_data(client, page, + return pmbus_read_word_data(client, page, 0xff, pmbus_fan_command_registers[id]); /* Can't sensibly map between RPM and PWM, just return zero */ @@ -530,7 +537,7 @@ EXPORT_SYMBOL_GPL(pmbus_check_byte_register); bool pmbus_check_word_register(struct i2c_client *client, int page, int reg) { - return pmbus_check_register(client, _pmbus_read_word_data, page, reg); + return pmbus_check_register(client, __pmbus_read_word_data, page, reg); } EXPORT_SYMBOL_GPL(pmbus_check_word_register); @@ -595,6 +602,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) sensor->data = _pmbus_read_word_data(client, sensor->page, + 0xff, sensor->reg); } pmbus_clear_faults(client); @@ -1964,7 +1972,7 @@ static ssize_t pmbus_show_samples(struct device *dev, struct i2c_client *client = to_i2c_client(dev->parent); struct pmbus_samples_reg *reg = to_samples_reg(devattr); - val = _pmbus_read_word_data(client, reg->page, reg->attr->reg); + val = _pmbus_read_word_data(client, reg->page, 0xff, reg->attr->reg); if (val < 0) return val; @@ -2120,7 +2128,7 @@ static int pmbus_read_status_byte(struct i2c_client *client, int page) static int pmbus_read_status_word(struct i2c_client *client, int page) { - return _pmbus_read_word_data(client, page, PMBUS_STATUS_WORD); + return _pmbus_read_word_data(client, page, 0xff, PMBUS_STATUS_WORD); } static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c index 23ea3415f166..81f4c4f166cd 100644 --- a/drivers/hwmon/pmbus/ucd9000.c +++ b/drivers/hwmon/pmbus/ucd9000.c @@ -370,7 +370,7 @@ static void ucd9000_probe_gpio(struct i2c_client *client, #ifdef CONFIG_DEBUG_FS static int ucd9000_get_mfr_status(struct i2c_client *client, u8 *buffer) { - int ret = pmbus_set_page(client, 0); + int ret = pmbus_set_page(client, 0, 0xff); if (ret < 0) return ret; diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c index 190b898e404a..3a827d0a881d 100644 --- a/drivers/hwmon/pmbus/zl6100.c +++ b/drivers/hwmon/pmbus/zl6100.c @@ -125,7 +125,8 @@ static inline void zl6100_wait(const struct zl6100_data *data) } } -static int zl6100_read_word_data(struct i2c_client *client, int page, int reg) +static int zl6100_read_word_data(struct i2c_client *client, int page, + int phase, int reg) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); struct zl6100_data *data = to_zl6100_data(info); @@ -167,7 +168,7 @@ static int zl6100_read_word_data(struct i2c_client *client, int page, int reg) } zl6100_wait(data); - ret = pmbus_read_word_data(client, page, vreg); + ret = pmbus_read_word_data(client, page, phase, vreg); data->access = ktime_get(); if (ret < 0) return ret; From patchwork Sat Feb 15 12:25:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11383847 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 541B11820 for ; Sat, 15 Feb 2020 12:26:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2D2F82083B for ; Sat, 15 Feb 2020 12:26:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JiqYpnRG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725971AbgBOM0M (ORCPT ); Sat, 15 Feb 2020 07:26:12 -0500 Received: from mail-pg1-f176.google.com ([209.85.215.176]:38630 "EHLO mail-pg1-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725937AbgBOM0L (ORCPT ); Sat, 15 Feb 2020 07:26:11 -0500 Received: by mail-pg1-f176.google.com with SMTP id d6so6563277pgn.5 for ; Sat, 15 Feb 2020 04:26:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=yphG9a62T919RVoCRAlzDsuykTSypn95aVQX3ODwS7k=; b=JiqYpnRG5qDm79ztT94c3rAXyjGT82tqywQSDKB6ElA9OfqsHcTljvKEpmrI/GjafX z2wZmkwOcyDtnAoeyNf1uh3pRob+P7aubLEnb7rHbXcQxutUCMlw9NzYJCv69FvIuSSb JAGFHaoUod/NXRntrhkttNtqxq9nq+8Zpvj8fuZ5W4R6l/LVuC3By0bchR9IIEkvm0MW 3L9vP3YG9PXFD5t5Ry0pYuXg0vLV80ByxdAdbjXTPx7JEJ4F35vW78/EMUYhWp3uiO8E 9s0RnQg4H477+B5bUsKptl3W2Y4OSppDIlnHT/LFRebgCUnbsy43hJykzmVprsvki8VS +aJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=yphG9a62T919RVoCRAlzDsuykTSypn95aVQX3ODwS7k=; b=fmr/rCtRaNnAns99WzrGr4yZ26ildGk00R/PAas8afcLOiae9newTT3LbVuvg7K55W Njg02/EqCWLyT36blvTnYf7WahPSZYT4ev0Z6GXlFUgmbCpxRK5cdHCiy+RZVyGMqKAW uvQeRKUg4zgmgLG+yP9Z4wvFMHBsZVr+GVsXyc6/9j9TkCc45boOTw/mkGKmDwOQed4L aXdzl1ww68RVIsqN41DuRODC54TZYXb4FgUMUmm8avPDAVyk62kydxSWAS9ZJ6EsDATC CSo7vsb1stFioz4yhGzrFxauUwlgBoqSl9YkM6GdiCReUqqmRuTWXthy99l1nk97KKc9 OXxw== X-Gm-Message-State: APjAAAVZR6DZNmdlfdUxLnjhBBfv9d6j/exJfBpqeQQxoDXQgFjqvC3D 1be4t8lrgU6khJZVgq2mnywc3rI8 X-Google-Smtp-Source: APXvYqxN8Sfur46jYEgB4/z7wF5Pcj1I8+WiE0mSZSxRf7HR7j7AxJtHkj3pzjL9dGCoeH+GUvOl+Q== X-Received: by 2002:aa7:9218:: with SMTP id 24mr8000040pfo.145.1581769568007; Sat, 15 Feb 2020 04:26:08 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id 4sm10722204pfn.90.2020.02.15.04.26.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Feb 2020 04:26:07 -0800 (PST) From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck , Vadim Pasternak Subject: [PATCH 3/8] hwmon: (pmbus) Implement multi-phase support Date: Sat, 15 Feb 2020 04:25:57 -0800 Message-Id: <20200215122602.14245-3-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200215122602.14245-1-linux@roeck-us.net> References: <20200215122602.14245-1-linux@roeck-us.net> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Some PMBus chips support multiple phases, and report telemetry such as input current, output current, or temperature for each phase. Add support for such chips to the PMBus core. Start with a maximum of 8 phases per page, and assume that supported sensors per phase are similar for all pages. Only support per-phase telemetry attributes, no limits or alarms. As part of this patch, set the initial page variable to 0xff to ensure that the page is updated when the first page command is issued. Also only issue page commands if the chip supports more than one page. Cc: Vadim Pasternak Signed-off-by: Guenter Roeck --- Documentation/hwmon/pmbus.rst | 8 ++- drivers/hwmon/pmbus/pmbus.h | 6 ++- drivers/hwmon/pmbus/pmbus_core.c | 85 +++++++++++++++++++++++--------- 3 files changed, 74 insertions(+), 25 deletions(-) diff --git a/Documentation/hwmon/pmbus.rst b/Documentation/hwmon/pmbus.rst index f787984e88a9..2658ddee70eb 100644 --- a/Documentation/hwmon/pmbus.rst +++ b/Documentation/hwmon/pmbus.rst @@ -227,7 +227,9 @@ currX_lcrit_alarm Output current critical low alarm. From IOUT_UC_FAULT status. currX_crit_alarm Current critical high alarm. From IIN_OC_FAULT or IOUT_OC_FAULT status. -currX_label "iin" or "ioutY" +currX_label "iin", "iinY", "iinY.Z", "ioutY", or "ioutY.Z", + where Y reflects the page number and Z reflects the + phase. powerX_input Measured power. From READ_PIN or READ_POUT register. powerX_cap Output power cap. From POUT_MAX register. @@ -239,7 +241,9 @@ powerX_alarm Power high alarm. From PIN_OP_WARNING or POUT_OP_WARNING status. powerX_crit_alarm Output power critical high alarm. From POUT_OP_FAULT status. -powerX_label "pin" or "poutY" +powerX_label "pin", "pinY", "pinY.Z", "poutY", or "poutY.Z", + where Y reflects the page number and Z reflects the + phase. tempX_input Measured temperature. From READ_TEMPERATURE_X register. diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index 27c7ae0ffa6b..18e06fc6c53f 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h @@ -362,6 +362,7 @@ enum pmbus_sensor_classes { }; #define PMBUS_PAGES 32 /* Per PMBus specification */ +#define PMBUS_PHASES 8 /* Maximum number of phases per page */ /* Functionality bit mask */ #define PMBUS_HAVE_VIN BIT(0) @@ -388,13 +389,15 @@ enum pmbus_sensor_classes { #define PMBUS_HAVE_PWM34 BIT(21) #define PMBUS_HAVE_SAMPLES BIT(22) -#define PMBUS_PAGE_VIRTUAL BIT(31) +#define PMBUS_PHASE_VIRTUAL BIT(30) /* Phases on this page are virtual */ +#define PMBUS_PAGE_VIRTUAL BIT(31) /* Page is virtual */ enum pmbus_data_format { linear = 0, direct, vid }; enum vrm_version { vr11 = 0, vr12, vr13, imvp9, amd625mv }; struct pmbus_driver_info { int pages; /* Total number of pages */ + u8 phases[PMBUS_PAGES]; /* Number of phases per page */ enum pmbus_data_format format[PSC_NUM_CLASSES]; enum vrm_version vrm_version[PMBUS_PAGES]; /* vrm version per page */ /* @@ -406,6 +409,7 @@ struct pmbus_driver_info { int R[PSC_NUM_CLASSES]; /* exponent */ u32 func[PMBUS_PAGES]; /* Functionality, per page */ + u32 pfunc[PMBUS_PHASES];/* Functionality, per phase */ /* * The following functions map manufacturing specific register values * to PMBus standard register values. Specify only if mapping is diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 9343ca7d4069..8d321bf7d15b 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -49,6 +49,7 @@ struct pmbus_sensor { char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ struct device_attribute attribute; u8 page; /* page number */ + u8 phase; /* phase number, 0xff for all phases */ u16 reg; /* register */ enum pmbus_sensor_classes class; /* sensor class */ bool update; /* runtime sensor update needed */ @@ -109,6 +110,7 @@ struct pmbus_data { int (*read_status)(struct i2c_client *client, int page); u8 currpage; + u8 currphase; /* current phase, 0xff for all */ }; struct pmbus_debugfs_entry { @@ -151,10 +153,11 @@ int pmbus_set_page(struct i2c_client *client, int page, int phase) struct pmbus_data *data = i2c_get_clientdata(client); int rv; - if (page < 0 || page == data->currpage) + if (page < 0) return 0; - if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL)) { + if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL) && + data->info->pages > 1 && page != data->currpage) { rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); if (rv < 0) return rv; @@ -166,9 +169,17 @@ int pmbus_set_page(struct i2c_client *client, int page, int phase) if (rv != page) return -EIO; } - data->currpage = page; + if (data->info->phases[page] && data->currphase != phase && + !(data->info->func[page] & PMBUS_PHASE_VIRTUAL)) { + rv = i2c_smbus_write_byte_data(client, PMBUS_PHASE, + phase); + if (rv) + return rv; + } + data->currphase = phase; + return 0; } EXPORT_SYMBOL_GPL(pmbus_set_page); @@ -602,7 +613,7 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) sensor->data = _pmbus_read_word_data(client, sensor->page, - 0xff, + sensor->phase, sensor->reg); } pmbus_clear_faults(client); @@ -1084,7 +1095,8 @@ static int pmbus_add_boolean(struct pmbus_data *data, static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, const char *name, const char *type, - int seq, int page, int reg, + int seq, int page, int phase, + int reg, enum pmbus_sensor_classes class, bool update, bool readonly, bool convert) @@ -1108,6 +1120,7 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, readonly = true; sensor->page = page; + sensor->phase = phase; sensor->reg = reg; sensor->class = class; sensor->update = update; @@ -1127,7 +1140,7 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, static int pmbus_add_label(struct pmbus_data *data, const char *name, int seq, - const char *lstring, int index) + const char *lstring, int index, int phase) { struct pmbus_label *label; struct device_attribute *a; @@ -1139,11 +1152,21 @@ static int pmbus_add_label(struct pmbus_data *data, a = &label->attribute; snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq); - if (!index) - strncpy(label->label, lstring, sizeof(label->label) - 1); - else - snprintf(label->label, sizeof(label->label), "%s%d", lstring, - index); + if (!index) { + if (phase == 0xff) + strncpy(label->label, lstring, + sizeof(label->label) - 1); + else + snprintf(label->label, sizeof(label->label), "%s.%d", + lstring, phase); + } else { + if (phase == 0xff) + snprintf(label->label, sizeof(label->label), "%s%d", + lstring, index); + else + snprintf(label->label, sizeof(label->label), "%s%d.%d", + lstring, index, phase); + } pmbus_dev_attr_init(a, label->name, 0444, pmbus_show_label, NULL); return pmbus_add_attribute(data, &a->attr); @@ -1208,7 +1231,7 @@ static int pmbus_add_limit_attrs(struct i2c_client *client, for (i = 0; i < nlimit; i++) { if (pmbus_check_word_register(client, page, l->reg)) { curr = pmbus_add_sensor(data, name, l->attr, index, - page, l->reg, attr->class, + page, 0xff, l->reg, attr->class, attr->update || l->update, false, true); if (!curr) @@ -1235,7 +1258,7 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client, struct pmbus_data *data, const struct pmbus_driver_info *info, const char *name, - int index, int page, + int index, int page, int phase, const struct pmbus_sensor_attr *attr, bool paged) { @@ -1245,15 +1268,16 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client, if (attr->label) { ret = pmbus_add_label(data, name, index, attr->label, - paged ? page + 1 : 0); + paged ? page + 1 : 0, phase); if (ret) return ret; } - base = pmbus_add_sensor(data, name, "input", index, page, attr->reg, - attr->class, true, true, true); + base = pmbus_add_sensor(data, name, "input", index, page, phase, + attr->reg, attr->class, true, true, true); if (!base) return -ENOMEM; - if (attr->sfunc) { + /* No limit and alarm attributes for phase specific sensors */ + if (attr->sfunc && phase == 0xff) { ret = pmbus_add_limit_attrs(client, data, info, name, index, page, base, attr); if (ret < 0) @@ -1323,10 +1347,25 @@ static int pmbus_add_sensor_attrs(struct i2c_client *client, continue; ret = pmbus_add_sensor_attrs_one(client, data, info, name, index, page, - attrs, paged); + 0xff, attrs, paged); if (ret) return ret; index++; + if (info->phases[page]) { + int phase; + + for (phase = 0; phase < info->phases[page]; + phase++) { + if (!(info->pfunc[phase] & attrs->func)) + continue; + ret = pmbus_add_sensor_attrs_one(client, + data, info, name, index, page, + phase, attrs, paged); + if (ret) + return ret; + index++; + } + } } attrs++; } @@ -1830,7 +1869,7 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client, struct pmbus_sensor *sensor; sensor = pmbus_add_sensor(data, "fan", "target", index, page, - PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN, + PMBUS_VIRT_FAN_TARGET_1 + id, 0xff, PSC_FAN, false, false, true); if (!sensor) @@ -1841,14 +1880,14 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client, return 0; sensor = pmbus_add_sensor(data, "pwm", NULL, index, page, - PMBUS_VIRT_PWM_1 + id, PSC_PWM, + PMBUS_VIRT_PWM_1 + id, 0xff, PSC_PWM, false, false, true); if (!sensor) return -ENOMEM; sensor = pmbus_add_sensor(data, "pwm", "enable", index, page, - PMBUS_VIRT_PWM_ENABLE_1 + id, PSC_PWM, + PMBUS_VIRT_PWM_ENABLE_1 + id, 0xff, PSC_PWM, true, false, false); if (!sensor) @@ -1890,7 +1929,7 @@ static int pmbus_add_fan_attributes(struct i2c_client *client, continue; if (pmbus_add_sensor(data, "fan", "input", index, - page, pmbus_fan_registers[f], + page, pmbus_fan_registers[f], 0xff, PSC_FAN, true, true, true) == NULL) return -ENOMEM; @@ -2490,6 +2529,8 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, if (pdata) data->flags = pdata->flags; data->info = info; + data->currpage = 0xff; + data->currphase = 0xfe; ret = pmbus_init_common(client, data, info); if (ret < 0) From patchwork Sat Feb 15 12:25:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11383845 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1E9481580 for ; Sat, 15 Feb 2020 12:26:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F3D872073A for ; Sat, 15 Feb 2020 12:26:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="tmMyf2WC" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725974AbgBOM0L (ORCPT ); Sat, 15 Feb 2020 07:26:11 -0500 Received: from mail-pf1-f193.google.com ([209.85.210.193]:35972 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725971AbgBOM0L (ORCPT ); Sat, 15 Feb 2020 07:26:11 -0500 Received: by mail-pf1-f193.google.com with SMTP id 185so6430416pfv.3 for ; Sat, 15 Feb 2020 04:26:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=JkAfwVZbNWHGdpldwRHrZyonVhihXq8lzmcEbXl+TRM=; b=tmMyf2WCT8VRZFSetrPsMl49WPojEGlJ7IuZtQ0m3MAMHck5ES/XXkySUFxH8W846S FFQW0Ms+WWuF6AvU0mb602nZTu2GeJZ6oekMVC5cEM0XpAn26OMUuD4UwXfy5gOeMq1v DTHnb+Tdicc0fWhEf8f7U7DxKNSc0BJsw/tPE4Kx/X6C432HuOnu28CLK+Ba0f31TJwJ TPxOgGEblAEJHKzOi3PaY9Owq20I4wtmc0OZ9o10HH+FmIvAyblmheBUH56nmStRNKEs vefeSiELXw8RXl0+OMv+bBoh1crgWi6dhZv66uq79oqPtFjcGjhfdBCIUVMpJl6m0VL1 4LHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=JkAfwVZbNWHGdpldwRHrZyonVhihXq8lzmcEbXl+TRM=; b=ujJAT/PfR+M9I8EskdnUqJ8LdsVxyWWU0AOVNqZrBKnJY+vJ21w8RmpYOSixXvPTTs VU6/6uBiaJi8z/2btwsImiaTgncLWVlubqiCFHXwty+QtwBGsp/0gqBkxq+hHjcpWCdb E0qM8nEIhubBoRyGejNv5xAfaX2gis9XEOihgrKamvntdwbEHspvdfOKfMjUIdyHoW2E RHS8lst0um57PiF9pGy1ptj/TW7kN1dNg9s/RN64nDrTXnEiYH/sLlNAzLLWdozXh5Iz BeRdVk4qaxBl/vSgcMPYBbjZY4U9DpFkUiDTHor+aYeesvGfC67ZuRLRyk9kU359fWQe GDLw== X-Gm-Message-State: APjAAAUoChnKufJETZnkKReKewIJxYzafjC6CVpyFyTMSNC11TofCPEu bGaUeGHeWaI13vABAPygt558Q7Lc X-Google-Smtp-Source: APXvYqyHm+RQiT8jlUbCe/p2hvXlwSAi6ES08XVVcmyuyHdRdvWOpL3OtBVfSCVnF/sf9BGkB8z6kA== X-Received: by 2002:aa7:8181:: with SMTP id g1mr8191448pfi.215.1581769570659; Sat, 15 Feb 2020 04:26:10 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id x143sm11140881pgx.54.2020.02.15.04.26.08 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Feb 2020 04:26:09 -0800 (PST) From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck , Vadim Pasternak Subject: [PATCH 4/8] hwmon: (pmbus/tps53679) Add support for multiple chips IDs Date: Sat, 15 Feb 2020 04:25:58 -0800 Message-Id: <20200215122602.14245-4-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200215122602.14245-1-linux@roeck-us.net> References: <20200215122602.14245-1-linux@roeck-us.net> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Chip specific support will be needed in the driver to be able to support additional chips of the same series. Add support for it to the driver. To simplify adding support for more chips, call identification code from the probe function. This lets us use a single structure for common elements of struct pmbus_driver_info, thus reducing code size as support for more chips is added. Cc: Vadim Pasternak Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/tps53679.c | 41 +++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/pmbus/tps53679.c b/drivers/hwmon/pmbus/tps53679.c index 9c22e9013dd7..77b2fb06c0d2 100644 --- a/drivers/hwmon/pmbus/tps53679.c +++ b/drivers/hwmon/pmbus/tps53679.c @@ -11,8 +11,13 @@ #include #include #include +#include #include "pmbus.h" +enum chips { + tps53679, tps53688, +}; + #define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */ #define TPS53679_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */ #define TPS53679_PROT_VR13_10MV 0x04 /* VR13.0 mode, 10-mV DAC */ @@ -53,47 +58,63 @@ static int tps53679_identify(struct i2c_client *client, } static struct pmbus_driver_info tps53679_info = { - .pages = TPS53679_PAGE_NUM, .format[PSC_VOLTAGE_IN] = linear, .format[PSC_VOLTAGE_OUT] = vid, .format[PSC_TEMPERATURE] = linear, .format[PSC_CURRENT_OUT] = linear, .format[PSC_POWER] = linear, - .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + .func[0] = PMBUS_HAVE_VIN | + PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_POUT, - .func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + .func[1] = PMBUS_HAVE_VIN | + PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_POUT, - .identify = tps53679_identify, }; static int tps53679_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; struct pmbus_driver_info *info; + enum chips chip_id; + + if (dev->of_node) + chip_id = (enum chips)of_device_get_match_data(dev); + else + chip_id = id->driver_data; - info = devm_kmemdup(&client->dev, &tps53679_info, sizeof(*info), - GFP_KERNEL); + info = devm_kmemdup(dev, &tps53679_info, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; + switch (chip_id) { + case tps53679: + case tps53688: + info->pages = TPS53679_PAGE_NUM; + info->identify = tps53679_identify; + break; + default: + return -ENODEV; + } + return pmbus_do_probe(client, id, info); } static const struct i2c_device_id tps53679_id[] = { - {"tps53679", 0}, - {"tps53688", 0}, + {"tps53679", tps53679}, + {"tps53688", tps53688}, {} }; MODULE_DEVICE_TABLE(i2c, tps53679_id); static const struct of_device_id __maybe_unused tps53679_of_match[] = { - {.compatible = "ti,tps53679"}, - {.compatible = "ti,tps53688"}, + {.compatible = "ti,tps53679", .data = (void *)tps53679}, + {.compatible = "ti,tps53688", .data = (void *)tps53688}, {} }; MODULE_DEVICE_TABLE(of, tps53679_of_match); From patchwork Sat Feb 15 12:25:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11383849 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 976EB159A for ; Sat, 15 Feb 2020 12:26:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 783F82073A for ; Sat, 15 Feb 2020 12:26:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fidofetq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726007AbgBOM0N (ORCPT ); Sat, 15 Feb 2020 07:26:13 -0500 Received: from mail-pj1-f65.google.com ([209.85.216.65]:54533 "EHLO mail-pj1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725937AbgBOM0N (ORCPT ); Sat, 15 Feb 2020 07:26:13 -0500 Received: by mail-pj1-f65.google.com with SMTP id dw13so5182193pjb.4 for ; Sat, 15 Feb 2020 04:26:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=V80Rj9uWCqbUwOljaNc1fQM4FIcB47cZEgf4BZ3vhOQ=; b=fidofetqHEjtWTsajb4Iy4QVKHfIDlxZwqGyYa2Ay0E8cJGDwRidmFCCP0Q5E0tY2i tRSIFQ9s3GrIp9T9uquFUN9N6hxDua2KEFuxeIOoLWiHtt3UB1/EiGx4zXGhtMymM9nd 7gEqpvkjTNqyPlySfZl8v9ubEPeIX59uVZxhAacfzGqgRLs/XVBTc9nkemf/O3i8bF4b VgbGe8t2fYitOMAwDe6DwkZ6wInpyUuyw1I7o3Emi393k8e3REuJygeuGkuKxeFVZxoU x3l8d2yabNFAJa2TLp/nmlMeIMA+5HrfXkqCoGZICoqP1YTMC+pabdhwXYxBnLuG0LfX yQxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=V80Rj9uWCqbUwOljaNc1fQM4FIcB47cZEgf4BZ3vhOQ=; b=hRypKnk5GOROG8PFw4msj02Qd2jnXwCU7z6DcUMvGWttbc4mI3przF6cBjJ3jXeZFO c/1EWSIqah+AGIXbVUNDjFapY19yN9HyMyQOw66UMnFxUi7eYO+rhAPxaP4yFXcCz5X3 c5t3+An99EjS8xP6r4d3jP1E8BpD4EkbuHMYDF7erkIZ2sHJb+Hv43UPCANDNkMoy+FW 5WeGq82K+JkWry+EiG6KI8NvJiZI6kaKOpa+c1YZt+SWCb5Svti+gDevpAZ4l8siQt5f euakhWjdzYe7I4CW8p6GR4hCwq3jOBCyc8ibxbHiuWylAKPhTpV4//2OWN0XhkKJpCYu F5Hg== X-Gm-Message-State: APjAAAXKFJ/Z24D8B7HZZuqpXA/yO+JcEM7Ou46Gw88mwaHSfNEZKu5t Q9K+cf8EPH04nG1GMa/J8sl8wpL/ X-Google-Smtp-Source: APXvYqx+8wLMb/7QNRhzAJhwqsDRW/LbsTrU0XFnc6zbc9PdJpkymBqVCFj97DQnA6rACGoyTk2G/Q== X-Received: by 2002:a17:902:8d83:: with SMTP id v3mr8037036plo.282.1581769572127; Sat, 15 Feb 2020 04:26:12 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id j8sm10515875pjb.4.2020.02.15.04.26.11 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Feb 2020 04:26:11 -0800 (PST) From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck Subject: [PATCH 5/8] hwmon: (pmbus/tps53679) Add support for IIN and PIN to TPS53679 and TPS53688 Date: Sat, 15 Feb 2020 04:25:59 -0800 Message-Id: <20200215122602.14245-5-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200215122602.14245-1-linux@roeck-us.net> References: <20200215122602.14245-1-linux@roeck-us.net> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org All chips of this series with published datasheets support IIN, PIN, and STATUS_INPUT PMBus commands. Per TI Power Management Forum, "TPS53679 and TPS53681 have the same PMBus command set". There is no reason to believe that this does not apply to TPS53688. Let's assume that this is correct and add support for IIN, PIN, and STATUS_INPUT to TPS53679 and TPS53688 to simplify adding support for more chips of the same series. At the same time, drop reporting VIN on channel 2. On chips with published datasheets this voltage is identical to the voltage reported on channel 1, and there is no reason to believe that this is different for TPS53679 and TPS53888. Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/tps53679.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/pmbus/tps53679.c b/drivers/hwmon/pmbus/tps53679.c index 77b2fb06c0d2..2a6495424a87 100644 --- a/drivers/hwmon/pmbus/tps53679.c +++ b/drivers/hwmon/pmbus/tps53679.c @@ -63,13 +63,13 @@ static struct pmbus_driver_info tps53679_info = { .format[PSC_TEMPERATURE] = linear, .format[PSC_CURRENT_OUT] = linear, .format[PSC_POWER] = linear, - .func[0] = PMBUS_HAVE_VIN | + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | + PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_POUT, - .func[1] = PMBUS_HAVE_VIN | - PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | + .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_POUT, From patchwork Sat Feb 15 12:26:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11383851 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0F4521580 for ; Sat, 15 Feb 2020 12:26:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DB7542073A for ; Sat, 15 Feb 2020 12:26:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Oz3W9UT1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726090AbgBOM0O (ORCPT ); Sat, 15 Feb 2020 07:26:14 -0500 Received: from mail-pj1-f67.google.com ([209.85.216.67]:54537 "EHLO mail-pj1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725937AbgBOM0O (ORCPT ); Sat, 15 Feb 2020 07:26:14 -0500 Received: by mail-pj1-f67.google.com with SMTP id dw13so5182213pjb.4 for ; Sat, 15 Feb 2020 04:26:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=nhecDubL59hJk+LQ1GiKxKu1rI6q/YrXu6oshEKLiHA=; b=Oz3W9UT1AbwL0nEVeGfcxXoo4bMKJOrWHcQiqurwBmDgONG80aM3NL51+dPjJq6+0b Y7PAoAbJTuQWQVQvl1HjQddrIj+ptz5kzXrEv3COK4QfM+5Jh2SmwUv48NjrLuo6mFq6 Iw2nTYNV1wzTJ7Ya0RCPOv+7ueOhKYW0kboa7nEQ4fzv17qfm+8UldZhOyVw6+mCXcA1 L8BAW/RJT6M2blrUUBgi/pM622jkr7BXC9ij60949yWmuSqNVlALipnqZ7UtB1fSMoxg xPoFYGyfCdfYnI2sTI5lLLvuAWYJlHSEYLdv4yNFAlRCVjKT9kwWDshuf5knbQknOuhr iWXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=nhecDubL59hJk+LQ1GiKxKu1rI6q/YrXu6oshEKLiHA=; b=TWTXeKiv0Pzdoj0Qx+NdP2VwmNWvOk/OmBjIz/j8yH88/jgIboNRnhk1/Z1nA6P8Pw laBWwsN/GUlsSAhwzbSNPi4MxAeq/07o4zqtywR/hbCEFuNon9eIUfTNN6IwJgGDgHNV 1FdnBgEkHDP7I9HzhuyU//1vd+diyJTXL6wx1oxEn0Jk+n9mzMewosTyyFS/gQ1YiKRD QJVl6i4T2ZmqlChNKAylXpcl8dr9EJSJZvoLwobXcGlY0dT7w9DiH442aLvdKijEGoah 2CEYK1c4n+KolC1IDLM2dCCWrPRAyC4CLtfA1rqCOZPTv4q9WZ5EFGhxf8hfvcHRWABL dDTA== X-Gm-Message-State: APjAAAUvlyvchb20eRobAYujy9lIEHgqtsEKJcHMf/kgZI/D5LecLIdD ZrynK51gE3+SseMjtQZ50OhzJ5lF X-Google-Smtp-Source: APXvYqzXIDApculiRTlFN7nkT8y9dr/ZbJkSaq2+YvGQahBcSj/fVwus+HZhtMmnjp/kdysRYIjMGw== X-Received: by 2002:a17:90a:ff15:: with SMTP id ce21mr9329832pjb.124.1581769573499; Sat, 15 Feb 2020 04:26:13 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id g10sm10751636pfo.166.2020.02.15.04.26.12 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Feb 2020 04:26:13 -0800 (PST) From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck , Vadim Pasternak Subject: [PATCH 6/8] hwmon: (pmbus/tps53679) Add support for TPS53681 Date: Sat, 15 Feb 2020 04:26:00 -0800 Message-Id: <20200215122602.14245-6-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200215122602.14245-1-linux@roeck-us.net> References: <20200215122602.14245-1-linux@roeck-us.net> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org TPS53681 is a dual-channel multiphase step-down controller supporting per-phase and per-channel output telemetry. Cc: Vadim Pasternak Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/Kconfig | 4 +- drivers/hwmon/pmbus/tps53679.c | 120 ++++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 5 deletions(-) diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index a9ea06204767..07bd5a4592bf 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig @@ -209,10 +209,10 @@ config SENSORS_TPS40422 be called tps40422. config SENSORS_TPS53679 - tristate "TI TPS53679, TPS53688" + tristate "TI TPS53679, TPS53681, TPS53688" help If you say yes here you get hardware monitoring support for TI - TPS53679, TPS53688 + TPS53679, TPS53681, and TPS53688. This driver can also be built as a module. If so, the module will be called tps53679. diff --git a/drivers/hwmon/pmbus/tps53679.c b/drivers/hwmon/pmbus/tps53679.c index 2a6495424a87..eb6e2ea0e66c 100644 --- a/drivers/hwmon/pmbus/tps53679.c +++ b/drivers/hwmon/pmbus/tps53679.c @@ -6,6 +6,7 @@ * Copyright (c) 2017 Vadim Pasternak */ +#include #include #include #include @@ -15,7 +16,7 @@ #include "pmbus.h" enum chips { - tps53679, tps53688, + tps53679, tps53681, tps53688 }; #define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */ @@ -25,8 +26,14 @@ enum chips { #define TPS53679_PROT_VR13_5MV 0x07 /* VR13.0 mode, 5-mV DAC */ #define TPS53679_PAGE_NUM 2 -static int tps53679_identify(struct i2c_client *client, - struct pmbus_driver_info *info) +#define TPS53681_DEVICE_ID 0x81 + +#define TPS53681_PMBUS_REVISION 0x33 + +#define TPS53681_MFR_SPECIFIC_20 0xe4 /* Number of phases, per page */ + +static int tps53679_identify_mode(struct i2c_client *client, + struct pmbus_driver_info *info) { u8 vout_params; int i, ret; @@ -57,6 +64,99 @@ static int tps53679_identify(struct i2c_client *client, return 0; } +static int tps53679_identify_phases(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + int ret; + + /* On TPS53681, only channel A provides per-phase output current */ + ret = pmbus_read_byte_data(client, 0, TPS53681_MFR_SPECIFIC_20); + if (ret < 0) + return ret; + info->phases[0] = (ret & 0x07) + 1; + + return 0; +} + +static int tps53679_identify_chip(struct i2c_client *client, + u8 revision, u16 id) +{ + u8 buf[I2C_SMBUS_BLOCK_MAX]; + int ret; + + ret = pmbus_read_byte_data(client, 0, PMBUS_REVISION); + if (ret < 0) + return ret; + if (ret != revision) { + dev_err(&client->dev, "Unexpected PMBus revision 0x%x\n", ret); + return -ENODEV; + } + + ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf); + if (ret < 0) + return ret; + if (ret != 1 || buf[0] != id) { + dev_err(&client->dev, "Unexpected device ID 0x%x\n", buf[0]); + return -ENODEV; + } + return 0; +} + +/* + * Common identification function for chips with multi-phase support. + * Since those chips have special configuration registers, we want to have + * some level of reassurance that we are really talking with the chip + * being probed. Check PMBus revision and chip ID. + */ +static int tps53679_identify_multiphase(struct i2c_client *client, + struct pmbus_driver_info *info, + int pmbus_rev, int device_id) +{ + int ret; + + ret = tps53679_identify_chip(client, pmbus_rev, device_id); + if (ret < 0) + return ret; + + ret = tps53679_identify_mode(client, info); + if (ret < 0) + return ret; + + return tps53679_identify_phases(client, info); +} + +static int tps53679_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + return tps53679_identify_mode(client, info); +} + +static int tps53681_identify(struct i2c_client *client, + struct pmbus_driver_info *info) +{ + return tps53679_identify_multiphase(client, info, + TPS53681_PMBUS_REVISION, + TPS53681_DEVICE_ID); +} + +static int tps53681_read_word_data(struct i2c_client *client, int page, + int phase, int reg) +{ + /* + * For reading the total output current (READ_IOUT) for all phases, + * the chip datasheet is a bit vague. It says "PHASE must be set to + * FFh to access all phases simultaneously. PHASE may also be set to + * 80h readack (!) the total phase current". + * Experiments show that the command does _not_ report the total + * current for all phases if the phase is set to 0xff. Instead, it + * appears to report the current of one of the phases. Override phase + * parameter with 0x80 when reading the total output current on page 0. + */ + if (reg == PMBUS_READ_IOUT && page == 0 && phase == 0xff) + return pmbus_read_word_data(client, page, 0x80, reg); + return -ENODATA; +} + static struct pmbus_driver_info tps53679_info = { .format[PSC_VOLTAGE_IN] = linear, .format[PSC_VOLTAGE_OUT] = vid, @@ -73,6 +173,12 @@ static struct pmbus_driver_info tps53679_info = { PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_POUT, + .pfunc[0] = PMBUS_HAVE_IOUT, + .pfunc[1] = PMBUS_HAVE_IOUT, + .pfunc[2] = PMBUS_HAVE_IOUT, + .pfunc[3] = PMBUS_HAVE_IOUT, + .pfunc[4] = PMBUS_HAVE_IOUT, + .pfunc[5] = PMBUS_HAVE_IOUT, }; static int tps53679_probe(struct i2c_client *client, @@ -97,6 +203,12 @@ static int tps53679_probe(struct i2c_client *client, info->pages = TPS53679_PAGE_NUM; info->identify = tps53679_identify; break; + case tps53681: + info->pages = TPS53679_PAGE_NUM; + info->phases[0] = 6; + info->identify = tps53681_identify; + info->read_word_data = tps53681_read_word_data; + break; default: return -ENODEV; } @@ -106,6 +218,7 @@ static int tps53679_probe(struct i2c_client *client, static const struct i2c_device_id tps53679_id[] = { {"tps53679", tps53679}, + {"tps53681", tps53681}, {"tps53688", tps53688}, {} }; @@ -114,6 +227,7 @@ MODULE_DEVICE_TABLE(i2c, tps53679_id); static const struct of_device_id __maybe_unused tps53679_of_match[] = { {.compatible = "ti,tps53679", .data = (void *)tps53679}, + {.compatible = "ti,tps53681", .data = (void *)tps53681}, {.compatible = "ti,tps53688", .data = (void *)tps53688}, {} }; From patchwork Sat Feb 15 12:26:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11383853 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 487BD1580 for ; Sat, 15 Feb 2020 12:26:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 28B4A2073A for ; Sat, 15 Feb 2020 12:26:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="n3ot+X7q" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726111AbgBOM0Q (ORCPT ); Sat, 15 Feb 2020 07:26:16 -0500 Received: from mail-pg1-f193.google.com ([209.85.215.193]:45434 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725937AbgBOM0P (ORCPT ); Sat, 15 Feb 2020 07:26:15 -0500 Received: by mail-pg1-f193.google.com with SMTP id b9so6426394pgk.12 for ; Sat, 15 Feb 2020 04:26:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=ksNM6jghe9F5KXhnDhz1gSh9uMRZEsmAFlnASz7qBgg=; b=n3ot+X7qvlrIph/8O51/nRoRic5GozS1HSI0buE94OSL8cE529OOAYRt/W1RZ+oojI 3w8YjjqSJxToe0eDIBTeKua5tplmFOXd/byG4quFrfgSBl0V9wo1v5QICGBT0VruZ95+ sdtOZVvHpw+DYKsDI4BeHhvBXWj+i63lk17hsX+pN0sIlDiFpILpZbRVCZ7dluGXggxc OMWH6EuR7vS7Cy1krN7DNtcwQPaa14VlUw6h//r2hH9dAsX4OWZLGch0YrfvqCAj4eqC TRcTDTDmS9ZhI+lZs/ecaRxrQMQfmWNhfTncAD1WJmhdwUu7Cq4Fx8KR/4CsJ+s8PYnk 440w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=ksNM6jghe9F5KXhnDhz1gSh9uMRZEsmAFlnASz7qBgg=; b=Vm0PN0w5u04OqlRGhRaXaWHA0BO4JX96Mko89q5dfS1uHruP6JqV9/NehM/SgfJuAJ b62BjcK4R7YfwlxDP+U4HrA4WpcajherF+7Vhkgf+MjfUf1WpO0p57Rkxw9dpj+lv7y9 j1hbFu6FWWp9u8oo3MtjruHWN7LsXcAaM0Ct97uesV3DSfRuRgothjRTrRG2r1O3w7gT Lya1vWvcwvqN53sXMzmJBDtkwUz2xEKnXt+Q1orwdVH/QHQmKcPL6DpROGUU1/YZuML1 yJmIPKA3ESK7yzUzHYHvKbfJrcPMTJ65TfLkAACGnBQXqJOIyVKhP7fedKfYOZCchtUR St/Q== X-Gm-Message-State: APjAAAXXYceFbnnw1J8QMasqM6xNTCDApbUlQWbvihB5rGhExdjmGh/i /SzGBe2sjfpnMkT42hNQxF99uW4a X-Google-Smtp-Source: APXvYqzH5RALg3NXX9W7AVykLd8/IuubdwV2uJDJOzSON/h6ch4ui/yBSCUllvb9IflEXoHxj/b8HQ== X-Received: by 2002:a62:2b8a:: with SMTP id r132mr7848652pfr.56.1581769574850; Sat, 15 Feb 2020 04:26:14 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id z4sm10394001pfn.42.2020.02.15.04.26.14 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Feb 2020 04:26:14 -0800 (PST) From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck , Vadim Pasternak Subject: [PATCH 7/8] hwmon: (pmbus/tps53679) Add support for TPS53647 and TPS53667 Date: Sat, 15 Feb 2020 04:26:01 -0800 Message-Id: <20200215122602.14245-7-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200215122602.14245-1-linux@roeck-us.net> References: <20200215122602.14245-1-linux@roeck-us.net> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org TPS53647 and TPS53667 are single channel, Step-Down Buck Controllers. TPS53647 supports 4 phases, TPS53667 supports 6 phases. The chips do not support per-phase output telemetry. Cc: Vadim Pasternak Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/Kconfig | 4 ++-- drivers/hwmon/pmbus/tps53679.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 07bd5a4592bf..3b8ae69254e8 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig @@ -209,10 +209,10 @@ config SENSORS_TPS40422 be called tps40422. config SENSORS_TPS53679 - tristate "TI TPS53679, TPS53681, TPS53688" + tristate "TI TPS53647, TPS53667, TPS53679, TPS53681, TPS53688" help If you say yes here you get hardware monitoring support for TI - TPS53679, TPS53681, and TPS53688. + TPS53647, TPS53667, TPS53679, TPS53681, and TPS53688. This driver can also be built as a module. If so, the module will be called tps53679. diff --git a/drivers/hwmon/pmbus/tps53679.c b/drivers/hwmon/pmbus/tps53679.c index eb6e2ea0e66c..157c99ffb52b 100644 --- a/drivers/hwmon/pmbus/tps53679.c +++ b/drivers/hwmon/pmbus/tps53679.c @@ -16,9 +16,11 @@ #include "pmbus.h" enum chips { - tps53679, tps53681, tps53688 + tps53647, tps53667, tps53679, tps53681, tps53688 }; +#define TPS53647_PAGE_NUM 1 + #define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */ #define TPS53679_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */ #define TPS53679_PROT_VR13_10MV 0x04 /* VR13.0 mode, 10-mV DAC */ @@ -38,7 +40,7 @@ static int tps53679_identify_mode(struct i2c_client *client, u8 vout_params; int i, ret; - for (i = 0; i < TPS53679_PAGE_NUM; i++) { + for (i = 0; i < info->pages; i++) { /* Read the register with VOUT scaling value.*/ ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); if (ret < 0) @@ -198,6 +200,11 @@ static int tps53679_probe(struct i2c_client *client, return -ENOMEM; switch (chip_id) { + case tps53647: + case tps53667: + info->pages = TPS53647_PAGE_NUM; + info->identify = tps53679_identify; + break; case tps53679: case tps53688: info->pages = TPS53679_PAGE_NUM; @@ -217,6 +224,8 @@ static int tps53679_probe(struct i2c_client *client, } static const struct i2c_device_id tps53679_id[] = { + {"tps53647", tps53647}, + {"tps53667", tps53667}, {"tps53679", tps53679}, {"tps53681", tps53681}, {"tps53688", tps53688}, @@ -226,6 +235,8 @@ static const struct i2c_device_id tps53679_id[] = { MODULE_DEVICE_TABLE(i2c, tps53679_id); static const struct of_device_id __maybe_unused tps53679_of_match[] = { + {.compatible = "ti,tps53647", .data = (void *)tps53647}, + {.compatible = "ti,tps53667", .data = (void *)tps53667}, {.compatible = "ti,tps53679", .data = (void *)tps53679}, {.compatible = "ti,tps53681", .data = (void *)tps53681}, {.compatible = "ti,tps53688", .data = (void *)tps53688}, From patchwork Sat Feb 15 12:26:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 11383855 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F3B921580 for ; Sat, 15 Feb 2020 12:26:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CC8422082F for ; Sat, 15 Feb 2020 12:26:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UcjXn5oN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726129AbgBOM0R (ORCPT ); Sat, 15 Feb 2020 07:26:17 -0500 Received: from mail-pf1-f175.google.com ([209.85.210.175]:42684 "EHLO mail-pf1-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725937AbgBOM0R (ORCPT ); Sat, 15 Feb 2020 07:26:17 -0500 Received: by mail-pf1-f175.google.com with SMTP id 4so6413474pfz.9 for ; Sat, 15 Feb 2020 04:26:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=UWjND2QgvvYLWyUrbBVs+iZBMdMm+VT6RUnJQxTl6g0=; b=UcjXn5oNN5v2WN+X2Ira+dRqH/JsEibfcUyfgEJFI4rbucQ1iqHHLiVLXOFUno/Dua ShnOQacNu5ONUj74388YQ971qUakT3LMuow4oCfXg/zbpD0JW+HtyxUvvlai2T7cadUq dcpAiBTVUKoUO8tFou0rvh3zV5FpOzL7GkU+W7aM4VlrvisusOn6Mpg0U3zGc+16P6IU j1PPUi1uEwRqlquTrfkLSfsosm6sptzANbioUndGdJt/Ldi27Q3973Eznt90dGPb6oMj mm6tg/OAizm4Z+Pt/aazE/P/MCAZjGZTLWghui7MvGIeyUZnqsyyT0Jkm0yNOi1VQ0Rp 3sGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=UWjND2QgvvYLWyUrbBVs+iZBMdMm+VT6RUnJQxTl6g0=; b=LWW3SW3oiPe2q4NgzjMLPKIT+vVPxYpy5t2D6+iEUNOYB7CpLKZ6+6iPh882jIpDQb ALQn62pucKzcevNmfkLGiUUGM/02csDJGlmHjdlLs9tYgmJ+TlJVDhU1gP3L0djOwQ3y szckl1Poh82Tbb90Tn0AMrVX7PhAryKETdl3J9ANZN8VhirSl5l+l7m+tP41clSSOSw3 GwFxUqs1SBh+JuEMS5cfqngpG0tdLn7ZCWiDsfN8Tc0lqWq8OZ/BbZNaDZ0GJToLakuQ /4JhkHPCiX21DxN8tSz8J7D31VDbs7p6dkEI1/4W/l41Qz7Eo6gTX2rIRvk+2ET3lJpn rNUQ== X-Gm-Message-State: APjAAAWpKhVPtwf99YF+JB0PoD+3ufzG4bqf886/f9o9nCjopRuTUQ0J VDhmXfe0pVK6IYxyMV9yxSxoVx5K X-Google-Smtp-Source: APXvYqwn5ptx5yDXj21piGU6Zx4QA0ZIQBvp5+mToTyUvuzaIpyM4FwPItY4cZ4VFfzGUgprnLQ44A== X-Received: by 2002:a63:a541:: with SMTP id r1mr8417080pgu.118.1581769576210; Sat, 15 Feb 2020 04:26:16 -0800 (PST) Received: from localhost ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id 13sm10225234pfj.68.2020.02.15.04.26.15 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 15 Feb 2020 04:26:15 -0800 (PST) From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck Subject: [PATCH 8/8] hwmon: (pmbus/tps53679) Add documentation Date: Sat, 15 Feb 2020 04:26:02 -0800 Message-Id: <20200215122602.14245-8-linux@roeck-us.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200215122602.14245-1-linux@roeck-us.net> References: <20200215122602.14245-1-linux@roeck-us.net> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Document tps53679 driver with all chips supported by it. Signed-off-by: Guenter Roeck --- Documentation/hwmon/index.rst | 1 + Documentation/hwmon/tps53679.rst | 178 +++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 Documentation/hwmon/tps53679.rst diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst index b24adb67ddca..8ef62fd39787 100644 --- a/Documentation/hwmon/index.rst +++ b/Documentation/hwmon/index.rst @@ -162,6 +162,7 @@ Hardware Monitoring Kernel Drivers tmp421 tmp513 tps40422 + tps53679 twl4030-madc-hwmon ucd9000 ucd9200 diff --git a/Documentation/hwmon/tps53679.rst b/Documentation/hwmon/tps53679.rst new file mode 100644 index 000000000000..be94cab78967 --- /dev/null +++ b/Documentation/hwmon/tps53679.rst @@ -0,0 +1,178 @@ +Kernel driver tps53679 +====================== + +Supported chips: + + * Texas Instruments TPS53647 + + Prefix: 'tps53647' + + Addresses scanned: - + + Datasheet: http://www.ti.com/lit/gpn/tps53647 + + * Texas Instruments TPS53667 + + Prefix: 'tps53667' + + Addresses scanned: - + + Datasheet: http://www.ti.com/lit/gpn/TPS53667 + + * Texas Instruments TPS53679 + + Prefix: 'tps53679' + + Addresses scanned: - + + Datasheet: http://www.ti.com/lit/gpn/TPS53679 (short version) + + * Texas Instruments TPS53681 + + Prefix: 'tps53681' + + Addresses scanned: - + + Datasheet: http://www.ti.com/lit/gpn/TPS53681 + + * Texas Instruments TPS53688 + + Prefix: 'tps53688' + + Addresses scanned: - + + Datasheet: Available under NDA + + +Authors: + Vadim Pasternak + Guenter Roeck + + +Description +----------- + +Chips in this series are multi-phase step-down converters with one or two +output channels and up to 8 phases per channel. + + +Usage Notes +----------- + +This driver does not probe for PMBus devices. You will have to instantiate +devices explicitly. + +Example: the following commands will load the driver for an TPS53681 at address +0x60 on I2C bus #1:: + + # modprobe tps53679 + # echo tps53681 0x60 > /sys/bus/i2c/devices/i2c-1/new_device + + +Sysfs attributes +---------------- + +======================= ======================================================== +in1_label "vin" + +in1_input Measured input voltage. + +in1_lcrit Critical minimum input voltage + + TPS53679, TPS53681, TPS53688 only. + +in1_lcrit_alarm Input voltage critical low alarm. + + TPS53679, TPS53681, TPS53688 only. + +in1_crit Critical maximum input voltage. + +in1_crit_alarm Input voltage critical high alarm. + +in[N]_label "vout[1-2]" + + - TPS53647, TPS53667: N=2 + - TPS53679, TPS53588: N=2,3 + +in[N]_input Measured output voltage. + +in[N]_lcrit Critical minimum input voltage. + + TPS53679, TPS53681, TPS53688 only. + +in[N]_lcrit_alarm Critical minimum voltage alarm. + + TPS53679, TPS53681, TPS53688 only. + +in[N]_alarm Output voltage alarm. + + TPS53647, TPS53667 only. + +in[N]_crit Critical maximum output voltage. + + TPS53679, TPS53681, TPS53688 only. + +in[N]_crit_alarm Output voltage critical high alarm. + + TPS53679, TPS53681, TPS53688 only. + +temp[N]_input Measured temperature. + + - TPS53647, TPS53667: N=1 + - TPS53679, TPS53681, TPS53588: N=1,2 + +temp[N]_max Maximum temperature. + +temp[N]_crit Critical high temperature. + +temp[N]_max_alarm Temperature high alarm. + +temp[N]_crit_alarm Temperature critical high alarm. + +power1_label "pin". + +power1_input Measured input power. + +power[N]_label "pout[1-2]". + + - TPS53647, TPS53667: N=2 + - TPS53679, TPS53681, TPS53588: N=2,3 + +power[N]_input Measured output power. + +curr1_label "iin". + +curr1_input Measured input current. + +curr1_max Maximum input current. + +curr1_max_alarm Input current high alarm. + +curr1_crit Critical input current. + +curr1_crit_alarm Input current critical alarm. + +curr[N]_label "iout[1-2]" or "iout1.[0-5]". + + The first digit is the output channel, the second + digit is the phase within the channel. Per-phase + telemetry supported on TPS53681 only. + + - TPS53647, TPS53667: N=2 + - TPS53679, TPS53588: N=2,3 + - TPS53681: N=2-9 + +curr[N]_input Measured output current. + +curr[N]_max Maximum output current. + +curr[N]_crit Critical high output current. + +curr[N]_max_alarm Output current high alarm. + +curr[N]_crit_alarm Output current critical high alarm. + + Limit and alarm attributes are only available for + non-phase telemetry (iout1, iout2). + +======================= ========================================================