Lines Matching +full:state +full:- +full:labels
1 // SPDX-License-Identifier: GPL-2.0+
3 * IIO driver for PAC1934 Multi-Channel DC Power/Energy Monitor
5 * Copyright (C) 2017-2024 Microchip Technology Inc. and its subsidiaries
12 …oads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/PAC1931-Family-Data-Sheet-DS20005850E.…
46 * (2^31 - 1) * 10^8 + 99999999
51 * -(2^31) * 10^8 - 99999999
53 #define PAC_193X_MIN_POWER_ACC -214748364899999999LL
118 * relative offsets when using multi-byte reads/writes even though these
147 /* Scale constant = (10^3 * 3.2 * 10^9 / 2^28) for mili Watt-second */
187 * 033771E0-1705-47B4-9535-D1BBE14D9A09,
190 #define PAC1934_DSM_UUID "033771E0-1705-47B4-9535-D1BBE14D9A09"
221 * struct pac1934_features - features of a pac1934 instance
257 * struct reg_data - data from the registers
283 * struct pac1934_chip_info - information about the chip
284 * @client: the i2c-client attached to the device
285 * @lock: synchronize access to driver's state members
296 * @labels: table with channels labels
302 struct mutex lock; /* synchronize access to driver's state members */
313 char *labels[PAC1934_MAX_NUM_CHANNELS]; member
439 /* Low-level I2c functions used to transfer up to 76 bytes at once */
446 .addr = client->addr, in pac1934_i2c_read()
451 .addr = client->addr, in pac1934_i2c_read()
458 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in pac1934_i2c_read()
475 return -EINVAL; in pac1934_get_samp_rate_idx()
486 return sysfs_emit(buf, "%u\n", info->shunts[this_attr->address]); in pac1934_shunt_value_show()
500 return -EINVAL; in pac1934_shunt_value_store()
503 scoped_guard(mutex, &info->lock) in pac1934_shunt_value_store()
504 info->shunts[this_attr->address] = sh_val; in pac1934_shunt_value_store()
521 return -EINVAL; in pac1934_read_avail()
528 struct i2c_client *client = info->client; in pac1934_send_refresh()
533 if (info->chip_revision == 2 || info->chip_revision == 3) { in pac1934_send_refresh()
541 FIELD_PREP(PAC1934_NEG_PWR_CH1_BIDI_MASK, info->bi_dir[0]) | in pac1934_send_refresh()
542 FIELD_PREP(PAC1934_NEG_PWR_CH2_BIDI_MASK, info->bi_dir[1]) | in pac1934_send_refresh()
543 FIELD_PREP(PAC1934_NEG_PWR_CH3_BIDI_MASK, info->bi_dir[2]) | in pac1934_send_refresh()
544 FIELD_PREP(PAC1934_NEG_PWR_CH4_BIDI_MASK, info->bi_dir[3]) | in pac1934_send_refresh()
545 FIELD_PREP(PAC1934_NEG_PWR_CH1_BIDV_MASK, info->bi_dir[0]) | in pac1934_send_refresh()
546 FIELD_PREP(PAC1934_NEG_PWR_CH2_BIDV_MASK, info->bi_dir[1]) | in pac1934_send_refresh()
547 FIELD_PREP(PAC1934_NEG_PWR_CH3_BIDV_MASK, info->bi_dir[2]) | in pac1934_send_refresh()
548 FIELD_PREP(PAC1934_NEG_PWR_CH4_BIDV_MASK, info->bi_dir[3]); in pac1934_send_refresh()
560 dev_err(&client->dev, "%s - cannot send 0x%02X\n", in pac1934_send_refresh()
567 * chip rev 2 and 3 bug workaround - write again the same in pac1934_send_refresh()
578 info->tstamp = jiffies; in pac1934_send_refresh()
590 struct i2c_client *client = info->client; in pac1934_reg_snapshot()
599 guard(mutex)(&info->lock); in pac1934_reg_snapshot()
604 dev_err(&client->dev, in pac1934_reg_snapshot()
605 "%s - cannot send refresh\n", in pac1934_reg_snapshot()
613 (u8 *)info->chip_reg_data.ctrl_regs); in pac1934_reg_snapshot()
615 dev_err(&client->dev, in pac1934_reg_snapshot()
616 "%s - cannot read ctrl/status registers\n", in pac1934_reg_snapshot()
621 reg_data = &info->chip_reg_data; in pac1934_reg_snapshot()
625 (u8 *)reg_data->meas_regs, PAC1934_MEAS_REG_LEN); in pac1934_reg_snapshot()
627 dev_err(&client->dev, in pac1934_reg_snapshot()
628 "%s - cannot read ACC_COUNT register: %d:%d\n", in pac1934_reg_snapshot()
634 samp_rate = samp_rate_map_tbl[((reg_data->ctrl_regs[PAC1934_CTRL_LAT_REG_OFF]) >> 6)]; in pac1934_reg_snapshot()
637 ctrl_regs_tmp = reg_data->ctrl_regs[PAC1934_CHANNEL_DIS_LAT_REG_OFF]; in pac1934_reg_snapshot()
638 offset_reg_data_p = ®_data->meas_regs[PAC1934_ACC_REG_LEN]; in pac1934_reg_snapshot()
641 for (cnt = 0; cnt < info->phys_channels; cnt++) { in pac1934_reg_snapshot()
647 if (info->enable_energy[cnt]) { in pac1934_reg_snapshot()
648 curr_energy = info->chip_reg_data.energy_sec_acc[cnt]; in pac1934_reg_snapshot()
652 if (info->bi_dir[cnt]) in pac1934_reg_snapshot()
653 reg_data->vpower_acc[cnt] = sign_extend64(tmp_energy, 47); in pac1934_reg_snapshot()
655 reg_data->vpower_acc[cnt] = tmp_energy; in pac1934_reg_snapshot()
662 inc = (reg_data->vpower_acc[cnt] >> samp_shift); in pac1934_reg_snapshot()
669 reg_data->energy_sec_acc[cnt] = curr_energy; in pac1934_reg_snapshot()
676 for (cnt = 0; cnt < info->phys_channels; cnt++) { in pac1934_reg_snapshot()
682 if (info->bi_dir[cnt]) in pac1934_reg_snapshot()
683 reg_data->vbus[cnt] = sign_extend32((u32)(tmp_value), 15); in pac1934_reg_snapshot()
685 reg_data->vbus[cnt] = tmp_value; in pac1934_reg_snapshot()
691 for (cnt = 0; cnt < info->phys_channels; cnt++) { in pac1934_reg_snapshot()
697 if (info->bi_dir[cnt]) in pac1934_reg_snapshot()
698 reg_data->vsense[cnt] = sign_extend32((u32)(tmp_value), 15); in pac1934_reg_snapshot()
700 reg_data->vsense[cnt] = tmp_value; in pac1934_reg_snapshot()
706 for (cnt = 0; cnt < info->phys_channels; cnt++) { in pac1934_reg_snapshot()
712 if (info->bi_dir[cnt]) in pac1934_reg_snapshot()
713 reg_data->vbus_avg[cnt] = sign_extend32((u32)(tmp_value), 15); in pac1934_reg_snapshot()
715 reg_data->vbus_avg[cnt] = tmp_value; in pac1934_reg_snapshot()
721 for (cnt = 0; cnt < info->phys_channels; cnt++) { in pac1934_reg_snapshot()
727 if (info->bi_dir[cnt]) in pac1934_reg_snapshot()
728 reg_data->vsense_avg[cnt] = sign_extend32((u32)(tmp_value), 15); in pac1934_reg_snapshot()
730 reg_data->vsense_avg[cnt] = tmp_value; in pac1934_reg_snapshot()
736 for (cnt = 0; cnt < info->phys_channels; cnt++) { in pac1934_reg_snapshot()
742 if (info->bi_dir[cnt]) in pac1934_reg_snapshot()
743 reg_data->vpower[cnt] = sign_extend32(tmp, 27); in pac1934_reg_snapshot()
745 reg_data->vpower[cnt] = tmp; in pac1934_reg_snapshot()
760 * re-read the chip, otherwise the cached info is just fine in pac1934_retrieve_data()
762 if (time_after(jiffies, info->tstamp + msecs_to_jiffies(PAC1934_MIN_POLLING_TIME_MS))) { in pac1934_retrieve_data()
767 * Re-schedule the work for the read registers on timeout in pac1934_retrieve_data()
770 mod_delayed_work(system_wq, &info->work_chip_rfsh, in pac1934_retrieve_data()
783 int ret, channel = chan->channel - 1; in pac1934_read_raw()
792 channel = channel - PAC1934_MAX_NUM_CHANNELS; in pac1934_read_raw()
800 switch (chan->type) { in pac1934_read_raw()
802 *val = info->chip_reg_data.vbus[channel]; in pac1934_read_raw()
805 *val = info->chip_reg_data.vsense[channel]; in pac1934_read_raw()
808 *val = info->chip_reg_data.vpower[channel]; in pac1934_read_raw()
811 curr_energy = info->chip_reg_data.energy_sec_acc[channel]; in pac1934_read_raw()
816 return -EINVAL; in pac1934_read_raw()
819 switch (chan->type) { in pac1934_read_raw()
821 *val = info->chip_reg_data.vbus_avg[channel]; in pac1934_read_raw()
824 *val = info->chip_reg_data.vsense_avg[channel]; in pac1934_read_raw()
827 return -EINVAL; in pac1934_read_raw()
830 switch (chan->address) { in pac1934_read_raw()
831 /* Voltages - scale for millivolts */ in pac1934_read_raw()
841 if (chan->scan_type.sign == 'u') in pac1934_read_raw()
847 * Currents - scale for mA - depends on the in pac1934_read_raw()
860 if (chan->scan_type.sign == 'u') in pac1934_read_raw()
861 *val2 = info->shunts[channel]; in pac1934_read_raw()
863 *val2 = info->shunts[channel] >> 1; in pac1934_read_raw()
866 * Power - uW - it will use the combined scale in pac1934_read_raw()
875 if (chan->scan_type.sign == 'u') in pac1934_read_raw()
876 *val2 = info->shunts[channel]; in pac1934_read_raw()
878 *val2 = info->shunts[channel] >> 1; in pac1934_read_raw()
886 * the scale for energy (miliWatt-second or miliJoule) in pac1934_read_raw()
890 if (chan->scan_type.sign == 'u') in pac1934_read_raw()
891 *val2 = info->shunts[channel]; in pac1934_read_raw()
893 *val2 = info->shunts[channel] >> 1; in pac1934_read_raw()
896 return -EINVAL; in pac1934_read_raw()
899 *val = info->sample_rate_value; in pac1934_read_raw()
902 *val = info->enable_energy[channel]; in pac1934_read_raw()
905 return -EINVAL; in pac1934_read_raw()
913 struct i2c_client *client = info->client; in pac1934_write_raw()
914 int ret = -EINVAL; in pac1934_write_raw()
925 scoped_guard(mutex, &info->lock) { in pac1934_write_raw()
929 dev_err(&client->dev, in pac1934_write_raw()
930 "%s - can't update sample rate\n", in pac1934_write_raw()
936 old_samp_rate = info->sample_rate_value; in pac1934_write_raw()
937 info->sample_rate_value = val; in pac1934_write_raw()
940 * now, force a snapshot with refresh - call retrieve in pac1934_write_raw()
945 info->tstamp -= msecs_to_jiffies(PAC1934_MIN_POLLING_TIME_MS); in pac1934_write_raw()
948 dev_err(&client->dev, in pac1934_write_raw()
949 "%s - cannot snapshot ctrl and measurement regs\n", in pac1934_write_raw()
956 scoped_guard(mutex, &info->lock) { in pac1934_write_raw()
957 info->enable_energy[chan->channel - 1] = val ? true : false; in pac1934_write_raw()
959 info->chip_reg_data.energy_sec_acc[chan->channel - 1] = 0; in pac1934_write_raw()
964 return -EINVAL; in pac1934_write_raw()
973 switch (chan->address) { in pac1934_read_label()
979 info->labels[chan->scan_index], in pac1934_read_label()
980 chan->scan_index + 1); in pac1934_read_label()
986 info->labels[chan->scan_index], in pac1934_read_label()
987 chan->scan_index + 1); in pac1934_read_label()
993 info->labels[chan->scan_index], in pac1934_read_label()
994 chan->scan_index + 1); in pac1934_read_label()
1000 info->labels[chan->scan_index], in pac1934_read_label()
1001 chan->scan_index + 1); in pac1934_read_label()
1007 info->labels[chan->scan_index], in pac1934_read_label()
1008 chan->scan_index + 1); in pac1934_read_label()
1014 info->labels[chan->scan_index], in pac1934_read_label()
1015 chan->scan_index + 1); in pac1934_read_label()
1024 struct device *dev = &info->client->dev; in pac1934_work_periodic_rfsh()
1026 dev_dbg(dev, "%s - Periodic refresh\n", __func__); in pac1934_work_periodic_rfsh()
1032 schedule_delayed_work(&info->work_chip_rfsh, in pac1934_work_periodic_rfsh()
1039 struct i2c_client *client = info->client; in pac1934_read_revision()
1045 dev_err(&client->dev, "cannot read revision\n"); in pac1934_read_revision()
1055 struct device *dev = &info->client->dev; in pac1934_chip_identify()
1062 info->chip_variant = rev_info[PAC1934_PID_IDX]; in pac1934_chip_identify()
1063 info->chip_revision = rev_info[PAC1934_RID_IDX]; in pac1934_chip_identify()
1065 dev_dbg(dev, "Chip variant: 0x%02X\n", info->chip_variant); in pac1934_chip_identify()
1066 dev_dbg(dev, "Chip revision: 0x%02X\n", info->chip_revision); in pac1934_chip_identify()
1068 switch (info->chip_variant) { in pac1934_chip_identify()
1078 return -EINVAL; in pac1934_chip_identify()
1084 …plicationNotes/ApplicationNotes/PAC1934-Integration-Notes-for-Microsoft-Windows-10-and-Windows-11-…
1091 struct device *dev = &client->dev; in pac1934_acpi_parse_channel_config()
1102 return -EINVAL; in pac1934_acpi_parse_channel_config()
1104 for (i = 0; i < rez->package.count; i += 2) { in pac1934_acpi_parse_channel_config()
1106 info->labels[idx] = in pac1934_acpi_parse_channel_config()
1107 devm_kmemdup(dev, rez->package.elements[i].string.pointer, in pac1934_acpi_parse_channel_config()
1108 (size_t)rez->package.elements[i].string.length + 1, in pac1934_acpi_parse_channel_config()
1110 info->labels[idx][rez->package.elements[i].string.length] = '\0'; in pac1934_acpi_parse_channel_config()
1111 info->shunts[idx] = rez->package.elements[i + 1].integer.value * 1000; in pac1934_acpi_parse_channel_config()
1112 info->active_channels[idx] = (info->shunts[idx] != 0); in pac1934_acpi_parse_channel_config()
1124 info->sample_rate_value = PAC1934_DEFAULT_CHIP_SAMP_SPEED_HZ; in pac1934_acpi_parse_channel_config()
1128 for (i = 0; i < rez->package.count; i++) { in pac1934_acpi_parse_channel_config()
1130 info->shunts[idx] = rez->package.elements[i].integer.value; in pac1934_acpi_parse_channel_config()
1131 info->active_channels[idx] = (info->shunts[idx] != 0); in pac1934_acpi_parse_channel_config()
1138 return -EINVAL; in pac1934_acpi_parse_channel_config()
1140 bi_dir_mask = rez->package.elements[0].integer.value; in pac1934_acpi_parse_channel_config()
1141 info->bi_dir[0] = ((bi_dir_mask & (1 << 3)) | (bi_dir_mask & (1 << 7))) != 0; in pac1934_acpi_parse_channel_config()
1142 info->bi_dir[1] = ((bi_dir_mask & (1 << 2)) | (bi_dir_mask & (1 << 6))) != 0; in pac1934_acpi_parse_channel_config()
1143 info->bi_dir[2] = ((bi_dir_mask & (1 << 1)) | (bi_dir_mask & (1 << 5))) != 0; in pac1934_acpi_parse_channel_config()
1144 info->bi_dir[3] = ((bi_dir_mask & (1 << 0)) | (bi_dir_mask & (1 << 4))) != 0; in pac1934_acpi_parse_channel_config()
1150 return -EINVAL; in pac1934_acpi_parse_channel_config()
1152 info->sample_rate_value = rez->package.elements[0].integer.value; in pac1934_acpi_parse_channel_config()
1162 struct device *dev = &client->dev; in pac1934_fw_parse_channel_config()
1166 info->sample_rate_value = 1024; in pac1934_fw_parse_channel_config()
1176 idx--; in pac1934_fw_parse_channel_config()
1178 if (current_channel >= (info->phys_channels + 1) || in pac1934_fw_parse_channel_config()
1179 idx >= info->phys_channels || idx < 0) in pac1934_fw_parse_channel_config()
1180 return dev_err_probe(dev, -EINVAL, in pac1934_fw_parse_channel_config()
1185 info->active_channels[idx] = true; in pac1934_fw_parse_channel_config()
1187 ret = fwnode_property_read_u32(node, "shunt-resistor-micro-ohms", in pac1934_fw_parse_channel_config()
1188 &info->shunts[idx]); in pac1934_fw_parse_channel_config()
1191 "%s: invalid shunt-resistor value: %d\n", in pac1934_fw_parse_channel_config()
1192 fwnode_get_name(node), info->shunts[idx]); in pac1934_fw_parse_channel_config()
1196 (const char **)&info->labels[idx]); in pac1934_fw_parse_channel_config()
1199 "%s: invalid rail-name value\n", in pac1934_fw_parse_channel_config()
1203 info->bi_dir[idx] = fwnode_property_read_bool(node, "bipolar"); in pac1934_fw_parse_channel_config()
1219 struct i2c_client *client = info->client; in pac1934_chip_configure()
1223 info->chip_reg_data.num_enabled_channels = 0; in pac1934_chip_configure()
1224 for (cnt = 0; cnt < info->phys_channels; cnt++) { in pac1934_chip_configure()
1225 if (info->active_channels[cnt]) in pac1934_chip_configure()
1226 info->chip_reg_data.num_enabled_channels++; in pac1934_chip_configure()
1239 dev_err_probe(&client->dev, ret, in pac1934_chip_configure()
1240 "%s - cannot read regs from 0x%02X\n", in pac1934_chip_configure()
1247 FIELD_PREP(PAC1934_CHAN_DIS_CH1_OFF_MASK, info->active_channels[0] ? 0 : 1) | in pac1934_chip_configure()
1248 FIELD_PREP(PAC1934_CHAN_DIS_CH2_OFF_MASK, info->active_channels[1] ? 0 : 1) | in pac1934_chip_configure()
1249 FIELD_PREP(PAC1934_CHAN_DIS_CH3_OFF_MASK, info->active_channels[2] ? 0 : 1) | in pac1934_chip_configure()
1250 FIELD_PREP(PAC1934_CHAN_DIS_CH4_OFF_MASK, info->active_channels[3] ? 0 : 1) | in pac1934_chip_configure()
1256 FIELD_PREP(PAC1934_NEG_PWR_CH1_BIDI_MASK, info->bi_dir[0]) | in pac1934_chip_configure()
1257 FIELD_PREP(PAC1934_NEG_PWR_CH2_BIDI_MASK, info->bi_dir[1]) | in pac1934_chip_configure()
1258 FIELD_PREP(PAC1934_NEG_PWR_CH3_BIDI_MASK, info->bi_dir[2]) | in pac1934_chip_configure()
1259 FIELD_PREP(PAC1934_NEG_PWR_CH4_BIDI_MASK, info->bi_dir[3]) | in pac1934_chip_configure()
1260 FIELD_PREP(PAC1934_NEG_PWR_CH1_BIDV_MASK, info->bi_dir[0]) | in pac1934_chip_configure()
1261 FIELD_PREP(PAC1934_NEG_PWR_CH2_BIDV_MASK, info->bi_dir[1]) | in pac1934_chip_configure()
1262 FIELD_PREP(PAC1934_NEG_PWR_CH3_BIDV_MASK, info->bi_dir[2]) | in pac1934_chip_configure()
1263 FIELD_PREP(PAC1934_NEG_PWR_CH4_BIDV_MASK, info->bi_dir[3]); in pac1934_chip_configure()
1286 dev_err(&client->dev, in pac1934_chip_configure()
1287 "%s - cannot send 0x%02X\n", in pac1934_chip_configure()
1306 INIT_DELAYED_WORK(&info->work_chip_rfsh, pac1934_work_periodic_rfsh); in pac1934_chip_configure()
1308 schedule_delayed_work(&info->work_chip_rfsh, in pac1934_chip_configure()
1311 return devm_add_action_or_reset(&client->dev, pac1934_cancel_delayed_work, in pac1934_chip_configure()
1312 &info->work_chip_rfsh); in pac1934_chip_configure()
1320 struct device *dev = &info->client->dev; in pac1934_prep_iio_channels()
1325 for (cnt = 0; cnt < info->phys_channels; cnt++) { in pac1934_prep_iio_channels()
1326 if (!info->active_channels[cnt]) in pac1934_prep_iio_channels()
1338 return -EINVAL; in pac1934_prep_iio_channels()
1343 for (cnt = 0; cnt < info->phys_channels; cnt++) { in pac1934_prep_iio_channels()
1344 if (!info->active_channels[cnt]) in pac1934_prep_iio_channels()
1363 * In order to be able to use labels for PAC1934_CH_VOLTAGE, and in pac1934_prep_iio_channels()
1377 * whole chip rail(channel) is bi-directional in pac1934_prep_iio_channels()
1379 if (info->bi_dir[cnt]) { in pac1934_prep_iio_channels()
1400 indio_dev->num_channels = attribute_count; in pac1934_prep_iio_channels()
1401 indio_dev->channels = (const struct iio_chan_spec *)dyn_ch_struct; in pac1934_prep_iio_channels()
1421 struct device *dev = &info->client->dev; in pac1934_prep_custom_attributes()
1423 for (i = 0 ; i < info->phys_channels; i++) in pac1934_prep_custom_attributes()
1424 if (info->active_channels[i]) in pac1934_prep_custom_attributes()
1429 return -ENOMEM; in pac1934_prep_custom_attributes()
1437 return -ENOMEM; in pac1934_prep_custom_attributes()
1440 if (info->active_channels[0]) in pac1934_prep_custom_attributes()
1443 if (info->active_channels[1]) in pac1934_prep_custom_attributes()
1446 if (info->active_channels[2]) in pac1934_prep_custom_attributes()
1449 if (info->active_channels[3]) in pac1934_prep_custom_attributes()
1452 pac1934_group->attrs = pac1934_custom_attr; in pac1934_prep_custom_attributes()
1453 info->iio_info.attrs = pac1934_group; in pac1934_prep_custom_attributes()
1478 struct device *dev = &client->dev; in pac1934_probe()
1482 return -ENOMEM; in pac1934_probe()
1486 info->client = client; in pac1934_probe()
1490 info->enable_energy[cnt] = true; in pac1934_probe()
1501 return -EINVAL; in pac1934_probe()
1503 info->phys_channels = chip->phys_channels; in pac1934_probe()
1504 indio_dev->name = chip->name; in pac1934_probe()
1506 info->phys_channels = pac1934_chip_config[ret].phys_channels; in pac1934_probe()
1507 indio_dev->name = pac1934_chip_config[ret].name; in pac1934_probe()
1510 if (acpi_match_device(dev->driver->acpi_match_table, dev)) in pac1934_probe()
1523 mutex_init(&info->lock); in pac1934_probe()
1525 &info->lock); in pac1934_probe()
1543 info->iio_info = pac1934_info; in pac1934_probe()
1544 indio_dev->info = &info->iio_info; in pac1934_probe()
1545 indio_dev->modes = INDIO_DIRECT_MODE; in pac1934_probe()
1601 …plicationNotes/ApplicationNotes/PAC1934-Integration-Notes-for-Microsoft-Windows-10-and-Windows-11-…
1624 MODULE_DESCRIPTION("IIO driver for PAC1934 Multi-Channel DC Power/Energy Monitor");