+ struct dev_context *devc;
+ struct sr_dev_inst *sdi;
+ struct sr_scpi_hw_info *hw_info;
+ struct sr_channel_group *cg;
+ struct sr_channel *ch;
+ const struct scpi_pps *device;
+ struct pps_channel *pch;
+ struct channel_spec *channels;
+ struct channel_group_spec *channel_groups, *cgs;
+ struct pps_channel_group *pcg;
+ GRegex *model_re;
+ GMatchInfo *model_mi;
+ GSList *l;
+ uint64_t mask;
+ unsigned int num_channels, num_channel_groups, ch_num, ch_idx, i, j;
+ int ret;
+ const char *vendor;
+ char ch_name[16];
+
+ if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
+ sr_info("Couldn't get IDN response.");
+ return NULL;
+ }
+
+ device = NULL;
+ for (i = 0; i < num_pps_profiles; i++) {
+ vendor = get_vendor(hw_info->manufacturer);
+ if (strcasecmp(vendor, pps_profiles[i].vendor))
+ continue;
+ model_re = g_regex_new(pps_profiles[i].model, 0, 0, NULL);
+ if (g_regex_match(model_re, hw_info->model, 0, &model_mi))
+ device = &pps_profiles[i];
+ g_match_info_unref(model_mi);
+ g_regex_unref(model_re);
+ if (device)
+ break;
+ }
+ if (!device) {
+ sr_scpi_hw_info_free(hw_info);
+ return NULL;
+ }
+
+ sdi = sr_dev_inst_new(SR_ST_ACTIVE, vendor, hw_info->model,
+ hw_info->firmware_version);
+ sdi->conn = scpi;
+ sdi->driver = di;
+ sdi->inst_type = SR_INST_SCPI;
+ sdi->serial_num = g_strdup(hw_info->serial_number);
+
+ devc = g_malloc0(sizeof(struct dev_context));
+ devc->device = device;
+ sdi->priv = devc;
+
+ if (device->num_channels) {
+ /* Static channels and groups. */
+ channels = device->channels;
+ num_channels = device->num_channels;
+ channel_groups = device->channel_groups;
+ num_channel_groups = device->num_channel_groups;
+ } else {
+ /* Channels and groups need to be probed. */
+ ret = device->probe_channels(sdi, hw_info, &channels, &num_channels,
+ &channel_groups, &num_channel_groups);
+ if (ret != SR_OK) {
+ sr_err("Failed to probe for channels.");
+ return NULL;
+ }
+ /*
+ * Since these were dynamically allocated, we'll need to free them
+ * later.
+ */
+ devc->channels = channels;
+ devc->channel_groups = channel_groups;
+ }
+
+ ch_idx = 0;
+ for (ch_num = 0; ch_num < num_channels; ch_num++) {
+ /* Create one channel per measurable output unit. */
+ for (i = 0; i < ARRAY_SIZE(pci); i++) {
+ if (!scpi_cmd_get(sdi, pci[i].command))
+ continue;
+ g_snprintf(ch_name, 16, "%s%s", pci[i].prefix,
+ channels[ch_num].name);
+ ch = sr_channel_new(ch_idx++, SR_CHANNEL_ANALOG, TRUE, ch_name);
+ pch = g_malloc0(sizeof(struct pps_channel));
+ pch->hw_output_idx = ch_num;
+ pch->hwname = channels[ch_num].name;
+ pch->mq = pci[i].mq;
+ ch->priv = pch;
+ sdi->channels = g_slist_append(sdi->channels, ch);
+ }
+ }