diff --git a/drake/drake.c b/drake/drake.c index 5a9cdedad..cbbb96be5 100644 --- a/drake/drake.c +++ b/drake/drake.c @@ -2,7 +2,7 @@ * Hamlib Drake backend - main file * Copyright (c) 2001-2004 by Stephane Fillod * - * $Id: drake.c,v 1.14 2004-09-01 01:08:11 fineware Exp $ + * $Id: drake.c,v 1.15 2004-09-05 00:32:57 fineware Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -480,6 +480,200 @@ int drake_get_mem(RIG *rig, vfo_t vfo, int *ch) return RIG_OK; } +/* + * drake_set_chan + * Assumes rig!=NULL + */ +int drake_set_chan(RIG *rig, const channel_t *chan) +{ + struct drake_priv_data *priv = rig->state.priv; + vfo_t old_vfo; + int old_chan; + char mdbuf[16], ackbuf[16]; + int mdbuf_len, ack_len, retval; + + drake_get_vfo(rig, &old_vfo); + old_chan = 0; + + /* set to vfo if needed */ + if (old_vfo == RIG_VFO_MEM){ + old_chan = priv->curr_ch; + retval = drake_set_vfo(rig, RIG_VFO_VFO); + if (retval != RIG_OK) + return retval; + } + + /* set all memory features */ + drake_set_ant(rig, RIG_VFO_CURR, chan->ant); + drake_set_freq(rig, RIG_VFO_CURR, chan->freq); + drake_set_mode(rig, RIG_VFO_CURR, chan->mode, chan->width); + drake_set_func(rig, RIG_VFO_CURR, RIG_FUNC_NB, + (chan->funcs & RIG_FUNC_NB) == RIG_FUNC_NB); + drake_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_AGC, + chan->levels[rig_setting2idx(RIG_LEVEL_AGC)]); + drake_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_PREAMP, + chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)]); + drake_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_ATT, + chan->levels[rig_setting2idx(RIG_LEVEL_ATT)]); + drake_set_func(rig, RIG_VFO_CURR, RIG_FUNC_MN, + (chan->funcs & RIG_FUNC_MN) == RIG_FUNC_MN); + + mdbuf_len = sprintf(mdbuf, "PR" EOM "%03d" EOM, chan->channel_num); + retval = drake_transaction (rig, mdbuf, mdbuf_len, ackbuf, &ack_len); + + if (old_vfo == RIG_VFO_MEM) + drake_set_mem(rig, RIG_VFO_CURR, old_chan); + + return retval; +} + +/* + * drake_get_chan + * Assumes rig!=NULL + */ +int drake_get_chan(RIG *rig, channel_t *chan) +{ + struct drake_priv_data *priv = rig->state.priv; + vfo_t old_vfo; + int old_chan; + char mdbuf[BUFSZ],freqstr[BUFSZ]; + int mdbuf_len, retval; + + chan->vfo = RIG_VFO_MEM; + chan->ant = RIG_ANT_NONE; + chan->freq = 0; + chan->mode = RIG_MODE_NONE; + chan->width = RIG_PASSBAND_NORMAL; + chan->tx_freq = 0; + chan->tx_mode = RIG_MODE_NONE; + chan->tx_width = RIG_PASSBAND_NORMAL; + chan->split = RIG_SPLIT_OFF; + chan->tx_vfo = RIG_VFO_NONE; + chan->rptr_shift = RIG_RPT_SHIFT_NONE; + chan->rptr_offs = 0; + chan->tuning_step = 0; + chan->rit = 0; + chan->xit = 0; + chan->funcs = 0; + chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; + chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; + chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 0; + chan->ctcss_tone = 0; + chan->ctcss_sql = 0; + chan->dcs_code = 0; + chan->dcs_sql = 0; + chan->scan_group = 0; + chan->flags = RIG_CHFLAG_SKIP; + strcpy(chan->channel_desc, " "); + + drake_get_vfo(rig, &old_vfo); + old_chan = 0; + + if (old_vfo == RIG_VFO_MEM) + old_chan = priv->curr_ch; + + //go to new channel + retval = drake_set_mem(rig, RIG_VFO_CURR, chan->channel_num); + if (retval != RIG_OK) + return retval; + + //now decypher it + retval = drake_transaction (rig, "RA" EOM, 3, mdbuf, &mdbuf_len); + if (retval != RIG_OK) + return retval; + + if (mdbuf_len < 35) { + rig_debug(RIG_DEBUG_ERR,"drake_get_channel: wrong answer %s, " + "len=%d\n", mdbuf, mdbuf_len); + return -RIG_ERJCTED; + } + + if ((mdbuf[5] >= '4') && (mdbuf[5] <= '?')) + chan->funcs |= RIG_FUNC_NB; + + switch(mdbuf[5] & 0x33){ + case '0': chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; break; + case '2': chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; break; + case '3': chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_SLOW; break; + default : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; + } + + if ((mdbuf[6] & 0x3c) == '8') + chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 10; + + if ((mdbuf[6] & 0x3c) == '4') + chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 10; + + if ((mdbuf[6] & 0x32) =='2'); + chan->funcs |= RIG_FUNC_MN; + + switch(mdbuf[7] & 0x3c){ + case '0': chan->ant = RIG_ANT_1; break; + case '4': chan->ant = RIG_ANT_3; break; + case '8': chan->ant = RIG_ANT_2; break; + default : chan->ant = RIG_ANT_NONE; + } + + switch(mdbuf[8] & 0x37){ + case '0': chan->width = s_Hz(500); break; + case '1': chan->width = s_Hz(1800); break; + case '2': chan->width = s_Hz(2300); break; + case '3': chan->width = s_Hz(4000); break; + case '4': chan->width = s_Hz(6000); break; + default : chan->width = RIG_PASSBAND_NORMAL; + } + + if ((mdbuf[8] >= '0') && (mdbuf[8] <= '4')) { + switch(mdbuf[7] & 0x33){ + case '0': chan->mode = RIG_MODE_LSB; break; + case '1': chan->mode = RIG_MODE_RTTY; break; + case '2': chan->mode = RIG_MODE_FM; + chan->width = s_Hz(12000); break; + default : chan->mode = RIG_MODE_NONE; + } + } else { + switch(mdbuf[7] & 0x33){ + case '0': chan->mode = RIG_MODE_USB; break; + case '1': chan->mode = RIG_MODE_CW; break; + case '2': chan->mode = RIG_MODE_AM; break; + default : chan->mode = RIG_MODE_NONE; + } + } + + if ((mdbuf[9] & 0x34) == '4') { + if (chan->mode == RIG_MODE_AM) + chan->mode = RIG_MODE_AMS; + else if (chan->mode == RIG_MODE_USB) + chan->mode = RIG_MODE_ECSSUSB; + else if (chan->mode == RIG_MODE_LSB) + chan->mode = RIG_MODE_ECSSLSB; + } + + strncpy(freqstr,mdbuf+11,9); + freqstr[9] = 0x00; + if ((mdbuf[21] == 'k') || (mdbuf[21] == 'K')) + chan->freq = strtod(freqstr,NULL) * 1000.0; + if ((mdbuf[21] == 'm') || (mdbuf[21] == 'M')) + chan->freq = strtod(freqstr,NULL) * 1000000.0; + + + strncpy(chan->channel_desc, mdbuf+25, 7); + + //now put the radio back the way it was + if (old_vfo != RIG_VFO_MEM) { + retval = drake_set_vfo(rig, RIG_VFO_VFO); + if (retval != RIG_OK) + return retval; + } + else { + retval = drake_set_mem(rig, RIG_VFO_CURR, old_chan); + if (retval != RIG_OK) + return retval; + } + + return RIG_OK; +} + /* * drake_vfo_op * Assumes rig!=NULL diff --git a/drake/drake.h b/drake/drake.h index 3aeefb905..ab689267c 100644 --- a/drake/drake.h +++ b/drake/drake.h @@ -2,7 +2,7 @@ * Hamlib Drake backend - main header * Copyright (c) 2001-2004 by Stephane Fillod * - * $Id: drake.h,v 1.6 2004-06-04 21:48:05 fillods Exp $ + * $Id: drake.h,v 1.7 2004-09-05 00:32:57 fineware Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -41,6 +41,8 @@ int drake_set_ant(RIG *rig, vfo_t vfo, ant_t ant); int drake_get_ant(RIG *rig, vfo_t vfo, ant_t *ant); int drake_set_mem(RIG *rig, vfo_t vfo, int ch); int drake_get_mem(RIG *rig, vfo_t vfo, int *ch); +int drake_set_chan(RIG *rig, const channel_t *chan); +int drake_get_chan(RIG *rig, channel_t *chan); int drake_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int drake_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int drake_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); diff --git a/drake/r8a.c b/drake/r8a.c index 6580ddf43..bd40eaa07 100644 --- a/drake/r8a.c +++ b/drake/r8a.c @@ -2,7 +2,7 @@ * Hamlib Drake backend - R-8A description * Copyright (c) 2001-2004 by Stephane Fillod * - * $Id: r8a.c,v 1.5 2004-08-31 03:45:34 fineware Exp $ + * $Id: r8a.c,v 1.6 2004-09-05 00:32:57 fineware Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -63,6 +63,19 @@ { 255, 60 }, \ } } +/* + * channel caps. + */ +#define DRAKE_MEM_CAP { \ + .freq = 1, \ + .mode = 1, \ + .width = 1, \ + .ant = 1, \ + .funcs = 1, \ + .levels = RIG_LEVEL_AGC|RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ + .channel_desc = 1, \ +} + /* * R-8A rig capabilities. * @@ -114,7 +127,7 @@ const struct rig_caps r8a_caps = { .vfo_ops = R8A_VFO_OPS, .chan_list = { - { 0, 439, RIG_MTYPE_MEM }, + { 0, 439, RIG_MTYPE_MEM, DRAKE_MEM_CAP }, RIG_CHAN_END }, @@ -168,6 +181,8 @@ const struct rig_caps r8a_caps = { .get_ant = drake_get_ant, .set_mem = drake_set_mem, .get_mem = drake_get_mem, +.set_channel = drake_set_chan, +.get_channel = drake_get_chan, .vfo_op = drake_vfo_op, .set_powerstat = drake_set_powerstat, .get_powerstat = drake_get_powerstat, diff --git a/drake/r8b.c b/drake/r8b.c index 7fbecc21d..9486ba45c 100644 --- a/drake/r8b.c +++ b/drake/r8b.c @@ -2,7 +2,7 @@ * Hamlib Drake backend - R-8B description * Copyright (c) 2001-2004 by Stephane Fillod * - * $Id: r8b.c,v 1.9 2004-08-31 03:45:34 fineware Exp $ + * $Id: r8b.c,v 1.10 2004-09-05 00:32:57 fineware Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -63,6 +63,19 @@ { 255, 60 }, \ } } +/* + * channel caps. + */ +#define DRAKE_MEM_CAP { \ + .freq = 1, \ + .mode = 1, \ + .width = 1, \ + .ant = 1, \ + .funcs = 1, \ + .levels = RIG_LEVEL_AGC|RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ + .channel_desc = 1, \ +} + /* * R-8B rig capabilities. * @@ -114,7 +127,7 @@ const struct rig_caps r8b_caps = { .vfo_ops = R8B_VFO_OPS, .chan_list = { - { 0, 999, RIG_MTYPE_MEM }, + { 0, 999, RIG_MTYPE_MEM, DRAKE_MEM_CAP }, RIG_CHAN_END }, @@ -168,6 +181,8 @@ const struct rig_caps r8b_caps = { .get_ant = drake_get_ant, .set_mem = drake_set_mem, .get_mem = drake_get_mem, +.set_channel = drake_set_chan, +.get_channel = drake_get_chan, .vfo_op = drake_vfo_op, .set_powerstat = drake_set_powerstat, .get_powerstat = drake_get_powerstat, diff --git a/jrc/jrc.c b/jrc/jrc.c index 78a416fa5..ed37b1305 100644 --- a/jrc/jrc.c +++ b/jrc/jrc.c @@ -2,7 +2,7 @@ * Hamlib JRC backend - main file * Copyright (c) 2001-2004 by Stephane Fillod * - * $Id: jrc.c,v 1.16 2004-08-31 03:47:52 fineware Exp $ + * $Id: jrc.c,v 1.17 2004-09-05 00:33:47 fineware Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -987,6 +987,163 @@ int jrc_get_mem(RIG *rig, vfo_t vfo, int *ch) return RIG_OK; } +/* + * jrc_set_chan + * Assumes rig!=NULL + */ +int jrc_set_chan(RIG *rig, const channel_t *chan) +{ + struct jrc_priv_caps *priv = (struct jrc_priv_caps*)rig->caps->priv; + char cmdbuf[BUFSZ]; + int cmd_len; + + sprintf(cmdbuf,"K%03d000",chan->channel_num); + + if (chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i == 20) + cmdbuf[4] = '1'; + + if (chan->width <= s_Hz(1500)) + cmdbuf[5] = '2'; + else if (chan->width <= s_Hz(4000)) + cmdbuf[5] = '1'; + else if (chan->width <= s_Hz(9000)) + cmdbuf[5] = '0'; + else if (rig->caps->rig_model == RIG_MODEL_NRD535) + cmdbuf[5] = '3'; /*aux - nrd535 only*/ + else + cmdbuf[5] = '1'; /*inter*/ + + switch (chan->mode) { + case RIG_MODE_CW: cmdbuf[6] = MD_CW; break; + case RIG_MODE_USB: cmdbuf[6] = MD_USB; break; + case RIG_MODE_LSB: cmdbuf[6] = MD_LSB; break; + case RIG_MODE_FM: cmdbuf[6] = MD_FM; break; + case RIG_MODE_AM: cmdbuf[6] = MD_AM; break; + case RIG_MODE_RTTY: cmdbuf[6] = MD_RTTY; break; + case RIG_MODE_WFM: cmdbuf[6] = MD_WFM; break; + case RIG_MODE_AMS: cmdbuf[6] = MD_AMS; break; + case RIG_MODE_FAX: cmdbuf[6] = MD_FAX; break; + case RIG_MODE_ECSSUSB: cmdbuf[6] = MD_ECSS_USB; break; + case RIG_MODE_ECSSLSB: cmdbuf[6] = MD_ECSS_LSB; break; + default: cmdbuf[6] = MD_AM; + } + + sprintf(cmdbuf+7,"%0*Ld", priv->max_freq_len, (long long)chan->freq); + + if (priv->mem_len==17) { + switch (chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i) { + case RIG_AGC_SLOW : cmdbuf[priv->mem_len-2] = '0'; break; + case RIG_AGC_FAST : cmdbuf[priv->mem_len-2] = '1'; break; + case RIG_AGC_OFF : cmdbuf[priv->mem_len-2] = '2'; break; + default : cmdbuf[priv->mem_len-2] = '1'; + } + } + else { + sprintf(cmdbuf+priv->mem_len-4,"%03d", chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i); + } + + cmd_len = priv->mem_len; + return jrc_transaction (rig, cmdbuf, cmd_len, NULL, NULL); +} + +/* + * jrc_get_chan + * Assumes rig!=NULL + */ +int jrc_get_chan(RIG *rig, channel_t *chan) +{ + struct jrc_priv_caps *priv = (struct jrc_priv_caps*)rig->caps->priv; + char membuf[BUFSZ], cmdbuf[BUFSZ], freqbuf[BUFSZ]; + int mem_len, cmd_len, retval; + + chan->vfo = RIG_VFO_MEM; + chan->ant = RIG_ANT_NONE; + chan->freq = 0; + chan->mode = RIG_MODE_NONE; + chan->width = RIG_PASSBAND_NORMAL; + chan->tx_freq = 0; + chan->tx_mode = RIG_MODE_NONE; + chan->tx_width = RIG_PASSBAND_NORMAL; + chan->split = RIG_SPLIT_OFF; + chan->tx_vfo = RIG_VFO_NONE; + chan->rptr_shift = RIG_RPT_SHIFT_NONE; + chan->rptr_offs = 0; + chan->tuning_step = 0; + chan->rit = 0; + chan->xit = 0; + chan->funcs = 0; + chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; + chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; + chan->ctcss_tone = 0; + chan->ctcss_sql = 0; + chan->dcs_code = 0; + chan->dcs_sql = 0; + chan->scan_group = 0; + chan->flags = RIG_CHFLAG_SKIP; + strcpy(chan->channel_desc, ""); + + cmd_len = sprintf(cmdbuf, "L%03d%03d" EOM, chan->channel_num, chan->channel_num); + retval = jrc_transaction (rig, cmdbuf, cmd_len, membuf, &mem_len); + if (retval != RIG_OK) + return retval; + + /* need to handle vacant memories LmmmV, len = 6 */ + if ((mem_len != priv->mem_len) && (mem_len != 6)) { + rig_debug(RIG_DEBUG_ERR,"jrc_get_mem: wrong answer %s, " + "len=%d\n", membuf, mem_len); + return -RIG_ERJCTED; + } + + if (mem_len != 6) { + if (membuf[4] == '1') + chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 20; + switch (membuf[5]) { + case '0' : chan->width = s_Hz(6000); break; //wide + case '1' : chan->width = s_Hz(2000); break; //inter + case '2' : chan->width = s_Hz(1000); break; //narr + case '3' : chan->width = s_Hz(12000); break; //aux - nrd535 only + default : chan->width = RIG_PASSBAND_NORMAL; + } + switch (membuf[6]) { + case '0' : chan->mode = RIG_MODE_RTTY; break; + case '1' : chan->mode = RIG_MODE_CW; break; + case '2' : chan->mode = RIG_MODE_USB; break; + case '3' : chan->mode = RIG_MODE_LSB; break; + case '4' : chan->mode = RIG_MODE_AM; break; + case '5' : chan->mode = RIG_MODE_FM; break; + case '6' : if (rig->caps->rig_model == RIG_MODEL_NRD535) { + chan->mode = RIG_MODE_FAX; break; //FAX on nrd535 + } + else { + chan->mode = RIG_MODE_AMS; break; //AMS on nrd545 + } + case '7' : chan->mode = RIG_MODE_ECSSUSB; break; //ECSS-USB + case '8' : chan->mode = RIG_MODE_ECSSLSB; break; //ECSS-LSB + case '9' : chan->mode = RIG_MODE_WFM; break; //nrd545 only + default: chan->mode = RIG_MODE_NONE; + } + + strncpy(freqbuf,membuf+7,priv->max_freq_len); + freqbuf[priv->max_freq_len] = 0x00; + chan->freq = strtol(freqbuf,NULL, 10); + + if (priv->mem_len==17) { + switch (membuf[priv->mem_len-2]){ + case '0' : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_SLOW; break; + case '1' : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; break; + case '2' : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; break; + default : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; + } + } + else { + strncpy(freqbuf,membuf+priv->mem_len-4,3); + chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = strtol(freqbuf,NULL, 10); + } + } + + return RIG_OK; +} + /* * jrc_vfo_op * Assumes rig!=NULL diff --git a/jrc/jrc.h b/jrc/jrc.h index 0e6cbd39b..d6bd9ea18 100644 --- a/jrc/jrc.h +++ b/jrc/jrc.h @@ -2,7 +2,7 @@ * Hamlib JRC backend - main header * Copyright (c) 2001-2004 by Stephane Fillod * - * $Id: jrc.h,v 1.9 2004-08-31 03:47:52 fineware Exp $ + * $Id: jrc.h,v 1.10 2004-09-05 00:33:56 fineware Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -53,6 +53,8 @@ int jrc_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int jrc_set_trn(RIG *rig, int trn); int jrc_set_mem(RIG *rig, vfo_t vfo, int ch); int jrc_get_mem(RIG *rig, vfo_t vfo, int *ch); +int jrc_set_chan(RIG *rig, const channel_t *chan); +int jrc_get_chan(RIG *rig, channel_t *chan); int jrc_set_powerstat(RIG *rig, powerstat_t status); int jrc_get_powerstat(RIG *rig, powerstat_t *status); int jrc_reset(RIG *rig, reset_t reset); diff --git a/jrc/nrd535.c b/jrc/nrd535.c index e6c2842ac..52be296a0 100644 --- a/jrc/nrd535.c +++ b/jrc/nrd535.c @@ -2,7 +2,7 @@ * Hamlib JRC backend - NRD-535 DSP description * Copyright (c) 2001-2004 by Stephane Fillod * - * $Id: nrd535.c,v 1.9 2004-08-31 03:47:52 fineware Exp $ + * $Id: nrd535.c,v 1.10 2004-09-05 00:33:56 fineware Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -199,6 +199,8 @@ const struct rig_caps nrd535_caps = { .reset = jrc_reset, .set_mem = jrc_set_mem, .get_mem = jrc_get_mem, +.set_channel = jrc_set_chan, +.get_channel = jrc_get_chan, .vfo_op = jrc_vfo_op, .scan = jrc_scan, .set_powerstat = jrc_set_powerstat, diff --git a/jrc/nrd545.c b/jrc/nrd545.c index d93c102e4..4998f8635 100644 --- a/jrc/nrd545.c +++ b/jrc/nrd545.c @@ -2,7 +2,7 @@ * Hamlib JRC backend - NRD-545 DSP description * Copyright (c) 2001-2004 by Stephane Fillod * - * $Id: nrd545.c,v 1.13 2004-08-31 03:47:52 fineware Exp $ + * $Id: nrd545.c,v 1.14 2004-09-05 00:33:56 fineware Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -198,6 +198,8 @@ const struct rig_caps nrd545_caps = { .reset = jrc_reset, .set_mem = jrc_set_mem, .get_mem = jrc_get_mem, +.set_channel = jrc_set_chan, +.get_channel = jrc_get_chan, .vfo_op = jrc_vfo_op, .scan = jrc_scan, .set_powerstat = jrc_set_powerstat,