hp-59306a: Rename channel groups from CHn to Rn
[libsigrok.git] / src / hardware / hp-59306a / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2021 Frank Stettner <frank-stettner@gmx.net>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include "scpi.h"
22 #include "protocol.h"
23
24 static const uint32_t scanopts[] = {
25         SR_CONF_CONN,
26 };
27
28 static const uint32_t drvopts[] = {
29         SR_CONF_MULTIPLEXER,
30 };
31
32 static const uint32_t devopts[] = {
33         SR_CONF_CONN | SR_CONF_GET,
34         SR_CONF_ENABLED | SR_CONF_SET,
35 };
36
37 static const uint32_t devopts_cg[] = {
38         SR_CONF_ENABLED | SR_CONF_SET,
39 };
40
41 static struct sr_dev_driver hp_59306a_driver_info;
42
43 static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
44 {
45         struct sr_dev_inst *sdi;
46         struct dev_context *devc;
47         struct channel_group_context *cgc;
48         size_t idx, nr;
49         struct sr_channel_group *cg;
50
51         /*
52          * The device cannot get identified by means of SCPI queries.
53          * Neither shall non-SCPI requests get emitted before reliable
54          * identification of the device. Assume that we only get here
55          * when user specs led us to believe it's safe to communicate
56          * to the expected kind of device.
57          */
58
59         sdi = g_malloc0(sizeof(*sdi));
60         sdi->vendor = g_strdup("Hewlett-Packard");
61         sdi->model = g_strdup("59306A");
62         sdi->conn = scpi;
63         sdi->driver = &hp_59306a_driver_info;
64         sdi->inst_type = SR_INST_SCPI;
65         if (sr_scpi_connection_id(scpi, &sdi->connection_id) != SR_OK) {
66                 g_free(sdi->connection_id);
67                 sdi->connection_id = NULL;
68         }
69
70         devc = g_malloc0(sizeof(*devc));
71         sdi->priv = devc;
72
73         devc->channel_count = 6;
74         for (idx = 0; idx < devc->channel_count; idx++) {
75                 nr = idx + 1;
76
77                 cg = g_malloc0(sizeof(*cg));
78                 cg->name = g_strdup_printf("R%zu", nr);
79
80                 cgc = g_malloc0(sizeof(*cgc));
81                 cgc->number = nr;
82                 cg->priv = cgc;
83
84                 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
85         }
86
87         return sdi;
88 }
89
90 static GSList *scan(struct sr_dev_driver *di, GSList *options)
91 {
92         const char *conn;
93
94         /* Only scan for a device when conn= was specified. */
95         conn = NULL;
96         (void)sr_serial_extract_options(options, &conn, NULL);
97         if (!conn)
98                 return NULL;
99
100         return sr_scpi_scan(di->context, options, probe_device);
101 }
102
103 static int dev_open(struct sr_dev_inst *sdi)
104 {
105         return sr_scpi_open(sdi->conn);
106 }
107
108 static int dev_close(struct sr_dev_inst *sdi)
109 {
110         return sr_scpi_close(sdi->conn);
111 }
112
113 static int config_get(uint32_t key, GVariant **data,
114         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
115 {
116         (void)cg;
117
118         if (!sdi || !data)
119                 return SR_ERR_ARG;
120
121         switch (key) {
122         case SR_CONF_CONN:
123                 *data = g_variant_new_string(sdi->connection_id);
124                 break;
125         default:
126                 return SR_ERR_NA;
127         }
128
129         return SR_OK;
130 }
131
132 static int config_set(uint32_t key, GVariant *data,
133         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
134 {
135         gboolean on;
136
137         if (!cg) {
138                 switch (key) {
139                 case SR_CONF_ENABLED:
140                         /* Enable/disable all channels at the same time. */
141                         on = g_variant_get_boolean(data);
142                         return hp_59306a_switch_cg(sdi, cg, on);
143                 default:
144                         return SR_ERR_NA;
145                 }
146         } else {
147                 switch (key) {
148                 case SR_CONF_ENABLED:
149                         on = g_variant_get_boolean(data);
150                         return hp_59306a_switch_cg(sdi, cg, on);
151                 default:
152                         return SR_ERR_NA;
153                 }
154         }
155
156         return SR_OK;
157 }
158
159 static int config_list(uint32_t key, GVariant **data,
160         const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
161 {
162         if (!cg) {
163                 switch (key) {
164                 case SR_CONF_SCAN_OPTIONS:
165                 case SR_CONF_DEVICE_OPTIONS:
166                         return STD_CONFIG_LIST(key, data, sdi, cg,
167                                 scanopts, drvopts, devopts);
168                 default:
169                         return SR_ERR_NA;
170                 }
171         } else {
172                 switch (key) {
173                 case SR_CONF_DEVICE_OPTIONS:
174                         *data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg));
175                         break;
176                 default:
177                         return SR_ERR_NA;
178                 }
179         }
180
181         return SR_OK;
182 }
183
184 static struct sr_dev_driver hp_59306a_driver_info = {
185         .name = "hp-59306a",
186         .longname = "HP 59306A",
187         .api_version = 1,
188         .init = std_init,
189         .cleanup = std_cleanup,
190         .scan = scan,
191         .dev_list = std_dev_list,
192         .dev_clear = std_dev_clear,
193         .config_get = config_get,
194         .config_set = config_set,
195         .config_list = config_list,
196         .dev_open = dev_open,
197         .dev_close = dev_close,
198         .dev_acquisition_start = std_dummy_dev_acquisition_start,
199         .dev_acquisition_stop = std_dummy_dev_acquisition_stop,
200         .context = NULL,
201 };
202 SR_REGISTER_DEV_DRIVER(hp_59306a_driver_info);