aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ieee802154
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2014-07-02 18:20:45 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-08 00:29:24 -0400
commitc8ee0f56c833d70a03f06bf809089423dd190ee8 (patch)
tree45b0d6fbb1878d9b79d485458a4633c9a808b975 /drivers/net/ieee802154
parentf76014f770ff2d4e26c82e4e3a5b0928dee1969b (diff)
at86rf230: rework detect device handling
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 <alex.aring@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ieee802154')
-rw-r--r--drivers/net/ieee802154/at86rf230.c183
1 files changed, 76 insertions, 107 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index e3697038bd6d..7d96cd410edb 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 = {
410}; 410};
411 411
412static int 412static int
413__at86rf230_detect_device(struct spi_device *spi, u16 *man_id, u8 *part,
414 u8 *version)
415{
416 u8 data[4];
417 u8 *buf = kmalloc(2, GFP_KERNEL);
418 int status;
419 struct spi_message msg;
420 struct spi_transfer xfer = {
421 .len = 2,
422 .tx_buf = buf,
423 .rx_buf = buf,
424 };
425 u8 reg;
426
427 if (!buf)
428 return -ENOMEM;
429
430 for (reg = RG_PART_NUM; reg <= RG_MAN_ID_1; reg++) {
431 buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
432 buf[1] = 0xff;
433 dev_vdbg(&spi->dev, "buf[0] = %02x\n", buf[0]);
434 spi_message_init(&msg);
435 spi_message_add_tail(&xfer, &msg);
436
437 status = spi_sync(spi, &msg);
438 dev_vdbg(&spi->dev, "status = %d\n", status);
439 if (msg.status)
440 status = msg.status;
441
442 dev_vdbg(&spi->dev, "status = %d\n", status);
443 dev_vdbg(&spi->dev, "buf[0] = %02x\n", buf[0]);
444 dev_vdbg(&spi->dev, "buf[1] = %02x\n", buf[1]);
445
446 if (status == 0)
447 data[reg - RG_PART_NUM] = buf[1];
448 else
449 break;
450 }
451
452 if (status == 0) {
453 *part = data[0];
454 *version = data[1];
455 *man_id = (data[3] << 8) | data[2];
456 }
457
458 kfree(buf);
459
460 return status;
461}
462
463static int
464at86rf230_write_fbuf(struct at86rf230_local *lp, u8 *data, u8 len) 413at86rf230_write_fbuf(struct at86rf230_local *lp, u8 *data, u8 len)
465{ 414{
466 u8 *buf = lp->buf; 415 u8 *buf = lp->buf;
@@ -1080,18 +1029,87 @@ done:
1080 return pdata; 1029 return pdata;
1081} 1030}
1082 1031
1032static int
1033at86rf230_detect_device(struct at86rf230_local *lp)
1034{
1035 unsigned int part, version, val;
1036 u16 man_id = 0;
1037 const char *chip;
1038 int rc;
1039
1040 rc = __at86rf230_read(lp, RG_MAN_ID_0, &val);
1041 if (rc)
1042 return rc;
1043 man_id |= val;
1044
1045 rc = __at86rf230_read(lp, RG_MAN_ID_1, &val);
1046 if (rc)
1047 return rc;
1048 man_id |= (val << 8);
1049
1050 rc = __at86rf230_read(lp, RG_PART_NUM, &part);
1051 if (rc)
1052 return rc;
1053
1054 rc = __at86rf230_read(lp, RG_PART_NUM, &version);
1055 if (rc)
1056 return rc;
1057
1058 if (man_id != 0x001f) {
1059 dev_err(&lp->spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
1060 man_id >> 8, man_id & 0xFF);
1061 return -EINVAL;
1062 }
1063
1064 lp->part = part;
1065 lp->vers = version;
1066 lp->dev->extra_tx_headroom = 0;
1067 lp->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
1068 IEEE802154_HW_TXPOWER | IEEE802154_HW_CSMA;
1069
1070 switch (part) {
1071 case 2:
1072 chip = "at86rf230";
1073 rc = -ENOTSUPP;
1074 break;
1075 case 3:
1076 chip = "at86rf231";
1077 lp->dev->phy->channels_supported[0] = 0x7FFF800;
1078 break;
1079 case 7:
1080 chip = "at86rf212";
1081 if (version == 1) {
1082 lp->dev->flags |= IEEE802154_HW_LBT;
1083 lp->dev->phy->channels_supported[0] = 0x00007FF;
1084 lp->dev->phy->channels_supported[2] = 0x00007FF;
1085 } else {
1086 rc = -ENOTSUPP;
1087 }
1088 break;
1089 case 11:
1090 chip = "at86rf233";
1091 lp->dev->phy->channels_supported[0] = 0x7FFF800;
1092 break;
1093 default:
1094 chip = "unkown";
1095 rc = -ENOTSUPP;
1096 break;
1097 }
1098
1099 dev_info(&lp->spi->dev, "Detected %s chip version %d\n", chip, version);
1100
1101 return rc;
1102}
1103
1083static int at86rf230_probe(struct spi_device *spi) 1104static int at86rf230_probe(struct spi_device *spi)
1084{ 1105{
1085 struct at86rf230_platform_data *pdata; 1106 struct at86rf230_platform_data *pdata;
1086 struct ieee802154_dev *dev; 1107 struct ieee802154_dev *dev;
1087 struct at86rf230_local *lp; 1108 struct at86rf230_local *lp;
1088 u16 man_id = 0;
1089 u8 part = 0, version = 0;
1090 unsigned int status; 1109 unsigned int status;
1091 irq_handler_t irq_handler; 1110 irq_handler_t irq_handler;
1092 work_func_t irq_worker; 1111 work_func_t irq_worker;
1093 int rc, irq_type; 1112 int rc, irq_type;
1094 const char *chip;
1095 1113
1096 if (!spi->irq) { 1114 if (!spi->irq) {
1097 dev_err(&spi->dev, "no IRQ specified\n"); 1115 dev_err(&spi->dev, "no IRQ specified\n");
@@ -1133,54 +1151,8 @@ static int at86rf230_probe(struct spi_device *spi)
1133 1151
1134 lp = dev->priv; 1152 lp = dev->priv;
1135 lp->dev = dev; 1153 lp->dev = dev;
1136 lp->part = part;
1137 lp->vers = version;
1138
1139 lp->spi = spi; 1154 lp->spi = spi;
1140
1141 dev->parent = &spi->dev; 1155 dev->parent = &spi->dev;
1142 dev->extra_tx_headroom = 0;
1143 dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
1144 IEEE802154_HW_TXPOWER | IEEE802154_HW_CSMA;
1145
1146 rc = __at86rf230_detect_device(spi, &man_id, &part, &version);
1147 if (rc < 0)
1148 goto free_dev;
1149
1150 if (man_id != 0x001f) {
1151 dev_err(&spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
1152 man_id >> 8, man_id & 0xFF);
1153 return -EINVAL;
1154 }
1155
1156 switch (part) {
1157 case 2:
1158 chip = "at86rf230";
1159 rc = -ENOTSUPP;
1160 /* FIXME: should be easy to support; */
1161 break;
1162 case 3:
1163 chip = "at86rf231";
1164 break;
1165 case 7:
1166 chip = "at86rf212";
1167 if (version == 1)
1168 dev->flags |= IEEE802154_HW_LBT;
1169 else
1170 rc = -ENOTSUPP;
1171 break;
1172 case 11:
1173 chip = "at86rf233";
1174 break;
1175 default:
1176 chip = "UNKNOWN";
1177 rc = -ENOTSUPP;
1178 break;
1179 }
1180
1181 dev_info(&spi->dev, "Detected %s chip version %d\n", chip, version);
1182 if (rc < 0)
1183 goto free_dev;
1184 1156
1185 lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config); 1157 lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config);
1186 if (IS_ERR(lp->regmap)) { 1158 if (IS_ERR(lp->regmap)) {
@@ -1190,6 +1162,10 @@ static int at86rf230_probe(struct spi_device *spi)
1190 goto free_dev; 1162 goto free_dev;
1191 } 1163 }
1192 1164
1165 rc = at86rf230_detect_device(lp);
1166 if (rc < 0)
1167 goto free_dev;
1168
1193 irq_type = irq_get_trigger_type(spi->irq); 1169 irq_type = irq_get_trigger_type(spi->irq);
1194 if (!irq_type) 1170 if (!irq_type)
1195 irq_type = IRQF_TRIGGER_RISING; 1171 irq_type = IRQF_TRIGGER_RISING;
@@ -1208,13 +1184,6 @@ static int at86rf230_probe(struct spi_device *spi)
1208 1184
1209 spi_set_drvdata(spi, lp); 1185 spi_set_drvdata(spi, lp);
1210 1186
1211 if (is_rf212(lp)) {
1212 dev->phy->channels_supported[0] = 0x00007FF;
1213 dev->phy->channels_supported[2] = 0x00007FF;
1214 } else {
1215 dev->phy->channels_supported[0] = 0x7FFF800;
1216 }
1217
1218 rc = at86rf230_hw_init(lp); 1187 rc = at86rf230_hw_init(lp);
1219 if (rc) 1188 if (rc)
1220 goto err_hw_init; 1189 goto err_hw_init;