Skip to content

Commit

Permalink
at86rf230: rework detect device handling
Browse files Browse the repository at this point in the history
This patch drops the current lowlevel spi calls for the detect device
function instead we handle this via regmap. Also put the detection of
in a seperate function and set all device specific attributes while detection.

Signed-off-by: Alexander Aring <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
alexaring authored and davem330 committed Jul 8, 2014
1 parent f76014f commit c8ee0f5
Showing 1 changed file with 76 additions and 107 deletions.
183 changes: 76 additions & 107 deletions drivers/net/ieee802154/at86rf230.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,57 +409,6 @@ static struct regmap_config at86rf230_regmap_spi_config = {
.precious_reg = at86rf230_reg_precious,
};

static int
__at86rf230_detect_device(struct spi_device *spi, u16 *man_id, u8 *part,
u8 *version)
{
u8 data[4];
u8 *buf = kmalloc(2, GFP_KERNEL);
int status;
struct spi_message msg;
struct spi_transfer xfer = {
.len = 2,
.tx_buf = buf,
.rx_buf = buf,
};
u8 reg;

if (!buf)
return -ENOMEM;

for (reg = RG_PART_NUM; reg <= RG_MAN_ID_1; reg++) {
buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
buf[1] = 0xff;
dev_vdbg(&spi->dev, "buf[0] = %02x\n", buf[0]);
spi_message_init(&msg);
spi_message_add_tail(&xfer, &msg);

status = spi_sync(spi, &msg);
dev_vdbg(&spi->dev, "status = %d\n", status);
if (msg.status)
status = msg.status;

dev_vdbg(&spi->dev, "status = %d\n", status);
dev_vdbg(&spi->dev, "buf[0] = %02x\n", buf[0]);
dev_vdbg(&spi->dev, "buf[1] = %02x\n", buf[1]);

if (status == 0)
data[reg - RG_PART_NUM] = buf[1];
else
break;
}

if (status == 0) {
*part = data[0];
*version = data[1];
*man_id = (data[3] << 8) | data[2];
}

kfree(buf);

return status;
}

static int
at86rf230_write_fbuf(struct at86rf230_local *lp, u8 *data, u8 len)
{
Expand Down Expand Up @@ -1080,18 +1029,87 @@ at86rf230_get_pdata(struct spi_device *spi)
return pdata;
}

static int
at86rf230_detect_device(struct at86rf230_local *lp)
{
unsigned int part, version, val;
u16 man_id = 0;
const char *chip;
int rc;

rc = __at86rf230_read(lp, RG_MAN_ID_0, &val);
if (rc)
return rc;
man_id |= val;

rc = __at86rf230_read(lp, RG_MAN_ID_1, &val);
if (rc)
return rc;
man_id |= (val << 8);

rc = __at86rf230_read(lp, RG_PART_NUM, &part);
if (rc)
return rc;

rc = __at86rf230_read(lp, RG_PART_NUM, &version);
if (rc)
return rc;

if (man_id != 0x001f) {
dev_err(&lp->spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
man_id >> 8, man_id & 0xFF);
return -EINVAL;
}

lp->part = part;
lp->vers = version;
lp->dev->extra_tx_headroom = 0;
lp->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
IEEE802154_HW_TXPOWER | IEEE802154_HW_CSMA;

switch (part) {
case 2:
chip = "at86rf230";
rc = -ENOTSUPP;
break;
case 3:
chip = "at86rf231";
lp->dev->phy->channels_supported[0] = 0x7FFF800;
break;
case 7:
chip = "at86rf212";
if (version == 1) {
lp->dev->flags |= IEEE802154_HW_LBT;
lp->dev->phy->channels_supported[0] = 0x00007FF;
lp->dev->phy->channels_supported[2] = 0x00007FF;
} else {
rc = -ENOTSUPP;
}
break;
case 11:
chip = "at86rf233";
lp->dev->phy->channels_supported[0] = 0x7FFF800;
break;
default:
chip = "unkown";
rc = -ENOTSUPP;
break;
}

dev_info(&lp->spi->dev, "Detected %s chip version %d\n", chip, version);

return rc;
}

static int at86rf230_probe(struct spi_device *spi)
{
struct at86rf230_platform_data *pdata;
struct ieee802154_dev *dev;
struct at86rf230_local *lp;
u16 man_id = 0;
u8 part = 0, version = 0;
unsigned int status;
irq_handler_t irq_handler;
work_func_t irq_worker;
int rc, irq_type;
const char *chip;

if (!spi->irq) {
dev_err(&spi->dev, "no IRQ specified\n");
Expand Down Expand Up @@ -1133,54 +1151,8 @@ static int at86rf230_probe(struct spi_device *spi)

lp = dev->priv;
lp->dev = dev;
lp->part = part;
lp->vers = version;

lp->spi = spi;

dev->parent = &spi->dev;
dev->extra_tx_headroom = 0;
dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
IEEE802154_HW_TXPOWER | IEEE802154_HW_CSMA;

rc = __at86rf230_detect_device(spi, &man_id, &part, &version);
if (rc < 0)
goto free_dev;

if (man_id != 0x001f) {
dev_err(&spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
man_id >> 8, man_id & 0xFF);
return -EINVAL;
}

switch (part) {
case 2:
chip = "at86rf230";
rc = -ENOTSUPP;
/* FIXME: should be easy to support; */
break;
case 3:
chip = "at86rf231";
break;
case 7:
chip = "at86rf212";
if (version == 1)
dev->flags |= IEEE802154_HW_LBT;
else
rc = -ENOTSUPP;
break;
case 11:
chip = "at86rf233";
break;
default:
chip = "UNKNOWN";
rc = -ENOTSUPP;
break;
}

dev_info(&spi->dev, "Detected %s chip version %d\n", chip, version);
if (rc < 0)
goto free_dev;

lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config);
if (IS_ERR(lp->regmap)) {
Expand All @@ -1190,6 +1162,10 @@ static int at86rf230_probe(struct spi_device *spi)
goto free_dev;
}

rc = at86rf230_detect_device(lp);
if (rc < 0)
goto free_dev;

irq_type = irq_get_trigger_type(spi->irq);
if (!irq_type)
irq_type = IRQF_TRIGGER_RISING;
Expand All @@ -1208,13 +1184,6 @@ static int at86rf230_probe(struct spi_device *spi)

spi_set_drvdata(spi, lp);

if (is_rf212(lp)) {
dev->phy->channels_supported[0] = 0x00007FF;
dev->phy->channels_supported[2] = 0x00007FF;
} else {
dev->phy->channels_supported[0] = 0x7FFF800;
}

rc = at86rf230_hw_init(lp);
if (rc)
goto err_hw_init;
Expand Down

0 comments on commit c8ee0f5

Please sign in to comment.