mrf24j40.c 32.8 KB
Newer Older
A
Alan Ott 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Driver for Microchip MRF24J40 802.15.4 Wireless-PAN Networking controller
 *
 * Copyright (C) 2012 Alan Ott <alan@signal11.us>
 *                    Signal 11 Software
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/spi/spi.h>
#include <linux/interrupt.h>
#include <linux/module.h>
A
Alexander Aring 已提交
21
#include <linux/regmap.h>
22
#include <linux/ieee802154.h>
23
#include <net/cfg802154.h>
A
Alan Ott 已提交
24 25 26
#include <net/mac802154.h>

/* MRF24J40 Short Address Registers */
27 28 29 30 31 32
#define REG_RXMCR	0x00  /* Receive MAC control */
#define REG_PANIDL	0x01  /* PAN ID (low) */
#define REG_PANIDH	0x02  /* PAN ID (high) */
#define REG_SADRL	0x03  /* Short address (low) */
#define REG_SADRH	0x04  /* Short address (high) */
#define REG_EADR0	0x05  /* Long address (low) (high is EADR7) */
33 34 35 36 37 38 39 40 41
#define REG_EADR1	0x06
#define REG_EADR2	0x07
#define REG_EADR3	0x08
#define REG_EADR4	0x09
#define REG_EADR5	0x0A
#define REG_EADR6	0x0B
#define REG_EADR7	0x0C
#define REG_RXFLUSH	0x0D
#define REG_ORDER	0x10
42
#define REG_TXMCR	0x11  /* Transmit MAC control */
43 44 45 46
#define REG_ACKTMOUT	0x12
#define REG_ESLOTG1	0x13
#define REG_SYMTICKL	0x14
#define REG_SYMTICKH	0x15
47 48 49
#define REG_PACON0	0x16  /* Power Amplifier Control */
#define REG_PACON1	0x17  /* Power Amplifier Control */
#define REG_PACON2	0x18  /* Power Amplifier Control */
50
#define REG_TXBCON0	0x1A
51
#define REG_TXNCON	0x1B  /* Transmit Normal FIFO Control */
52 53 54 55 56 57 58 59
#define REG_TXG1CON	0x1C
#define REG_TXG2CON	0x1D
#define REG_ESLOTG23	0x1E
#define REG_ESLOTG45	0x1F
#define REG_ESLOTG67	0x20
#define REG_TXPEND	0x21
#define REG_WAKECON	0x22
#define REG_FROMOFFSET	0x23
60
#define REG_TXSTAT	0x24  /* TX MAC Status Register */
61 62 63 64 65
#define REG_TXBCON1	0x25
#define REG_GATECLK	0x26
#define REG_TXTIME	0x27
#define REG_HSYMTMRL	0x28
#define REG_HSYMTMRH	0x29
66
#define REG_SOFTRST	0x2A  /* Soft Reset */
67 68
#define REG_SECCON0	0x2C
#define REG_SECCON1	0x2D
69
#define REG_TXSTBL	0x2E  /* TX Stabilization */
70
#define REG_RXSR	0x30
71 72 73 74
#define REG_INTSTAT	0x31  /* Interrupt Status */
#define REG_INTCON	0x32  /* Interrupt Control */
#define REG_GPIO	0x33  /* GPIO */
#define REG_TRISGPIO	0x34  /* GPIO direction */
75
#define REG_SLPACK	0x35
76
#define REG_RFCTL	0x36  /* RF Control Mode Register */
77 78
#define REG_SECCR2	0x37
#define REG_BBREG0	0x38
79 80
#define REG_BBREG1	0x39  /* Baseband Registers */
#define REG_BBREG2	0x3A  /* */
81 82
#define REG_BBREG3	0x3B
#define REG_BBREG4	0x3C
83 84
#define REG_BBREG6	0x3E  /* */
#define REG_CCAEDTH	0x3F  /* Energy Detection Threshold */
A
Alan Ott 已提交
85 86

/* MRF24J40 Long Address Registers */
87 88 89 90 91 92 93 94
#define REG_RFCON0	0x200  /* RF Control Registers */
#define REG_RFCON1	0x201
#define REG_RFCON2	0x202
#define REG_RFCON3	0x203
#define REG_RFCON5	0x205
#define REG_RFCON6	0x206
#define REG_RFCON7	0x207
#define REG_RFCON8	0x208
95 96 97 98
#define REG_SLPCAL0	0x209
#define REG_SLPCAL1	0x20A
#define REG_SLPCAL2	0x20B
#define REG_RFSTATE	0x20F
99 100 101 102 103
#define REG_RSSI	0x210
#define REG_SLPCON0	0x211  /* Sleep Clock Control Registers */
#define REG_SLPCON1	0x220
#define REG_WAKETIMEL	0x222  /* Wake-up Time Match Value Low */
#define REG_WAKETIMEH	0x223  /* Wake-up Time Match Value High */
104 105 106 107 108 109
#define REG_REMCNTL	0x224
#define REG_REMCNTH	0x225
#define REG_MAINCNT0	0x226
#define REG_MAINCNT1	0x227
#define REG_MAINCNT2	0x228
#define REG_MAINCNT3	0x229
110
#define REG_TESTMODE	0x22F  /* Test mode */
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
#define REG_ASSOEAR0	0x230
#define REG_ASSOEAR1	0x231
#define REG_ASSOEAR2	0x232
#define REG_ASSOEAR3	0x233
#define REG_ASSOEAR4	0x234
#define REG_ASSOEAR5	0x235
#define REG_ASSOEAR6	0x236
#define REG_ASSOEAR7	0x237
#define REG_ASSOSAR0	0x238
#define REG_ASSOSAR1	0x239
#define REG_UNONCE0	0x240
#define REG_UNONCE1	0x241
#define REG_UNONCE2	0x242
#define REG_UNONCE3	0x243
#define REG_UNONCE4	0x244
#define REG_UNONCE5	0x245
#define REG_UNONCE6	0x246
#define REG_UNONCE7	0x247
#define REG_UNONCE8	0x248
#define REG_UNONCE9	0x249
#define REG_UNONCE10	0x24A
#define REG_UNONCE11	0x24B
#define REG_UNONCE12	0x24C
134
#define REG_RX_FIFO	0x300  /* Receive FIFO */
A
Alan Ott 已提交
135 136 137 138 139 140 141 142 143 144 145

/* Device configuration: Only channels 11-26 on page 0 are supported. */
#define MRF24J40_CHAN_MIN 11
#define MRF24J40_CHAN_MAX 26
#define CHANNEL_MASK (((u32)1 << (MRF24J40_CHAN_MAX + 1)) \
		      - ((u32)1 << MRF24J40_CHAN_MIN))

#define TX_FIFO_SIZE 128 /* From datasheet */
#define RX_FIFO_SIZE 144 /* From datasheet */
#define SET_CHANNEL_DELAY_US 192 /* From datasheet */

146 147
enum mrf24j40_modules { MRF24J40, MRF24J40MA, MRF24J40MC };

A
Alan Ott 已提交
148 149 150
/* Device Private Data */
struct mrf24j40 {
	struct spi_device *spi;
151
	struct ieee802154_hw *hw;
A
Alan Ott 已提交
152

A
Alexander Aring 已提交
153 154
	struct regmap *regmap_short;
	struct regmap *regmap_long;
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169

	/* for writing txfifo */
	struct spi_message tx_msg;
	u8 tx_hdr_buf[2];
	struct spi_transfer tx_hdr_trx;
	u8 tx_len_buf[2];
	struct spi_transfer tx_len_trx;
	struct spi_transfer tx_buf_trx;
	struct sk_buff *tx_skb;

	/* post transmit message to send frame out  */
	struct spi_message tx_post_msg;
	u8 tx_post_buf[2];
	struct spi_transfer tx_post_trx;

170 171 172 173 174 175 176 177 178 179 180 181 182 183
	/* for protect/unprotect/read length rxfifo */
	struct spi_message rx_msg;
	u8 rx_buf[3];
	struct spi_transfer rx_trx;

	/* receive handling */
	struct spi_message rx_buf_msg;
	u8 rx_addr_buf[2];
	struct spi_transfer rx_addr_trx;
	u8 rx_lqi_buf[2];
	struct spi_transfer rx_lqi_trx;
	u8 rx_fifo_buf[RX_FIFO_SIZE];
	struct spi_transfer rx_fifo_buf_trx;

184 185 186 187
	/* isr handling for reading intstat */
	struct spi_message irq_msg;
	u8 irq_buf[2];
	struct spi_transfer irq_trx;
A
Alan Ott 已提交
188 189
};

A
Alexander Aring 已提交
190 191 192 193 194 195 196 197 198
/* regmap information for short address register access */
#define MRF24J40_SHORT_WRITE	0x01
#define MRF24J40_SHORT_READ	0x00
#define MRF24J40_SHORT_NUMREGS	0x3F

/* regmap information for long address register access */
#define MRF24J40_LONG_ACCESS	0x80
#define MRF24J40_LONG_NUMREGS	0x38F

A
Alan Ott 已提交
199 200 201 202 203 204
/* Read/Write SPI Commands for Short and Long Address registers. */
#define MRF24J40_READSHORT(reg) ((reg) << 1)
#define MRF24J40_WRITESHORT(reg) ((reg) << 1 | 1)
#define MRF24J40_READLONG(reg) (1 << 15 | (reg) << 5)
#define MRF24J40_WRITELONG(reg) (1 << 15 | (reg) << 5 | 1 << 4)

205 206
/* The datasheet indicates the theoretical maximum for SCK to be 10MHz */
#define MAX_SPI_SPEED_HZ 10000000
A
Alan Ott 已提交
207 208 209

#define printdev(X) (&X->spi->dev)

A
Alexander Aring 已提交
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
static bool
mrf24j40_short_reg_writeable(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case REG_RXMCR:
	case REG_PANIDL:
	case REG_PANIDH:
	case REG_SADRL:
	case REG_SADRH:
	case REG_EADR0:
	case REG_EADR1:
	case REG_EADR2:
	case REG_EADR3:
	case REG_EADR4:
	case REG_EADR5:
	case REG_EADR6:
	case REG_EADR7:
	case REG_RXFLUSH:
	case REG_ORDER:
	case REG_TXMCR:
	case REG_ACKTMOUT:
	case REG_ESLOTG1:
	case REG_SYMTICKL:
	case REG_SYMTICKH:
	case REG_PACON0:
	case REG_PACON1:
	case REG_PACON2:
	case REG_TXBCON0:
	case REG_TXNCON:
	case REG_TXG1CON:
	case REG_TXG2CON:
	case REG_ESLOTG23:
	case REG_ESLOTG45:
	case REG_ESLOTG67:
	case REG_TXPEND:
	case REG_WAKECON:
	case REG_FROMOFFSET:
	case REG_TXBCON1:
	case REG_GATECLK:
	case REG_TXTIME:
	case REG_HSYMTMRL:
	case REG_HSYMTMRH:
	case REG_SOFTRST:
	case REG_SECCON0:
	case REG_SECCON1:
	case REG_TXSTBL:
	case REG_RXSR:
	case REG_INTCON:
	case REG_TRISGPIO:
	case REG_GPIO:
	case REG_RFCTL:
	case REG_SLPACK:
	case REG_BBREG0:
	case REG_BBREG1:
	case REG_BBREG2:
	case REG_BBREG3:
	case REG_BBREG4:
	case REG_BBREG6:
	case REG_CCAEDTH:
		return true;
	default:
		return false;
	}
}

static bool
mrf24j40_short_reg_readable(struct device *dev, unsigned int reg)
{
	bool rc;

	/* all writeable are also readable */
	rc = mrf24j40_short_reg_writeable(dev, reg);
	if (rc)
		return rc;

	/* readonly regs */
	switch (reg) {
	case REG_TXSTAT:
	case REG_INTSTAT:
		return true;
	default:
		return false;
	}
}

static bool
mrf24j40_short_reg_volatile(struct device *dev, unsigned int reg)
{
	/* can be changed during runtime */
	switch (reg) {
	case REG_TXSTAT:
	case REG_INTSTAT:
	case REG_RXFLUSH:
	case REG_TXNCON:
	case REG_SOFTRST:
	case REG_RFCTL:
	case REG_TXBCON0:
	case REG_TXG1CON:
	case REG_TXG2CON:
	case REG_TXBCON1:
	case REG_SECCON0:
	case REG_RXSR:
	case REG_SLPACK:
	case REG_SECCR2:
	case REG_BBREG6:
	/* use them in spi_async and regmap so it's volatile */
	case REG_BBREG1:
		return true;
	default:
		return false;
	}
}

static bool
mrf24j40_short_reg_precious(struct device *dev, unsigned int reg)
{
	/* don't clear irq line on read */
	switch (reg) {
	case REG_INTSTAT:
		return true;
	default:
		return false;
	}
}

static const struct regmap_config mrf24j40_short_regmap = {
	.name = "mrf24j40_short",
	.reg_bits = 7,
	.val_bits = 8,
	.pad_bits = 1,
	.write_flag_mask = MRF24J40_SHORT_WRITE,
	.read_flag_mask = MRF24J40_SHORT_READ,
	.cache_type = REGCACHE_RBTREE,
	.max_register = MRF24J40_SHORT_NUMREGS,
	.writeable_reg = mrf24j40_short_reg_writeable,
	.readable_reg = mrf24j40_short_reg_readable,
	.volatile_reg = mrf24j40_short_reg_volatile,
	.precious_reg = mrf24j40_short_reg_precious,
};

static bool
mrf24j40_long_reg_writeable(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case REG_RFCON0:
	case REG_RFCON1:
	case REG_RFCON2:
	case REG_RFCON3:
	case REG_RFCON5:
	case REG_RFCON6:
	case REG_RFCON7:
	case REG_RFCON8:
	case REG_SLPCAL2:
	case REG_SLPCON0:
	case REG_SLPCON1:
	case REG_WAKETIMEL:
	case REG_WAKETIMEH:
	case REG_REMCNTL:
	case REG_REMCNTH:
	case REG_MAINCNT0:
	case REG_MAINCNT1:
	case REG_MAINCNT2:
	case REG_MAINCNT3:
	case REG_TESTMODE:
	case REG_ASSOEAR0:
	case REG_ASSOEAR1:
	case REG_ASSOEAR2:
	case REG_ASSOEAR3:
	case REG_ASSOEAR4:
	case REG_ASSOEAR5:
	case REG_ASSOEAR6:
	case REG_ASSOEAR7:
	case REG_ASSOSAR0:
	case REG_ASSOSAR1:
	case REG_UNONCE0:
	case REG_UNONCE1:
	case REG_UNONCE2:
	case REG_UNONCE3:
	case REG_UNONCE4:
	case REG_UNONCE5:
	case REG_UNONCE6:
	case REG_UNONCE7:
	case REG_UNONCE8:
	case REG_UNONCE9:
	case REG_UNONCE10:
	case REG_UNONCE11:
	case REG_UNONCE12:
		return true;
	default:
		return false;
	}
}

static bool
mrf24j40_long_reg_readable(struct device *dev, unsigned int reg)
{
	bool rc;

	/* all writeable are also readable */
	rc = mrf24j40_long_reg_writeable(dev, reg);
	if (rc)
		return rc;

	/* readonly regs */
	switch (reg) {
	case REG_SLPCAL0:
	case REG_SLPCAL1:
	case REG_RFSTATE:
	case REG_RSSI:
		return true;
	default:
		return false;
	}
}

static bool
mrf24j40_long_reg_volatile(struct device *dev, unsigned int reg)
{
	/* can be changed during runtime */
	switch (reg) {
	case REG_SLPCAL0:
	case REG_SLPCAL1:
	case REG_SLPCAL2:
	case REG_RFSTATE:
	case REG_RSSI:
	case REG_MAINCNT3:
		return true;
	default:
		return false;
	}
}

static const struct regmap_config mrf24j40_long_regmap = {
	.name = "mrf24j40_long",
	.reg_bits = 11,
	.val_bits = 8,
	.pad_bits = 5,
	.write_flag_mask = MRF24J40_LONG_ACCESS,
	.read_flag_mask = MRF24J40_LONG_ACCESS,
	.cache_type = REGCACHE_RBTREE,
	.max_register = MRF24J40_LONG_NUMREGS,
	.writeable_reg = mrf24j40_long_reg_writeable,
	.readable_reg = mrf24j40_long_reg_readable,
	.volatile_reg = mrf24j40_long_reg_volatile,
};

static int mrf24j40_long_regmap_write(void *context, const void *data,
				      size_t count)
{
	struct spi_device *spi = context;
	u8 buf[3];

	if (count > 3)
		return -EINVAL;

	/* regmap supports read/write mask only in frist byte
	 * long write access need to set the 12th bit, so we
	 * make special handling for write.
	 */
	memcpy(buf, data, count);
	buf[1] |= (1 << 4);

	return spi_write(spi, buf, count);
}

static int
mrf24j40_long_regmap_read(void *context, const void *reg, size_t reg_size,
			  void *val, size_t val_size)
{
	struct spi_device *spi = context;

	return spi_write_then_read(spi, reg, reg_size, val, val_size);
}

static const struct regmap_bus mrf24j40_long_regmap_bus = {
	.write = mrf24j40_long_regmap_write,
	.read = mrf24j40_long_regmap_read,
	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
	.val_format_endian_default = REGMAP_ENDIAN_BIG,
};

491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
static void write_tx_buf_complete(void *context)
{
	struct mrf24j40 *devrec = context;
	__le16 fc = ieee802154_get_fc_from_skb(devrec->tx_skb);
	u8 val = 0x01;
	int ret;

	if (ieee802154_is_ackreq(fc))
		val |= 0x04;

	devrec->tx_post_msg.complete = NULL;
	devrec->tx_post_buf[0] = MRF24J40_WRITESHORT(REG_TXNCON);
	devrec->tx_post_buf[1] = val;

	ret = spi_async(devrec->spi, &devrec->tx_post_msg);
	if (ret)
		dev_err(printdev(devrec), "SPI write Failed for transmit buf\n");
}

A
Alan Ott 已提交
510 511 512 513 514 515 516
/* This function relies on an undocumented write method. Once a write command
   and address is set, as many bytes of data as desired can be clocked into
   the device. The datasheet only shows setting one byte at a time. */
static int write_tx_buf(struct mrf24j40 *devrec, u16 reg,
			const u8 *data, size_t length)
{
	u16 cmd;
517
	int ret;
A
Alan Ott 已提交
518 519 520 521 522 523 524 525

	/* Range check the length. 2 bytes are used for the length fields.*/
	if (length > TX_FIFO_SIZE-2) {
		dev_err(printdev(devrec), "write_tx_buf() was passed too large a buffer. Performing short write.\n");
		length = TX_FIFO_SIZE-2;
	}

	cmd = MRF24J40_WRITELONG(reg);
526 527 528 529 530 531 532 533
	devrec->tx_hdr_buf[0] = cmd >> 8 & 0xff;
	devrec->tx_hdr_buf[1] = cmd & 0xff;
	devrec->tx_len_buf[0] = 0x0; /* Header Length. Set to 0 for now. TODO */
	devrec->tx_len_buf[1] = length; /* Total length */
	devrec->tx_buf_trx.tx_buf = data;
	devrec->tx_buf_trx.len = length;

	ret = spi_async(devrec->spi, &devrec->tx_msg);
A
Alan Ott 已提交
534 535 536 537 538 539
	if (ret)
		dev_err(printdev(devrec), "SPI write Failed for TX buf\n");

	return ret;
}

540 541 542 543 544 545 546 547 548 549
static int mrf24j40_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
{
	struct mrf24j40 *devrec = hw->priv;

	dev_dbg(printdev(devrec), "tx packet of %d bytes\n", skb->len);
	devrec->tx_skb = skb;

	return write_tx_buf(devrec, 0x000, skb->data, skb->len);
}

550
static int mrf24j40_ed(struct ieee802154_hw *hw, u8 *level)
A
Alan Ott 已提交
551 552
{
	/* TODO: */
553
	pr_warn("mrf24j40: ed not implemented\n");
A
Alan Ott 已提交
554 555 556 557
	*level = 0;
	return 0;
}

558
static int mrf24j40_start(struct ieee802154_hw *hw)
A
Alan Ott 已提交
559
{
560
	struct mrf24j40 *devrec = hw->priv;
A
Alan Ott 已提交
561 562 563

	dev_dbg(printdev(devrec), "start\n");

564 565 566
	/* Clear TXNIE and RXIE. Enable interrupts */
	return regmap_update_bits(devrec->regmap_short, REG_INTCON,
				  0x01 | 0x08, 0x00);
A
Alan Ott 已提交
567 568
}

569
static void mrf24j40_stop(struct ieee802154_hw *hw)
A
Alan Ott 已提交
570
{
571
	struct mrf24j40 *devrec = hw->priv;
572

A
Alan Ott 已提交
573 574
	dev_dbg(printdev(devrec), "stop\n");

575 576 577
	/* Set TXNIE and RXIE. Disable Interrupts */
	regmap_update_bits(devrec->regmap_short, REG_INTCON, 0x01 | 0x08,
			   0x01 | 0x08);
A
Alan Ott 已提交
578 579
}

580
static int mrf24j40_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
A
Alan Ott 已提交
581
{
582
	struct mrf24j40 *devrec = hw->priv;
A
Alan Ott 已提交
583 584 585 586 587 588 589 590 591 592 593
	u8 val;
	int ret;

	dev_dbg(printdev(devrec), "Set Channel %d\n", channel);

	WARN_ON(page != 0);
	WARN_ON(channel < MRF24J40_CHAN_MIN);
	WARN_ON(channel > MRF24J40_CHAN_MAX);

	/* Set Channel TODO */
	val = (channel-11) << 4 | 0x03;
594 595 596
	ret = regmap_update_bits(devrec->regmap_long, REG_RFCON0, 0xf0, val);
	if (ret)
		return ret;
A
Alan Ott 已提交
597 598

	/* RF Reset */
599
	ret = regmap_update_bits(devrec->regmap_short, REG_RFCTL, 0x04, 0x04);
A
Alan Ott 已提交
600 601 602
	if (ret)
		return ret;

603 604 605
	ret = regmap_update_bits(devrec->regmap_short, REG_RFCTL, 0x04, 0x00);
	if (!ret)
		udelay(SET_CHANNEL_DELAY_US); /* per datasheet */
A
Alan Ott 已提交
606

607
	return ret;
A
Alan Ott 已提交
608 609
}

610
static int mrf24j40_filter(struct ieee802154_hw *hw,
A
Alan Ott 已提交
611 612 613
			   struct ieee802154_hw_addr_filt *filt,
			   unsigned long changed)
{
614
	struct mrf24j40 *devrec = hw->priv;
A
Alan Ott 已提交
615 616 617

	dev_dbg(printdev(devrec), "filter\n");

618
	if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
A
Alan Ott 已提交
619 620
		/* Short Addr */
		u8 addrh, addrl;
621

622 623
		addrh = le16_to_cpu(filt->short_addr) >> 8 & 0xff;
		addrl = le16_to_cpu(filt->short_addr) & 0xff;
A
Alan Ott 已提交
624

625 626
		regmap_write(devrec->regmap_short, REG_SADRH, addrh);
		regmap_write(devrec->regmap_short, REG_SADRL, addrl);
A
Alan Ott 已提交
627 628 629 630
		dev_dbg(printdev(devrec),
			"Set short addr to %04hx\n", filt->short_addr);
	}

631
	if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
A
Alan Ott 已提交
632
		/* Device Address */
633 634 635
		u8 i, addr[8];

		memcpy(addr, &filt->ieee_addr, 8);
A
Alan Ott 已提交
636
		for (i = 0; i < 8; i++)
637 638
			regmap_write(devrec->regmap_short, REG_EADR0 + i,
				     addr[i]);
A
Alan Ott 已提交
639 640

#ifdef DEBUG
641
		pr_debug("Set long addr to: ");
A
Alan Ott 已提交
642
		for (i = 0; i < 8; i++)
643 644
			pr_debug("%02hhx ", addr[7 - i]);
		pr_debug("\n");
A
Alan Ott 已提交
645 646 647
#endif
	}

648
	if (changed & IEEE802154_AFILT_PANID_CHANGED) {
A
Alan Ott 已提交
649 650
		/* PAN ID */
		u8 panidl, panidh;
651

652 653
		panidh = le16_to_cpu(filt->pan_id) >> 8 & 0xff;
		panidl = le16_to_cpu(filt->pan_id) & 0xff;
654 655
		regmap_write(devrec->regmap_short, REG_PANIDH, panidh);
		regmap_write(devrec->regmap_short, REG_PANIDL, panidl);
A
Alan Ott 已提交
656 657 658 659

		dev_dbg(printdev(devrec), "Set PANID to %04hx\n", filt->pan_id);
	}

660
	if (changed & IEEE802154_AFILT_PANC_CHANGED) {
A
Alan Ott 已提交
661 662 663 664 665
		/* Pan Coordinator */
		u8 val;
		int ret;

		if (filt->pan_coord)
666
			val = 0x8;
A
Alan Ott 已提交
667
		else
668 669 670 671 672
			val = 0x0;
		ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR, 0x8,
					 val);
		if (ret)
			return ret;
A
Alan Ott 已提交
673 674 675 676 677 678

		/* REG_SLOTTED is maintained as default (unslotted/CSMA-CA).
		 * REG_ORDER is maintained as default (no beacon/superframe).
		 */

		dev_dbg(printdev(devrec), "Set Pan Coord to %s\n",
679
			filt->pan_coord ? "on" : "off");
A
Alan Ott 已提交
680 681 682 683 684
	}

	return 0;
}

685
static void mrf24j40_handle_rx_read_buf_unlock(struct mrf24j40 *devrec)
A
Alan Ott 已提交
686
{
687
	int ret;
A
Alan Ott 已提交
688

689 690 691 692 693
	/* Turn back on reception of packets off the air. */
	devrec->rx_msg.complete = NULL;
	devrec->rx_buf[0] = MRF24J40_WRITESHORT(REG_BBREG1);
	devrec->rx_buf[1] = 0x00; /* CLR RXDECINV */
	ret = spi_async(devrec->spi, &devrec->rx_msg);
A
Alan Ott 已提交
694
	if (ret)
695 696
		dev_err(printdev(devrec), "failed to unlock rx buffer\n");
}
A
Alan Ott 已提交
697

698 699 700 701 702 703 704 705 706 707 708
static void mrf24j40_handle_rx_read_buf_complete(void *context)
{
	struct mrf24j40 *devrec = context;
	u8 len = devrec->rx_buf[2];
	u8 rx_local_buf[RX_FIFO_SIZE];
	struct sk_buff *skb;

	memcpy(rx_local_buf, devrec->rx_fifo_buf, len);
	mrf24j40_handle_rx_read_buf_unlock(devrec);

	skb = dev_alloc_skb(IEEE802154_MTU);
A
Alan Ott 已提交
709
	if (!skb) {
710 711
		dev_err(printdev(devrec), "failed to allocate skb\n");
		return;
A
Alan Ott 已提交
712 713
	}

714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
	memcpy(skb_put(skb, len), rx_local_buf, len);
	ieee802154_rx_irqsafe(devrec->hw, skb, 0);

#ifdef DEBUG
	 print_hex_dump(KERN_DEBUG, "mrf24j40 rx: ", DUMP_PREFIX_OFFSET, 16, 1,
			rx_local_buf, len, 0);
	 pr_debug("mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n",
		  devrec->rx_lqi_buf[0], devrec->rx_lqi_buf[1]);
#endif
}

static void mrf24j40_handle_rx_read_buf(void *context)
{
	struct mrf24j40 *devrec = context;
	u16 cmd;
	int ret;

	/* if length is invalid read the full MTU */
	if (!ieee802154_is_valid_psdu_len(devrec->rx_buf[2]))
		devrec->rx_buf[2] = IEEE802154_MTU;

	cmd = MRF24J40_READLONG(REG_RX_FIFO + 1);
	devrec->rx_addr_buf[0] = cmd >> 8 & 0xff;
	devrec->rx_addr_buf[1] = cmd & 0xff;
	devrec->rx_fifo_buf_trx.len = devrec->rx_buf[2];
	ret = spi_async(devrec->spi, &devrec->rx_buf_msg);
	if (ret) {
		dev_err(printdev(devrec), "failed to read rx buffer\n");
		mrf24j40_handle_rx_read_buf_unlock(devrec);
A
Alan Ott 已提交
743
	}
744
}
A
Alan Ott 已提交
745

746 747 748 749 750
static void mrf24j40_handle_rx_read_len(void *context)
{
	struct mrf24j40 *devrec = context;
	u16 cmd;
	int ret;
A
Alan Ott 已提交
751

752 753 754 755 756 757
	/* read the length of received frame */
	devrec->rx_msg.complete = mrf24j40_handle_rx_read_buf;
	devrec->rx_trx.len = 3;
	cmd = MRF24J40_READLONG(REG_RX_FIFO);
	devrec->rx_buf[0] = cmd >> 8 & 0xff;
	devrec->rx_buf[1] = cmd & 0xff;
A
Alan Ott 已提交
758

759 760 761 762 763 764
	ret = spi_async(devrec->spi, &devrec->rx_msg);
	if (ret) {
		dev_err(printdev(devrec), "failed to read rx buffer length\n");
		mrf24j40_handle_rx_read_buf_unlock(devrec);
	}
}
A
Alan Ott 已提交
765

766 767 768 769 770 771 772 773 774 775 776
static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
{
	/* Turn off reception of packets off the air. This prevents the
	 * device from overwriting the buffer while we're reading it.
	 */
	devrec->rx_msg.complete = mrf24j40_handle_rx_read_len;
	devrec->rx_trx.len = 2;
	devrec->rx_buf[0] = MRF24J40_WRITESHORT(REG_BBREG1);
	devrec->rx_buf[1] = 0x04; /* SET RXDECINV */

	return spi_async(devrec->spi, &devrec->rx_msg);
A
Alan Ott 已提交
777 778
}

779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
static int
mrf24j40_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be,
		     u8 retries)
{
	struct mrf24j40 *devrec = hw->priv;
	u8 val;

	/* min_be */
	val = min_be << 3;
	/* csma backoffs */
	val |= retries;

	return regmap_update_bits(devrec->regmap_short, REG_TXMCR, 0x1f, val);
}

A
Alexander Aring 已提交
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824
static int mrf24j40_set_cca_mode(struct ieee802154_hw *hw,
				 const struct wpan_phy_cca *cca)
{
	struct mrf24j40 *devrec = hw->priv;
	u8 val;

	/* mapping 802.15.4 to driver spec */
	switch (cca->mode) {
	case NL802154_CCA_ENERGY:
		val = 2;
		break;
	case NL802154_CCA_CARRIER:
		val = 1;
		break;
	case NL802154_CCA_ENERGY_CARRIER:
		switch (cca->opt) {
		case NL802154_CCA_OPT_ENERGY_CARRIER_AND:
			val = 3;
			break;
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}

	return regmap_update_bits(devrec->regmap_short, REG_BBREG2, 0xc0,
				  val << 6);
}

825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
/* array for representing ed levels */
static const s32 mrf24j40_ed_levels[] = {
	-9000, -8900, -8800, -8700, -8600, -8500, -8400, -8300, -8200, -8100,
	-8000, -7900, -7800, -7700, -7600, -7500, -7400, -7300, -7200, -7100,
	-7000, -6900, -6800, -6700, -6600, -6500, -6400, -6300, -6200, -6100,
	-6000, -5900, -5800, -5700, -5600, -5500, -5400, -5300, -5200, -5100,
	-5000, -4900, -4800, -4700, -4600, -4500, -4400, -4300, -4200, -4100,
	-4000, -3900, -3800, -3700, -3600, -3500
};

/* map ed levels to register value */
static const s32 mrf24j40_ed_levels_map[][2] = {
	{ -9000, 0 }, { -8900, 1 }, { -8800, 2 }, { -8700, 5 }, { -8600, 9 },
	{ -8500, 13 }, { -8400, 18 }, { -8300, 23 }, { -8200, 27 },
	{ -8100, 32 }, { -8000, 37 }, { -7900, 43 }, { -7800, 48 },
	{ -7700, 53 }, { -7600, 58 }, { -7500, 63 }, { -7400, 68 },
	{ -7300, 73 }, { -7200, 78 }, { -7100, 83 }, { -7000, 89 },
	{ -6900, 95 }, { -6800, 100 }, { -6700, 107 }, { -6600, 111 },
	{ -6500, 117 }, { -6400, 121 }, { -6300, 125 }, { -6200, 129 },
	{ -6100, 133 },	{ -6000, 138 }, { -5900, 143 }, { -5800, 148 },
	{ -5700, 153 }, { -5600, 159 },	{ -5500, 165 }, { -5400, 170 },
	{ -5300, 176 }, { -5200, 183 }, { -5100, 188 }, { -5000, 193 },
	{ -4900, 198 }, { -4800, 203 }, { -4700, 207 }, { -4600, 212 },
	{ -4500, 216 }, { -4400, 221 }, { -4300, 225 }, { -4200, 228 },
	{ -4100, 233 }, { -4000, 239 }, { -3900, 245 }, { -3800, 250 },
	{ -3700, 253 }, { -3600, 254 }, { -3500, 255 },
};

static int mrf24j40_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
{
	struct mrf24j40 *devrec = hw->priv;
	int i;

	for (i = 0; i < ARRAY_SIZE(mrf24j40_ed_levels_map); i++) {
		if (mrf24j40_ed_levels_map[i][0] == mbm)
			return regmap_write(devrec->regmap_short, REG_CCAEDTH,
					    mrf24j40_ed_levels_map[i][1]);
	}

	return -EINVAL;
}

A
Alexander Aring 已提交
867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
static const s32 mrf24j40ma_powers[] = {
	0, -50, -120, -190, -280, -370, -490, -630, -1000, -1050, -1120, -1190,
	-1280, -1370, -1490, -1630, -2000, -2050, -2120, -2190, -2280, -2370,
	-2490, -2630, -3000, -3050, -3120, -3190, -3280, -3370, -3490, -3630,
};

static int mrf24j40_set_txpower(struct ieee802154_hw *hw, s32 mbm)
{
	struct mrf24j40 *devrec = hw->priv;
	s32 small_scale;
	u8 val;

	if (0 >= mbm && mbm > -1000) {
		val = 0;
		small_scale = mbm;
	} else if (-1000 >= mbm && mbm > -2000) {
		val = 0x40;
		small_scale = mbm + 1000;
	} else if (-2000 >= mbm && mbm > -3000) {
		val = 0x80;
		small_scale = mbm + 2000;
	} else if (-3000 >= mbm && mbm > -4000) {
		val = 0xc0;
		small_scale = mbm + 3000;
	} else {
		return -EINVAL;
	}

	switch (small_scale) {
	case 0:
		break;
	case -50:
		val |= 0x08;
		break;
	case -120:
		val |= 0x10;
		break;
	case -190:
		val |= 0x18;
		break;
	case -280:
		val |= 0x20;
		break;
	case -370:
		val |= 0x28;
		break;
	case -490:
		val |= 0x30;
		break;
	case -630:
		val |= 0x38;
		break;
	default:
		return -EINVAL;
	}

	return regmap_update_bits(devrec->regmap_long, REG_RFCON3, 0xf8, val);
}

926
static const struct ieee802154_ops mrf24j40_ops = {
A
Alan Ott 已提交
927
	.owner = THIS_MODULE,
928
	.xmit_async = mrf24j40_tx,
A
Alan Ott 已提交
929 930 931 932 933
	.ed = mrf24j40_ed,
	.start = mrf24j40_start,
	.stop = mrf24j40_stop,
	.set_channel = mrf24j40_set_channel,
	.set_hw_addr_filt = mrf24j40_filter,
934
	.set_csma_params = mrf24j40_csma_params,
A
Alexander Aring 已提交
935
	.set_cca_mode = mrf24j40_set_cca_mode,
936
	.set_cca_ed_level = mrf24j40_set_cca_ed_level,
A
Alexander Aring 已提交
937
	.set_txpower = mrf24j40_set_txpower,
A
Alan Ott 已提交
938 939
};

940
static void mrf24j40_intstat_complete(void *context)
A
Alan Ott 已提交
941
{
942 943
	struct mrf24j40 *devrec = context;
	u8 intstat = devrec->irq_buf[1];
A
Alan Ott 已提交
944

945
	enable_irq(devrec->spi->irq);
A
Alan Ott 已提交
946 947 948

	/* Check for TX complete */
	if (intstat & 0x1)
949
		ieee802154_xmit_complete(devrec->hw, devrec->tx_skb, false);
A
Alan Ott 已提交
950 951 952 953

	/* Check for Rx */
	if (intstat & 0x8)
		mrf24j40_handle_rx(devrec);
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969
}

static irqreturn_t mrf24j40_isr(int irq, void *data)
{
	struct mrf24j40 *devrec = data;
	int ret;

	disable_irq_nosync(irq);

	devrec->irq_buf[0] = MRF24J40_READSHORT(REG_INTSTAT);
	/* Read the interrupt status */
	ret = spi_async(devrec->spi, &devrec->irq_msg);
	if (ret) {
		enable_irq(irq);
		return IRQ_NONE;
	}
A
Alan Ott 已提交
970

A
Alan Ott 已提交
971
	return IRQ_HANDLED;
A
Alan Ott 已提交
972 973
}

974 975 976 977 978 979
static int mrf24j40_hw_init(struct mrf24j40 *devrec)
{
	int ret;

	/* Initialize the device.
		From datasheet section 3.2: Initialization. */
980
	ret = regmap_write(devrec->regmap_short, REG_SOFTRST, 0x07);
981 982 983
	if (ret)
		goto err_ret;

984
	ret = regmap_write(devrec->regmap_short, REG_PACON2, 0x98);
985 986 987
	if (ret)
		goto err_ret;

988
	ret = regmap_write(devrec->regmap_short, REG_TXSTBL, 0x95);
989 990 991
	if (ret)
		goto err_ret;

992
	ret = regmap_write(devrec->regmap_long, REG_RFCON0, 0x03);
993 994 995
	if (ret)
		goto err_ret;

996
	ret = regmap_write(devrec->regmap_long, REG_RFCON1, 0x01);
997 998 999
	if (ret)
		goto err_ret;

1000
	ret = regmap_write(devrec->regmap_long, REG_RFCON2, 0x80);
1001 1002 1003
	if (ret)
		goto err_ret;

1004
	ret = regmap_write(devrec->regmap_long, REG_RFCON6, 0x90);
1005 1006 1007
	if (ret)
		goto err_ret;

1008
	ret = regmap_write(devrec->regmap_long, REG_RFCON7, 0x80);
1009 1010 1011
	if (ret)
		goto err_ret;

1012
	ret = regmap_write(devrec->regmap_long, REG_RFCON8, 0x10);
1013 1014 1015
	if (ret)
		goto err_ret;

1016
	ret = regmap_write(devrec->regmap_long, REG_SLPCON1, 0x21);
1017 1018 1019
	if (ret)
		goto err_ret;

1020
	ret = regmap_write(devrec->regmap_short, REG_BBREG2, 0x80);
1021 1022 1023
	if (ret)
		goto err_ret;

1024
	ret = regmap_write(devrec->regmap_short, REG_CCAEDTH, 0x60);
1025 1026 1027
	if (ret)
		goto err_ret;

1028
	ret = regmap_write(devrec->regmap_short, REG_BBREG6, 0x40);
1029 1030 1031
	if (ret)
		goto err_ret;

1032
	ret = regmap_write(devrec->regmap_short, REG_RFCTL, 0x04);
1033 1034 1035
	if (ret)
		goto err_ret;

1036
	ret = regmap_write(devrec->regmap_short, REG_RFCTL, 0x0);
1037 1038 1039 1040 1041 1042
	if (ret)
		goto err_ret;

	udelay(192);

	/* Set RX Mode. RXMCR<1:0>: 0x0 normal, 0x1 promisc, 0x2 error */
1043
	ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR, 0x03, 0x00);
1044 1045 1046
	if (ret)
		goto err_ret;

1047 1048 1049 1050
	if (spi_get_device_id(devrec->spi)->driver_data == MRF24J40MC) {
		/* Enable external amplifier.
		 * From MRF24J40MC datasheet section 1.3: Operation.
		 */
1051 1052
		regmap_update_bits(devrec->regmap_long, REG_TESTMODE, 0x07,
				   0x07);
1053

1054 1055 1056
		/* Set GPIO3 as output. */
		regmap_update_bits(devrec->regmap_short, REG_TRISGPIO, 0x08,
				   0x08);
1057

1058 1059
		/* Set GPIO3 HIGH to enable U5 voltage regulator */
		regmap_update_bits(devrec->regmap_short, REG_GPIO, 0x08, 0x08);
1060 1061 1062 1063

		/* Reduce TX pwr to meet FCC requirements.
		 * From MRF24J40MC datasheet section 3.1.1
		 */
1064
		regmap_write(devrec->regmap_long, REG_RFCON3, 0x28);
1065 1066
	}

1067 1068 1069 1070 1071 1072
	return 0;

err_ret:
	return ret;
}

1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
static void
mrf24j40_setup_tx_spi_messages(struct mrf24j40 *devrec)
{
	spi_message_init(&devrec->tx_msg);
	devrec->tx_msg.context = devrec;
	devrec->tx_msg.complete = write_tx_buf_complete;
	devrec->tx_hdr_trx.len = 2;
	devrec->tx_hdr_trx.tx_buf = devrec->tx_hdr_buf;
	spi_message_add_tail(&devrec->tx_hdr_trx, &devrec->tx_msg);
	devrec->tx_len_trx.len = 2;
	devrec->tx_len_trx.tx_buf = devrec->tx_len_buf;
	spi_message_add_tail(&devrec->tx_len_trx, &devrec->tx_msg);
	spi_message_add_tail(&devrec->tx_buf_trx, &devrec->tx_msg);

	spi_message_init(&devrec->tx_post_msg);
	devrec->tx_post_msg.context = devrec;
	devrec->tx_post_trx.len = 2;
	devrec->tx_post_trx.tx_buf = devrec->tx_post_buf;
	spi_message_add_tail(&devrec->tx_post_trx, &devrec->tx_post_msg);
}

1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
static void
mrf24j40_setup_rx_spi_messages(struct mrf24j40 *devrec)
{
	spi_message_init(&devrec->rx_msg);
	devrec->rx_msg.context = devrec;
	devrec->rx_trx.len = 2;
	devrec->rx_trx.tx_buf = devrec->rx_buf;
	devrec->rx_trx.rx_buf = devrec->rx_buf;
	spi_message_add_tail(&devrec->rx_trx, &devrec->rx_msg);

	spi_message_init(&devrec->rx_buf_msg);
	devrec->rx_buf_msg.context = devrec;
	devrec->rx_buf_msg.complete = mrf24j40_handle_rx_read_buf_complete;
	devrec->rx_addr_trx.len = 2;
	devrec->rx_addr_trx.tx_buf = devrec->rx_addr_buf;
	spi_message_add_tail(&devrec->rx_addr_trx, &devrec->rx_buf_msg);
	devrec->rx_fifo_buf_trx.rx_buf = devrec->rx_fifo_buf;
	spi_message_add_tail(&devrec->rx_fifo_buf_trx, &devrec->rx_buf_msg);
	devrec->rx_lqi_trx.len = 2;
	devrec->rx_lqi_trx.rx_buf = devrec->rx_lqi_buf;
	spi_message_add_tail(&devrec->rx_lqi_trx, &devrec->rx_buf_msg);
}

1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128
static void
mrf24j40_setup_irq_spi_messages(struct mrf24j40 *devrec)
{
	spi_message_init(&devrec->irq_msg);
	devrec->irq_msg.context = devrec;
	devrec->irq_msg.complete = mrf24j40_intstat_complete;
	devrec->irq_trx.len = 2;
	devrec->irq_trx.tx_buf = devrec->irq_buf;
	devrec->irq_trx.rx_buf = devrec->irq_buf;
	spi_message_add_tail(&devrec->irq_trx, &devrec->irq_msg);
}

1129 1130
static void  mrf24j40_phy_setup(struct mrf24j40 *devrec)
{
1131
	ieee802154_random_extended_addr(&devrec->hw->phy->perm_extended_addr);
1132
	devrec->hw->phy->current_channel = 11;
1133 1134 1135 1136 1137 1138 1139 1140

	/* mrf24j40 supports max_minbe 0 - 3 */
	devrec->hw->phy->supported.max_minbe = 3;
	/* datasheet doesn't say anything about max_be, but we have min_be
	 * So we assume the max_be default.
	 */
	devrec->hw->phy->supported.min_maxbe = 5;
	devrec->hw->phy->supported.max_maxbe = 5;
A
Alexander Aring 已提交
1141 1142 1143 1144 1145 1146

	devrec->hw->phy->cca.mode = NL802154_CCA_CARRIER;;
	devrec->hw->phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) |
					       BIT(NL802154_CCA_CARRIER) |
					       BIT(NL802154_CCA_ENERGY_CARRIER);
	devrec->hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND);
1147 1148 1149 1150

	devrec->hw->phy->cca_ed_level = -6900;
	devrec->hw->phy->supported.cca_ed_levels = mrf24j40_ed_levels;
	devrec->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(mrf24j40_ed_levels);
A
Alexander Aring 已提交
1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161

	switch (spi_get_device_id(devrec->spi)->driver_data) {
	case MRF24J40:
	case MRF24J40MA:
		devrec->hw->phy->supported.tx_powers = mrf24j40ma_powers;
		devrec->hw->phy->supported.tx_powers_size = ARRAY_SIZE(mrf24j40ma_powers);
		devrec->hw->phy->flags |= WPAN_PHY_FLAG_TXPOWER;
		break;
	default:
		break;
	}
1162 1163
}

1164
static int mrf24j40_probe(struct spi_device *spi)
A
Alan Ott 已提交
1165 1166
{
	int ret = -ENOMEM;
1167
	struct ieee802154_hw *hw;
A
Alan Ott 已提交
1168 1169
	struct mrf24j40 *devrec;

1170
	dev_info(&spi->dev, "probe(). IRQ: %d\n", spi->irq);
A
Alan Ott 已提交
1171

1172 1173 1174 1175
	/* Register with the 802154 subsystem */

	hw = ieee802154_alloc_hw(sizeof(*devrec), &mrf24j40_ops);
	if (!hw)
1176
		goto err_ret;
1177 1178 1179 1180 1181 1182 1183

	devrec = hw->priv;
	devrec->spi = spi;
	spi_set_drvdata(spi, devrec);
	devrec->hw = hw;
	devrec->hw->parent = &spi->dev;
	devrec->hw->phy->supported.channels[0] = CHANNEL_MASK;
1184 1185
	devrec->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
			    IEEE802154_HW_CSMA_PARAMS;
1186

1187 1188
	devrec->hw->phy->flags = WPAN_PHY_FLAG_CCA_MODE |
				 WPAN_PHY_FLAG_CCA_ED_LEVEL;
A
Alexander Aring 已提交
1189

1190
	mrf24j40_setup_tx_spi_messages(devrec);
1191
	mrf24j40_setup_rx_spi_messages(devrec);
1192
	mrf24j40_setup_irq_spi_messages(devrec);
1193

A
Alexander Aring 已提交
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212
	devrec->regmap_short = devm_regmap_init_spi(spi,
						    &mrf24j40_short_regmap);
	if (IS_ERR(devrec->regmap_short)) {
		ret = PTR_ERR(devrec->regmap_short);
		dev_err(&spi->dev, "Failed to allocate short register map: %d\n",
			ret);
		goto err_register_device;
	}

	devrec->regmap_long = devm_regmap_init(&spi->dev,
					       &mrf24j40_long_regmap_bus,
					       spi, &mrf24j40_long_regmap);
	if (IS_ERR(devrec->regmap_long)) {
		ret = PTR_ERR(devrec->regmap_long);
		dev_err(&spi->dev, "Failed to allocate long register map: %d\n",
			ret);
		goto err_register_device;
	}

1213 1214 1215 1216 1217
	if (spi->max_speed_hz > MAX_SPI_SPEED_HZ) {
		dev_warn(&spi->dev, "spi clock above possible maximum: %d",
			 MAX_SPI_SPEED_HZ);
		return -EINVAL;
	}
A
Alan Ott 已提交
1218

1219
	ret = mrf24j40_hw_init(devrec);
A
Alan Ott 已提交
1220
	if (ret)
1221
		goto err_register_device;
A
Alan Ott 已提交
1222

1223 1224
	mrf24j40_phy_setup(devrec);

1225 1226 1227
	ret = devm_request_irq(&spi->dev, spi->irq, mrf24j40_isr,
			       IRQF_TRIGGER_LOW, dev_name(&spi->dev),
			       devrec);
A
Alan Ott 已提交
1228 1229
	if (ret) {
		dev_err(printdev(devrec), "Unable to get IRQ");
1230
		goto err_register_device;
A
Alan Ott 已提交
1231 1232
	}

1233 1234 1235 1236 1237
	dev_dbg(printdev(devrec), "registered mrf24j40\n");
	ret = ieee802154_register_hw(devrec->hw);
	if (ret)
		goto err_register_device;

A
Alan Ott 已提交
1238 1239 1240
	return 0;

err_register_device:
1241
	ieee802154_free_hw(devrec->hw);
1242
err_ret:
A
Alan Ott 已提交
1243 1244 1245
	return ret;
}

1246
static int mrf24j40_remove(struct spi_device *spi)
A
Alan Ott 已提交
1247
{
1248
	struct mrf24j40 *devrec = spi_get_drvdata(spi);
A
Alan Ott 已提交
1249 1250 1251

	dev_dbg(printdev(devrec), "remove\n");

1252 1253
	ieee802154_unregister_hw(devrec->hw);
	ieee802154_free_hw(devrec->hw);
A
Alan Ott 已提交
1254 1255 1256 1257 1258 1259
	/* TODO: Will ieee802154_free_device() wait until ->xmit() is
	 * complete? */

	return 0;
}

1260 1261 1262 1263 1264 1265 1266 1267
static const struct of_device_id mrf24j40_of_match[] = {
	{ .compatible = "microchip,mrf24j40", .data = (void *)MRF24J40 },
	{ .compatible = "microchip,mrf24j40ma", .data = (void *)MRF24J40MA },
	{ .compatible = "microchip,mrf24j40mc", .data = (void *)MRF24J40MC },
	{ },
};
MODULE_DEVICE_TABLE(of, mrf24j40_of_match);

A
Alan Ott 已提交
1268
static const struct spi_device_id mrf24j40_ids[] = {
1269 1270 1271
	{ "mrf24j40", MRF24J40 },
	{ "mrf24j40ma", MRF24J40MA },
	{ "mrf24j40mc", MRF24J40MC },
A
Alan Ott 已提交
1272 1273 1274 1275 1276 1277
	{ },
};
MODULE_DEVICE_TABLE(spi, mrf24j40_ids);

static struct spi_driver mrf24j40_driver = {
	.driver = {
1278
		.of_match_table = of_match_ptr(mrf24j40_of_match),
A
Alan Ott 已提交
1279 1280 1281 1282 1283
		.name = "mrf24j40",
		.owner = THIS_MODULE,
	},
	.id_table = mrf24j40_ids,
	.probe = mrf24j40_probe,
1284
	.remove = mrf24j40_remove,
A
Alan Ott 已提交
1285 1286
};

1287
module_spi_driver(mrf24j40_driver);
A
Alan Ott 已提交
1288 1289 1290 1291

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alan Ott");
MODULE_DESCRIPTION("MRF24J40 SPI 802.15.4 Controller Driver");