|
|
@@ -42,6 +42,7 @@ struct nanofury_state {
|
|
|
unsigned long current_baud;
|
|
|
bool ledalternating;
|
|
|
bool ledvalue;
|
|
|
+ bool powered_off;
|
|
|
};
|
|
|
|
|
|
// Bit-banging reset, to reset more chips in chain - toggle for longer period... Each 3 reset cycles reset first chip in chain
|
|
|
@@ -66,7 +67,7 @@ bool nanofury_spi_reset(struct mcp2210_device * const mcp)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static void nanofury_device_off(struct mcp2210_device *);
|
|
|
+static void nanofury_device_off(struct mcp2210_device *, struct nanofury_state *);
|
|
|
|
|
|
static
|
|
|
bool nanofury_spi_txrx(struct spi_port * const port)
|
|
|
@@ -113,7 +114,7 @@ bool nanofury_spi_txrx(struct spi_port * const port)
|
|
|
|
|
|
err:
|
|
|
mcp2210_spi_cancel(mcp);
|
|
|
- nanofury_device_off(mcp);
|
|
|
+ nanofury_device_off(mcp, state);
|
|
|
if (cgpu)
|
|
|
{
|
|
|
struct thr_info * const thr = cgpu->thr[0];
|
|
|
@@ -137,15 +138,17 @@ void nanofury_do_led_alternating(struct nanofury_state * const state)
|
|
|
}
|
|
|
|
|
|
static
|
|
|
-void nanofury_device_off(struct mcp2210_device * const mcp)
|
|
|
+void nanofury_device_off(struct mcp2210_device * const mcp, struct nanofury_state * const state)
|
|
|
{
|
|
|
// Try to reset everything back to input
|
|
|
for (int i = 0; i < 9; ++i)
|
|
|
mcp2210_get_gpio_input(mcp, i);
|
|
|
+ if (state)
|
|
|
+ state->powered_off = true;
|
|
|
}
|
|
|
|
|
|
static
|
|
|
-bool nanofury_power_enable(struct mcp2210_device * const mcp, const bool poweron)
|
|
|
+bool nanofury_power_enable(struct mcp2210_device * const mcp, const bool poweron, struct nanofury_state * const state)
|
|
|
{
|
|
|
if (!mcp2210_set_gpio_output(mcp, NANOFURY_GP_PIN_PWR_EN, poweron ? MGV_HIGH : MGV_LOW))
|
|
|
return false;
|
|
|
@@ -153,11 +156,14 @@ bool nanofury_power_enable(struct mcp2210_device * const mcp, const bool poweron
|
|
|
if (!mcp2210_set_gpio_output(mcp, NANOFURY_GP_PIN_PWR_EN0, poweron ? MGV_LOW : MGV_HIGH))
|
|
|
return false;
|
|
|
|
|
|
+ if (state)
|
|
|
+ state->powered_off = !poweron;
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
static
|
|
|
-bool nanofury_checkport(struct mcp2210_device * const mcp, const unsigned long baud)
|
|
|
+bool nanofury_checkport(struct mcp2210_device * const mcp, const unsigned long baud, struct nanofury_state * const state)
|
|
|
{
|
|
|
int i;
|
|
|
const char tmp = 0;
|
|
|
@@ -174,7 +180,7 @@ bool nanofury_checkport(struct mcp2210_device * const mcp, const unsigned long b
|
|
|
if (!mcp2210_set_gpio_output(mcp, NANOFURY_GP_PIN_LED, MGV_HIGH))
|
|
|
goto fail;
|
|
|
|
|
|
- nanofury_power_enable(mcp, true);
|
|
|
+ nanofury_power_enable(mcp, true, state);
|
|
|
|
|
|
// cancel any outstanding SPI transfers
|
|
|
mcp2210_spi_cancel(mcp);
|
|
|
@@ -217,7 +223,7 @@ bool nanofury_checkport(struct mcp2210_device * const mcp, const unsigned long b
|
|
|
return true;
|
|
|
|
|
|
fail:
|
|
|
- nanofury_device_off(mcp);
|
|
|
+ nanofury_device_off(mcp, state);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
@@ -272,7 +278,7 @@ bool nanofury_lowl_probe(const struct lowlevel_device_info * const info)
|
|
|
drv_set_defaults(&nanofury_drv, bitfury_set_device_funcs_probe, &dummy_bitfury, NULL, NULL, 1);
|
|
|
}
|
|
|
|
|
|
- if (!nanofury_checkport(mcp, port->speed))
|
|
|
+ if (!nanofury_checkport(mcp, port->speed, NULL))
|
|
|
{
|
|
|
applog(LOG_WARNING, "%s: Matched \"%s\" serial \"%s\", but failed to detect nanofury",
|
|
|
__func__, product, serial);
|
|
|
@@ -284,7 +290,7 @@ bool nanofury_lowl_probe(const struct lowlevel_device_info * const info)
|
|
|
chips = libbitfury_detectChips1(port);
|
|
|
free(port);
|
|
|
|
|
|
- nanofury_device_off(mcp);
|
|
|
+ nanofury_device_off(mcp, NULL);
|
|
|
mcp2210_close(mcp);
|
|
|
|
|
|
if (lowlevel_claim(&nanofury_drv, true, info))
|
|
|
@@ -332,7 +338,7 @@ bool nanofury_init(struct thr_info * const thr)
|
|
|
applog(LOG_ERR, "%"PRIpreprv": Failed to open mcp2210 device", cgpu->proc_repr);
|
|
|
return false;
|
|
|
}
|
|
|
- if (!nanofury_checkport(mcp, state->current_baud))
|
|
|
+ if (!nanofury_checkport(mcp, state->current_baud, state))
|
|
|
{
|
|
|
applog(LOG_ERR, "%"PRIpreprv": checkport failed", cgpu->proc_repr);
|
|
|
mcp2210_close(mcp);
|
|
|
@@ -385,34 +391,56 @@ bool nanofury_init(struct thr_info * const thr)
|
|
|
static
|
|
|
void nanofury_disable(struct thr_info * const thr)
|
|
|
{
|
|
|
+ struct cgpu_info * const proc = thr->cgpu;
|
|
|
+ struct cgpu_info * const dev = proc->device;
|
|
|
struct nanofury_state * const state = thr->cgpu_data;
|
|
|
struct mcp2210_device * const mcp = state->mcp;
|
|
|
|
|
|
bitfury_disable(thr);
|
|
|
- nanofury_device_off(mcp);
|
|
|
+
|
|
|
+ // Before powering off, ensure no other chip needs power
|
|
|
+ for_each_managed_proc(oproc, dev)
|
|
|
+ if (oproc->deven == DEV_ENABLED)
|
|
|
+ return;
|
|
|
+
|
|
|
+ applog(LOG_NOTICE, "%s: Last chip disabled, shutting off power",
|
|
|
+ dev->dev_repr);
|
|
|
+ nanofury_device_off(mcp, state);
|
|
|
}
|
|
|
|
|
|
static
|
|
|
void nanofury_enable(struct thr_info * const thr)
|
|
|
{
|
|
|
+ struct cgpu_info * const proc = thr->cgpu;
|
|
|
+ struct cgpu_info * const dev = proc->device;
|
|
|
struct nanofury_state * const state = thr->cgpu_data;
|
|
|
struct mcp2210_device * const mcp = state->mcp;
|
|
|
|
|
|
- nanofury_checkport(mcp, state->current_baud);
|
|
|
- nanofury_send_led_gpio(state);
|
|
|
+ if (state->powered_off)
|
|
|
+ {
|
|
|
+ // All chips were disabled, so we need to power back on
|
|
|
+ applog(LOG_DEBUG, "%s: Enabling power",
|
|
|
+ dev->dev_repr);
|
|
|
+ nanofury_checkport(mcp, state->current_baud, state);
|
|
|
+ nanofury_send_led_gpio(state);
|
|
|
+ }
|
|
|
+
|
|
|
bitfury_enable(thr);
|
|
|
}
|
|
|
|
|
|
static
|
|
|
-void nanofury_reinit(struct cgpu_info * const cgpu)
|
|
|
+void nanofury_reinit(struct cgpu_info * const proc)
|
|
|
{
|
|
|
- struct thr_info * const thr = cgpu->thr[0];
|
|
|
+ struct thr_info * const thr = proc->thr[0];
|
|
|
+ struct cgpu_info * const dev = proc->device;
|
|
|
struct nanofury_state * const state = thr->cgpu_data;
|
|
|
struct mcp2210_device * const mcp = state->mcp;
|
|
|
|
|
|
- nanofury_device_off(mcp);
|
|
|
+ nanofury_device_off(mcp, state);
|
|
|
cgsleep_ms(1);
|
|
|
- nanofury_enable(thr);
|
|
|
+ for_each_managed_proc(oproc, dev)
|
|
|
+ if (oproc->deven == DEV_ENABLED)
|
|
|
+ nanofury_enable(oproc->thr[0]);
|
|
|
}
|
|
|
|
|
|
static
|
|
|
@@ -471,7 +499,7 @@ void nanofury_shutdown(struct thr_info * const thr)
|
|
|
struct mcp2210_device * const mcp = state->mcp;
|
|
|
|
|
|
if (mcp)
|
|
|
- nanofury_device_off(mcp);
|
|
|
+ nanofury_device_off(mcp, state);
|
|
|
}
|
|
|
|
|
|
const char *nanofury_set_ledmode(struct cgpu_info * const proc, const char * const option, const char * const setting, char * const replybuf, enum bfg_set_device_replytype * const success)
|