2010/10/18 Wolfgang Grandegger <[email protected]>:
> The plx_pci_check_sja1000() of the plx_pci driver is known to work. Why
> not just using that one, or something similar, at least:
> But these functions require the chip to be in the reset state.
Exactly. The plx_pci_check_sja1000 function only works if the chip is
in post hardware reset state. Admittedly, this is usually the case,
but...
The function I sent works always, no matter what state the chip is in:
reset or operating mode, BasicCAN or PeliCAN mode. However, because
the function only performs read tests (10 bits total (2 + 8)), it may
return false positives, if some other chip is in that region with
those exact same register space bits (very unlikely, I would say). We
could easily add some write tests to completely eliminate these false
positives. How about this function?
static int sja1000_probe_chip(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
u8 cdr, cmr;
/* CDR.4 always reads 0 (datasheet section 6.5.4) */
cdr = priv->read_reg(priv, REG_CDR);
if (cdr & 0x10)
return 0;
/* CMR reads 0x00 in PeliCAN (6.4.4) and 0xff in BasicCAN (6.3.4) */
cmr = priv->read_reg(priv, REG_CMR);
if (cdr & CDR_PELICAN) {
if (cmr != 0x00)
return 0;
} else {
if (cmr != 0xff)
return 0;
}
/* Now make sure it is in reset mode, to be able to toggle CAN mode */
priv->write_reg(priv, REG_MOD, MOD_RM);
/* Toggle CAN mode (BasicCAN to PeliCAN, or PeliCAN to BasicCAN) */
cdr ^= CDR_PELICAN;
priv->write_reg(priv, REG_CDR, cdr);
/* And see if the CMR register bits also toggle */
cmr = priv->read_reg(priv, REG_CMR);
if (cdr & CDR_PELICAN) {
if (cmr != 0x00)
return 0;
} else {
if (cmr != 0xff)
return 0;
}
return 1;
}
Regards,
--
Andre B. Oliveira
_______________________________________________
Socketcan-core mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core