+ (void)get_config;
+ (void)get_init_state;
+ (void)get_curr_meas;
+
+ switch (devc->model->model_type) {
+ case MODEL_DPS:
+ /*
+ * Transfer a chunk of registers in a single call. It's
+ * unfortunate that the model dependency and the sparse
+ * register map force us to open code addresses, sizes,
+ * and the sequence of the registers and how to interpret
+ * their bit fields. But then this is not too unusual for
+ * a hardware specific device driver ...
+ */
+ g_mutex_lock(&devc->rw_mutex);
+ ret = rdtech_dps_read_holding_registers(modbus,
+ REG_DPS_USET, 10, registers);
+ g_mutex_unlock(&devc->rw_mutex);
+ if (ret != SR_OK)
+ return ret;
+
+ /* Interpret the registers' values. */
+ rdptr = (const void *)registers;
+ uset_raw = read_u16be_inc(&rdptr);
+ volt_target = uset_raw / devc->voltage_multiplier;
+ iset_raw = read_u16be_inc(&rdptr);
+ curr_limit = iset_raw / devc->current_multiplier;
+ uout_raw = read_u16be_inc(&rdptr);
+ curr_voltage = uout_raw / devc->voltage_multiplier;
+ iout_raw = read_u16be_inc(&rdptr);
+ curr_current = iout_raw / devc->current_multiplier;
+ power_raw = read_u16be_inc(&rdptr);
+ curr_power = power_raw / 100.0f;
+ (void)read_u16be_inc(&rdptr); /* UIN */
+ reg_val = read_u16be_inc(&rdptr); /* LOCK */
+ is_lock = reg_val != 0;
+ reg_val = read_u16be_inc(&rdptr); /* PROTECT */
+ uses_ovp = reg_val == STATE_OVP;
+ uses_ocp = reg_val == STATE_OCP;
+ reg_state = read_u16be_inc(&rdptr); /* CV_CC */
+ is_reg_cc = reg_state == MODE_CC;
+ out_state = read_u16be_inc(&rdptr); /* ENABLE */
+ is_out_enabled = out_state != 0;
+
+ /* Transfer another chunk of registers in a single call. */
+ g_mutex_lock(&devc->rw_mutex);
+ ret = rdtech_dps_read_holding_registers(modbus,
+ PRE_DPS_OVPSET, 2, registers);
+ g_mutex_unlock(&devc->rw_mutex);
+ if (ret != SR_OK)
+ return ret;
+
+ /* Interpret the second registers chunk's values. */
+ rdptr = (const void *)registers;
+ ovpset_raw = read_u16be_inc(&rdptr); /* PRE OVPSET */
+ ovp_threshold = ovpset_raw * devc->voltage_multiplier;
+ ocpset_raw = read_u16be_inc(&rdptr); /* PRE OCPSET */
+ ocp_threshold = ocpset_raw * devc->current_multiplier;
+
+ break;
+
+ case MODEL_RD:
+ /* Retrieve a set of adjacent registers. */
+ g_mutex_lock(&devc->rw_mutex);
+ ret = rdtech_dps_read_holding_registers(modbus,
+ REG_RD_VOLT_TGT, 11, registers);
+ g_mutex_unlock(&devc->rw_mutex);
+ if (ret != SR_OK)
+ return ret;
+
+ /* Interpret the registers' raw content. */
+ rdptr = (const void *)registers;
+ uset_raw = read_u16be_inc(&rdptr); /* USET */
+ volt_target = uset_raw / devc->voltage_multiplier;
+ iset_raw = read_u16be_inc(&rdptr); /* ISET */
+ curr_limit = iset_raw / devc->current_multiplier;
+ uout_raw = read_u16be_inc(&rdptr); /* UOUT */
+ curr_voltage = uout_raw / devc->voltage_multiplier;
+ iout_raw = read_u16be_inc(&rdptr); /* IOUT */
+ curr_current = iout_raw / devc->current_multiplier;
+ (void)read_u16be_inc(&rdptr); /* ENERGY */
+ power_raw = read_u16be_inc(&rdptr); /* POWER */
+ curr_power = power_raw / 100.0f;
+ (void)read_u16be_inc(&rdptr); /* VOLT_IN */
+ (void)read_u16be_inc(&rdptr);
+ reg_val = read_u16be_inc(&rdptr); /* PROTECT */
+ uses_ovp = reg_val == STATE_OVP;
+ uses_ocp = reg_val == STATE_OCP;
+ reg_state = read_u16be_inc(&rdptr); /* REGULATION */
+ is_reg_cc = reg_state == MODE_CC;
+ out_state = read_u16be_inc(&rdptr); /* ENABLE */
+ is_out_enabled = out_state != 0;
+
+ /* Retrieve a set of adjacent registers. */
+ g_mutex_lock(&devc->rw_mutex);
+ ret = rdtech_dps_read_holding_registers(modbus,
+ REG_RD_OVP_THR, 2, registers);
+ g_mutex_unlock(&devc->rw_mutex);
+ if (ret != SR_OK)
+ return ret;