--- zzzz-none-000/linux-5.15.111/drivers/hwmon/ina2xx.c 2023-05-11 14:00:40.000000000 +0000 +++ puma7-atom-6670-761/linux-5.15.111/drivers/hwmon/ina2xx.c 2024-02-07 10:23:00.000000000 +0000 @@ -18,6 +18,14 @@ * Bi-directional Current/Power Monitor with I2C Interface * Datasheet: https://www.ti.com/product/ina230 * + * INA232: + * Bi-directional Current/Power Monitor with I2C Interface + * Datasheet: http://www.ti.com/product/ina232 + * + * INA234: + * Bi-directional Current/Power Monitor with I2C Interface + * Datasheet: http://www.ti.com/product/ina234 + * * Copyright (C) 2012 Lothar Felten * Thanks to Jan Volkering */ @@ -52,11 +60,13 @@ #define INA226_ALERT_LIMIT 0x07 #define INA226_DIE_ID 0xFF -/* register count */ -#define INA219_REGISTERS 6 -#define INA226_REGISTERS 8 - -#define INA2XX_MAX_REGISTERS 8 +/* INA23X register definitions */ +#define INA232_MANUFACTURER_ID 0x3E +#define INA234_DEVICE_ID 0x3F + +/* Highest register address being used by the driver */ +#define INA219_MAX_REGISTER INA2XX_CALIBRATION +#define INA226_MAX_REGISTER INA226_ALERT_LIMIT /* settings - depend on use case */ #define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */ @@ -99,14 +109,16 @@ .val_bits = 16, }; -enum ina2xx_ids { ina219, ina226 }; +enum ina2xx_ids { ina219, ina226, ina232, ina234, ina236 }; struct ina2xx_config { u16 config_default; int calibration_value; - int registers; + int max_register; int shunt_div; + int shunt_voltage_shift; int bus_voltage_shift; + int current_shift; int bus_voltage_lsb; /* uV */ int power_lsb_factor; }; @@ -119,6 +131,7 @@ long power_lsb_uW; struct mutex config_lock; struct regmap *regmap; + enum ina2xx_ids chip; const struct attribute_group *groups[INA2XX_MAX_ATTRIBUTE_GROUPS]; }; @@ -127,7 +140,7 @@ [ina219] = { .config_default = INA219_CONFIG_DEFAULT, .calibration_value = 4096, - .registers = INA219_REGISTERS, + .max_register = INA219_MAX_REGISTER, .shunt_div = 100, .bus_voltage_shift = 3, .bus_voltage_lsb = 4000, @@ -136,12 +149,40 @@ [ina226] = { .config_default = INA226_CONFIG_DEFAULT, .calibration_value = 2048, - .registers = INA226_REGISTERS, + .max_register = INA226_MAX_REGISTER, .shunt_div = 400, .bus_voltage_shift = 0, .bus_voltage_lsb = 1250, .power_lsb_factor = 25, }, + [ina232] = { + .config_default = INA226_CONFIG_DEFAULT, + .calibration_value = 2048, + .max_register = INA226_MAX_REGISTER, + .shunt_div = 400, + .bus_voltage_lsb = 1600, + .power_lsb_factor = 32, + }, + [ina234] = { + .config_default = INA226_CONFIG_DEFAULT, + .calibration_value = 2048, + .max_register = INA226_MAX_REGISTER, + .shunt_div = 25, + .shunt_voltage_shift = 4, + .bus_voltage_shift = 4, + .current_shift = 4, + .bus_voltage_lsb = 25600, + .power_lsb_factor = 32, + }, + [ina236] = { + .config_default = INA226_CONFIG_DEFAULT, + .calibration_value = 2048, + .max_register = INA226_MAX_REGISTER, + .shunt_div = 400, + .bus_voltage_shift = 0, + .bus_voltage_lsb = 1600, + .power_lsb_factor = 32, + }, }; /* @@ -270,7 +311,8 @@ switch (reg) { case INA2XX_SHUNT_VOLTAGE: /* signed register */ - val = DIV_ROUND_CLOSEST((s16)regval, data->config->shunt_div); + val = shift_right((s16)regval, data->config->shunt_voltage_shift); + val = DIV_ROUND_CLOSEST((s16)val, data->config->shunt_div); break; case INA2XX_BUS_VOLTAGE: val = (regval >> data->config->bus_voltage_shift) @@ -282,7 +324,8 @@ break; case INA2XX_CURRENT: /* signed register, result in mA */ - val = (s16)regval * data->current_lsb_uA; + val = shift_right((s16)regval, data->config->current_shift); + val = (s16)val * data->current_lsb_uA; val = DIV_ROUND_CLOSEST(val, 1000); break; case INA2XX_CALIBRATION: @@ -626,6 +669,8 @@ if (client->dev.of_node) chip = (enum ina2xx_ids)of_device_get_match_data(&client->dev); + else if (ACPI_HANDLE(dev)) + chip = (enum ina2xx_ids)acpi_device_get_match_data(dev); else chip = i2c_match_id(ina2xx_id, client)->driver_data; @@ -635,9 +680,10 @@ /* set the device type */ data->config = &ina2xx_config[chip]; + data->chip = chip; mutex_init(&data->config_lock); - if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) { + if (device_property_read_u32(dev, "shunt-resistor", &val) < 0) { struct ina2xx_platform_data *pdata = dev_get_platdata(dev); if (pdata) @@ -648,7 +694,7 @@ ina2xx_set_shunt(data, val); - ina2xx_regmap_config.max_register = data->config->registers; + ina2xx_regmap_config.max_register = data->config->max_register; data->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config); if (IS_ERR(data->regmap)) { @@ -663,7 +709,7 @@ } data->groups[group++] = &ina2xx_group; - if (chip == ina226) + if (chip == ina226 || chip == ina232 ||chip == ina234 || chip == ina236) data->groups[group++] = &ina226_group; hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, @@ -683,6 +729,9 @@ { "ina226", ina226 }, { "ina230", ina226 }, { "ina231", ina226 }, + { "ina232", ina232 }, + { "ina234", ina234 }, + { "ina236", ina236 }, { } }; MODULE_DEVICE_TABLE(i2c, ina2xx_id); @@ -708,14 +757,33 @@ .compatible = "ti,ina231", .data = (void *)ina226 }, + { + .compatible = "ti,ina232", + .data = (void *)ina232 + }, + { + .compatible = "ti,ina234", + .data = (void *)ina234 + }, + { + .compatible = "ti,ina236", + .data = (void *)ina236 + }, { }, }; MODULE_DEVICE_TABLE(of, ina2xx_of_match); +static const struct acpi_device_id __maybe_unused ina2xx_acpi_id[] = { + {"TXNW0232", ina232}, // FIXME: Not an official ID + {}, +}; +MODULE_DEVICE_TABLE(acpi, ina2xx_acpi_id); + static struct i2c_driver ina2xx_driver = { .driver = { .name = "ina2xx", .of_match_table = of_match_ptr(ina2xx_of_match), + .acpi_match_table = ACPI_PTR(ina2xx_acpi_id), }, .probe_new = ina2xx_probe, .id_table = ina2xx_id,