diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index e369703..7d96cd4 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -410,57 +410,6 @@ static struct regmap_config at86rf230_regmap_spi_config = {
 };
 
 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)
 {
 	u8 *buf = lp->buf;
@@ -1080,18 +1029,87 @@ done:
 	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");
@@ -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)) {
@@ -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;
@@ -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;
