Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (pmbus/ucd9000) Add support for UCD90320 Power Sequencer

Add support for the UCD90320 chip and its expanded set of GPIO pins.

Signed-off-by: Jim Wright <wrightj@linux.vnet.ibm.com>
Link: https://lore.kernel.org/r/20191205232411.21492-3-wrightj@linux.vnet.ibm.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Jim Wright and committed by
Guenter Roeck
a470f11c 8a36e38d

+40 -17
+10 -2
Documentation/hwmon/ucd9000.rst
··· 3 3 4 4 Supported chips: 5 5 6 - * TI UCD90120, UCD90124, UCD90160, UCD9090, and UCD90910 6 + * TI UCD90120, UCD90124, UCD90160, UCD90320, UCD9090, and UCD90910 7 7 8 - Prefixes: 'ucd90120', 'ucd90124', 'ucd90160', 'ucd9090', 'ucd90910' 8 + Prefixes: 'ucd90120', 'ucd90124', 'ucd90160', 'ucd90320', 'ucd9090', 9 + 'ucd90910' 9 10 10 11 Addresses scanned: - 11 12 ··· 15 14 - http://focus.ti.com/lit/ds/symlink/ucd90120.pdf 16 15 - http://focus.ti.com/lit/ds/symlink/ucd90124.pdf 17 16 - http://focus.ti.com/lit/ds/symlink/ucd90160.pdf 17 + - http://focus.ti.com/lit/ds/symlink/ucd90320.pdf 18 18 - http://focus.ti.com/lit/ds/symlink/ucd9090.pdf 19 19 - http://focus.ti.com/lit/ds/symlink/ucd90910.pdf 20 20 ··· 46 44 power-on reset signals, external interrupts, cascading, or other system 47 45 functions. Twelve of these pins offer PWM functionality. Using these pins, the 48 46 UCD90160 offers support for margining, and general-purpose PWM functions. 47 + 48 + The UCD90320 is a 32-rail PMBus/I2C addressable power-supply sequencer and 49 + monitor. The 24 integrated ADC channels (AMONx) monitor the power supply 50 + voltage, current, and temperature. Of the 84 GPIO pins, 8 can be used as 51 + digital monitors (DMONx), 32 to enable the power supply (ENx), 24 for margining 52 + (MARx), 16 for logical GPO, and 32 GPIs for cascading, and system function. 49 53 50 54 The UCD9090 is a 10-rail PMBus/I2C addressable power-supply sequencer and 51 55 monitor. The device integrates a 12-bit ADC for monitoring up to 10 power-supply
+3 -3
drivers/hwmon/pmbus/Kconfig
··· 209 209 be called tps53679. 210 210 211 211 config SENSORS_UCD9000 212 - tristate "TI UCD90120, UCD90124, UCD90160, UCD9090, UCD90910" 212 + tristate "TI UCD90120, UCD90124, UCD90160, UCD90320, UCD9090, UCD90910" 213 213 help 214 214 If you say yes here you get hardware monitoring support for TI 215 - UCD90120, UCD90124, UCD90160, UCD9090, UCD90910, Sequencer and System 216 - Health Controllers. 215 + UCD90120, UCD90124, UCD90160, UCD90320, UCD9090, UCD90910, Sequencer 216 + and System Health Controllers. 217 217 218 218 This driver can also be built as a module. If so, the module will 219 219 be called ucd9000.
+27 -12
drivers/hwmon/pmbus/ucd9000.c
··· 18 18 #include <linux/gpio/driver.h> 19 19 #include "pmbus.h" 20 20 21 - enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 }; 21 + enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd90320, ucd9090, 22 + ucd90910 }; 22 23 23 24 #define UCD9000_MONITOR_CONFIG 0xd5 24 25 #define UCD9000_NUM_PAGES 0xd6 ··· 39 38 #define UCD9000_GPIO_OUTPUT 1 40 39 41 40 #define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07) 42 - #define UCD9000_MON_PAGE(x) ((x) & 0x0f) 41 + #define UCD9000_MON_PAGE(x) ((x) & 0x1f) 43 42 44 43 #define UCD9000_MON_VOLTAGE 1 45 44 #define UCD9000_MON_TEMPERATURE 2 ··· 51 50 #define UCD9000_GPIO_NAME_LEN 16 52 51 #define UCD9090_NUM_GPIOS 23 53 52 #define UCD901XX_NUM_GPIOS 26 53 + #define UCD90320_NUM_GPIOS 84 54 54 #define UCD90910_NUM_GPIOS 26 55 55 56 56 #define UCD9000_DEBUGFS_NAME_LEN 24 57 57 #define UCD9000_GPI_COUNT 8 58 + #define UCD90320_GPI_COUNT 32 58 59 59 60 struct ucd9000_data { 60 61 u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX]; ··· 134 131 {"ucd90120", ucd90120}, 135 132 {"ucd90124", ucd90124}, 136 133 {"ucd90160", ucd90160}, 134 + {"ucd90320", ucd90320}, 137 135 {"ucd9090", ucd9090}, 138 136 {"ucd90910", ucd90910}, 139 137 {} ··· 157 153 { 158 154 .compatible = "ti,ucd90160", 159 155 .data = (void *)ucd90160 156 + }, 157 + { 158 + .compatible = "ti,ucd90320", 159 + .data = (void *)ucd90320 160 160 }, 161 161 { 162 162 .compatible = "ti,ucd9090", ··· 330 322 case ucd90160: 331 323 data->gpio.ngpio = UCD901XX_NUM_GPIOS; 332 324 break; 325 + case ucd90320: 326 + data->gpio.ngpio = UCD90320_NUM_GPIOS; 327 + break; 333 328 case ucd90910: 334 329 data->gpio.ngpio = UCD90910_NUM_GPIOS; 335 330 break; ··· 383 372 struct ucd9000_debugfs_entry *entry = data; 384 373 struct i2c_client *client = entry->client; 385 374 u8 buffer[I2C_SMBUS_BLOCK_MAX]; 386 - int ret; 375 + int ret, i; 387 376 388 377 ret = ucd9000_get_mfr_status(client, buffer); 389 378 if (ret < 0) 390 379 return ret; 391 380 392 381 /* 393 - * Attribute only created for devices with gpi fault bits at bits 394 - * 16-23, which is the second byte of the response. 382 + * GPI fault bits are in sets of 8, two bytes from end of response. 395 383 */ 396 - *val = !!(buffer[1] & BIT(entry->index)); 384 + i = ret - 3 - entry->index / 8; 385 + if (i >= 0) 386 + *val = !!(buffer[i] & BIT(entry->index % 8)); 397 387 398 388 return 0; 399 389 } ··· 434 422 { 435 423 struct dentry *debugfs; 436 424 struct ucd9000_debugfs_entry *entries; 437 - int i; 425 + int i, gpi_count; 438 426 char name[UCD9000_DEBUGFS_NAME_LEN]; 439 427 440 428 debugfs = pmbus_get_debugfs_dir(client); ··· 447 435 448 436 /* 449 437 * Of the chips this driver supports, only the UCD9090, UCD90160, 450 - * and UCD90910 report GPI faults in their MFR_STATUS register, so only 451 - * create the GPI fault debugfs attributes for those chips. 438 + * UCD90320, and UCD90910 report GPI faults in their MFR_STATUS 439 + * register, so only create the GPI fault debugfs attributes for those 440 + * chips. 452 441 */ 453 442 if (mid->driver_data == ucd9090 || mid->driver_data == ucd90160 || 454 - mid->driver_data == ucd90910) { 443 + mid->driver_data == ucd90320 || mid->driver_data == ucd90910) { 444 + gpi_count = mid->driver_data == ucd90320 ? UCD90320_GPI_COUNT 445 + : UCD9000_GPI_COUNT; 455 446 entries = devm_kcalloc(&client->dev, 456 - UCD9000_GPI_COUNT, sizeof(*entries), 447 + gpi_count, sizeof(*entries), 457 448 GFP_KERNEL); 458 449 if (!entries) 459 450 return -ENOMEM; 460 451 461 - for (i = 0; i < UCD9000_GPI_COUNT; i++) { 452 + for (i = 0; i < gpi_count; i++) { 462 453 entries[i].client = client; 463 454 entries[i].index = i; 464 455 scnprintf(name, UCD9000_DEBUGFS_NAME_LEN,