/* * free all resources used by the channels and switch off leds and can power */ static void pcan_free_channels(struct pcan_pccard *card) { int i; u8 led_mask = 0; for (i = 0; i < card->chan_count; i++) { struct net_device *netdev; char name[IFNAMSIZ]; led_mask |= PCC_LED(i); netdev = card->channel[i].netdev; if (!netdev) continue; strncpy(name, netdev->name, IFNAMSIZ); unregister_sja1000dev(netdev); free_sja1000dev(netdev); dev_info(&card->pdev->dev, "%s removed\n", name); } /* do it only if device not removed */ if (pcan_pccard_present(card)) { pcan_set_leds(card, led_mask, PCC_LED_OFF); pcan_set_can_power(card, 0); } }
/* * write a sja1000 register */ static void pcan_write_canreg(const struct sja1000_priv *priv, int port, u8 v) { struct pcan_pccard *card = priv->priv; int c = (priv->reg_base - card->ioport_addr) / PCC_CHAN_SIZE; /* sja1000 register changes control the leds state */ if (port == REG_MOD) switch (v) { case MOD_RM: /* Reset Mode: set led on */ pcan_set_leds(card, PCC_LED(c), PCC_LED_ON); break; case 0x00: /* Normal Mode: led slow blinking and start led timer */ pcan_set_leds(card, PCC_LED(c), PCC_LED_SLOW); pcan_start_led_timer(card); break; default: break; } iowrite8(v, priv->reg_base + port); }
static void pcan_write_canreg(const struct sja1000_priv *priv, int port, u8 v) { struct pcan_pccard *card = priv->priv; int c = (priv->reg_base - card->ioport_addr) / PCC_CHAN_SIZE; if (port == REG_MOD) switch (v) { case MOD_RM: pcan_set_leds(card, PCC_LED(c), PCC_LED_ON); break; case 0x00: pcan_set_leds(card, PCC_LED(c), PCC_LED_SLOW); pcan_start_led_timer(card); break; default: break; } iowrite8(v, priv->reg_base + port); }
static void pcan_set_leds(struct pcan_pccard *card, u8 led_mask, u8 state) { u8 ccr = card->ccr; int i; for (i = 0; i < card->chan_count; i++) if (led_mask & PCC_LED(i)) { /* clear corresponding led bits in ccr */ ccr &= ~PCC_CCR_LED_MASK_CHAN(i); /* then set new bits */ ccr |= PCC_CCR_LED_CHAN(state, i); } /* real write only if something has changed in ccr */ pcan_write_reg(card, PCC_CCR, ccr); }
static void pcan_set_leds(struct pcan_pccard *card, u8 led_mask, u8 state) { u8 ccr = card->ccr; int i; for (i = 0; i < card->chan_count; i++) if (led_mask & PCC_LED(i)) { ccr &= ~PCC_CCR_LED_MASK_CHAN(i); ccr |= PCC_CCR_LED_CHAN(state, i); } pcan_write_reg(card, PCC_CCR, ccr); }