genericdmm: use new scan API

This commit is contained in:
Bert Vermeulen 2012-07-08 23:49:04 +02:00
parent bbb40871c8
commit 3a0fe4023d
1 changed files with 102 additions and 16 deletions

View File

@ -187,6 +187,31 @@ GSList *genericdmm_connect(const char *conn, const char *serialcomm)
return NULL; return NULL;
} }
static GSList *default_scan(GSList *options)
{
GSList *l, *devices;
struct sr_hwopt *opt;
const char *conn, *serialcomm;
devices = NULL;
conn = serialcomm = NULL;
for (l = options; l; l = l->next) {
opt = l->data;
switch (opt->hwopt) {
case SR_HWOPT_CONN:
conn = opt->value;
break;
case SR_HWOPT_SERIALCOMM:
serialcomm = opt->value;
break;
}
}
if (conn)
devices = genericdmm_connect(conn, serialcomm);
return devices;
}
static int hw_init(void) static int hw_init(void)
{ {
@ -199,28 +224,89 @@ static int hw_init(void)
return SR_OK; return SR_OK;
} }
static int hw_scan(void) static GSList *hw_scan(GSList *options)
{ {
struct sr_dev_inst *sdi; GSList *l, *ldef, *defopts, *newopts, *devices;
struct context *ctx; struct sr_hwopt *opt, *defopt;
int devcnt = 0; struct dev_profile *pr, *profile;
const char *model;
if (!(ctx = g_try_malloc0(sizeof(struct context)))) { /* Separate model from the options list. */
sr_err("genericdmm: ctx malloc failed."); model = NULL;
return 0; newopts = NULL;
for (l = options; l; l = l->next) {
opt = l->data;
if (opt->hwopt == SR_HWOPT_MODEL)
model = opt->value;
else
/* New list with references to the original data. */
newopts = g_slist_append(newopts, opt);
}
if (!model) {
sr_err("Need a model to scan for.");
return NULL;
} }
devcnt = g_slist_length(genericdmm_dev_insts); /* Find a profile with this model name. */
if (!(sdi = sr_dev_inst_new(devcnt, SR_ST_ACTIVE, "Generic DMM", profile = NULL;
NULL, NULL))) { for (pr = dev_profiles; pr->modelid; pr++) {
sr_err("genericdmm: sr_dev_inst_new returned NULL."); if (!strcmp(pr->modelid, model)) {
return 0; profile = pr;
break;
}
}
if (!profile) {
sr_err("Unknown model %s.", model);
return NULL;
} }
sdi->priv = ctx;
genericdmm_dev_insts = g_slist_append(genericdmm_dev_insts, sdi);
/* Always initialized just one device instance. */ /* Initialize the DMM chip driver. */
return 0; if (profile->chip->init)
profile->chip->init();
/* Convert the profile's default options list to a GSList. */
defopts = NULL;
for (opt = profile->defaults_opts; opt->hwopt; opt++) {
/* New list with references to const data in the profile. */
defopts = g_slist_append(defopts, opt);
}
/* Options given as argument to this function override the
* profile's default options.
*/
for (ldef = defopts; ldef; ldef = ldef->next) {
defopt = ldef->data;
for (l = newopts; l; l = l->next) {
opt = l->data;
if (opt->hwopt == defopt->hwopt) {
/* Override the default, and drop it from the
* options list.
*/
ldef->data = l->data;
newopts = g_slist_remove(newopts, opt);
break;
}
}
}
/* Whatever is left in newopts wasn't in the default options. */
defopts = g_slist_concat(defopts, newopts);
g_slist_free(newopts);
if (profile->chip->scan)
/* The DMM chip driver wants to do its own scanning. */
devices = profile->chip->scan(defopts);
else
devices = default_scan(defopts);
g_slist_free(defopts);
if (devices) {
/* TODO: need to fix up sdi->index fields */
/* Add a copy of these new devices to the driver instances. */
for (l = devices; l; l = l->next)
gdi->instances = g_slist_append(gdi->instances, l->data);
}
return devices;
} }
static int hw_dev_open(int dev_index) static int hw_dev_open(int dev_index)