1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
23731a334SAlan Ott /*
33731a334SAlan Ott  * Driver for Microchip MRF24J40 802.15.4 Wireless-PAN Networking controller
43731a334SAlan Ott  *
53731a334SAlan Ott  * Copyright (C) 2012 Alan Ott <alan@signal11.us>
63731a334SAlan Ott  *                    Signal 11 Software
73731a334SAlan Ott  */
83731a334SAlan Ott 
93731a334SAlan Ott #include <linux/spi/spi.h>
103731a334SAlan Ott #include <linux/interrupt.h>
11aab53e67SAndy Shevchenko #include <linux/mod_devicetable.h>
123731a334SAlan Ott #include <linux/module.h>
13b0156792SAlexander Aring #include <linux/regmap.h>
144ca24acaSAlexander Aring #include <linux/ieee802154.h>
15afaf7fdeSAlexander Aring #include <linux/irq.h>
165ad60d36SAlexander Aring #include <net/cfg802154.h>
173731a334SAlan Ott #include <net/mac802154.h>
183731a334SAlan Ott 
193731a334SAlan Ott /* MRF24J40 Short Address Registers */
203731a334SAlan Ott #define REG_RXMCR	0x00  /* Receive MAC control */
217d840545SAlexander Aring #define BIT_PROMI	BIT(0)
227d840545SAlexander Aring #define BIT_ERRPKT	BIT(1)
237d840545SAlexander Aring #define BIT_NOACKRSP	BIT(5)
247d840545SAlexander Aring #define BIT_PANCOORD	BIT(3)
257d840545SAlexander Aring 
263731a334SAlan Ott #define REG_PANIDL	0x01  /* PAN ID (low) */
273731a334SAlan Ott #define REG_PANIDH	0x02  /* PAN ID (high) */
283731a334SAlan Ott #define REG_SADRL	0x03  /* Short address (low) */
293731a334SAlan Ott #define REG_SADRH	0x04  /* Short address (high) */
303731a334SAlan Ott #define REG_EADR0	0x05  /* Long address (low) (high is EADR7) */
31554b4949SAlexander Aring #define REG_EADR1	0x06
32554b4949SAlexander Aring #define REG_EADR2	0x07
33554b4949SAlexander Aring #define REG_EADR3	0x08
34554b4949SAlexander Aring #define REG_EADR4	0x09
35554b4949SAlexander Aring #define REG_EADR5	0x0A
36554b4949SAlexander Aring #define REG_EADR6	0x0B
37554b4949SAlexander Aring #define REG_EADR7	0x0C
38554b4949SAlexander Aring #define REG_RXFLUSH	0x0D
39554b4949SAlexander Aring #define REG_ORDER	0x10
403731a334SAlan Ott #define REG_TXMCR	0x11  /* Transmit MAC control */
417d840545SAlexander Aring #define TXMCR_MIN_BE_SHIFT		3
427d840545SAlexander Aring #define TXMCR_MIN_BE_MASK		0x18
437d840545SAlexander Aring #define TXMCR_CSMA_RETRIES_SHIFT	0
447d840545SAlexander Aring #define TXMCR_CSMA_RETRIES_MASK		0x07
457d840545SAlexander Aring 
46554b4949SAlexander Aring #define REG_ACKTMOUT	0x12
47554b4949SAlexander Aring #define REG_ESLOTG1	0x13
48554b4949SAlexander Aring #define REG_SYMTICKL	0x14
49554b4949SAlexander Aring #define REG_SYMTICKH	0x15
503731a334SAlan Ott #define REG_PACON0	0x16  /* Power Amplifier Control */
513731a334SAlan Ott #define REG_PACON1	0x17  /* Power Amplifier Control */
523731a334SAlan Ott #define REG_PACON2	0x18  /* Power Amplifier Control */
53554b4949SAlexander Aring #define REG_TXBCON0	0x1A
543731a334SAlan Ott #define REG_TXNCON	0x1B  /* Transmit Normal FIFO Control */
557d840545SAlexander Aring #define BIT_TXNTRIG	BIT(0)
5687820441SAlexandre Macabies #define BIT_TXNSECEN	BIT(1)
577d840545SAlexander Aring #define BIT_TXNACKREQ	BIT(2)
587d840545SAlexander Aring 
59554b4949SAlexander Aring #define REG_TXG1CON	0x1C
60554b4949SAlexander Aring #define REG_TXG2CON	0x1D
61554b4949SAlexander Aring #define REG_ESLOTG23	0x1E
62554b4949SAlexander Aring #define REG_ESLOTG45	0x1F
63554b4949SAlexander Aring #define REG_ESLOTG67	0x20
64554b4949SAlexander Aring #define REG_TXPEND	0x21
65554b4949SAlexander Aring #define REG_WAKECON	0x22
66554b4949SAlexander Aring #define REG_FROMOFFSET	0x23
673731a334SAlan Ott #define REG_TXSTAT	0x24  /* TX MAC Status Register */
68554b4949SAlexander Aring #define REG_TXBCON1	0x25
69554b4949SAlexander Aring #define REG_GATECLK	0x26
70554b4949SAlexander Aring #define REG_TXTIME	0x27
71554b4949SAlexander Aring #define REG_HSYMTMRL	0x28
72554b4949SAlexander Aring #define REG_HSYMTMRH	0x29
733731a334SAlan Ott #define REG_SOFTRST	0x2A  /* Soft Reset */
74554b4949SAlexander Aring #define REG_SECCON0	0x2C
75554b4949SAlexander Aring #define REG_SECCON1	0x2D
763731a334SAlan Ott #define REG_TXSTBL	0x2E  /* TX Stabilization */
77554b4949SAlexander Aring #define REG_RXSR	0x30
783731a334SAlan Ott #define REG_INTSTAT	0x31  /* Interrupt Status */
797d840545SAlexander Aring #define BIT_TXNIF	BIT(0)
807d840545SAlexander Aring #define BIT_RXIF	BIT(3)
815a62f3c6SAlexandre Macabies #define BIT_SECIF	BIT(4)
825a62f3c6SAlexandre Macabies #define BIT_SECIGNORE	BIT(7)
837d840545SAlexander Aring 
843731a334SAlan Ott #define REG_INTCON	0x32  /* Interrupt Control */
857d840545SAlexander Aring #define BIT_TXNIE	BIT(0)
867d840545SAlexander Aring #define BIT_RXIE	BIT(3)
875a62f3c6SAlexandre Macabies #define BIT_SECIE	BIT(4)
887d840545SAlexander Aring 
89db9e0ee8SSimon Vincent #define REG_GPIO	0x33  /* GPIO */
90db9e0ee8SSimon Vincent #define REG_TRISGPIO	0x34  /* GPIO direction */
91554b4949SAlexander Aring #define REG_SLPACK	0x35
923731a334SAlan Ott #define REG_RFCTL	0x36  /* RF Control Mode Register */
937d840545SAlexander Aring #define BIT_RFRST	BIT(2)
947d840545SAlexander Aring 
95554b4949SAlexander Aring #define REG_SECCR2	0x37
96554b4949SAlexander Aring #define REG_BBREG0	0x38
973731a334SAlan Ott #define REG_BBREG1	0x39  /* Baseband Registers */
987d840545SAlexander Aring #define BIT_RXDECINV	BIT(2)
997d840545SAlexander Aring 
1003731a334SAlan Ott #define REG_BBREG2	0x3A  /* */
1017d840545SAlexander Aring #define BBREG2_CCA_MODE_SHIFT	6
1027d840545SAlexander Aring #define BBREG2_CCA_MODE_MASK	0xc0
1037d840545SAlexander Aring 
104554b4949SAlexander Aring #define REG_BBREG3	0x3B
105554b4949SAlexander Aring #define REG_BBREG4	0x3C
1063731a334SAlan Ott #define REG_BBREG6	0x3E  /* */
1073731a334SAlan Ott #define REG_CCAEDTH	0x3F  /* Energy Detection Threshold */
1083731a334SAlan Ott 
1093731a334SAlan Ott /* MRF24J40 Long Address Registers */
1103731a334SAlan Ott #define REG_RFCON0	0x200  /* RF Control Registers */
1117d840545SAlexander Aring #define RFCON0_CH_SHIFT	4
1127d840545SAlexander Aring #define RFCON0_CH_MASK	0xf0
1137d840545SAlexander Aring #define RFOPT_RECOMMEND	3
1147d840545SAlexander Aring 
1153731a334SAlan Ott #define REG_RFCON1	0x201
1163731a334SAlan Ott #define REG_RFCON2	0x202
1173731a334SAlan Ott #define REG_RFCON3	0x203
1187d840545SAlexander Aring 
1197d840545SAlexander Aring #define TXPWRL_MASK	0xc0
1207d840545SAlexander Aring #define TXPWRL_SHIFT	6
1217d840545SAlexander Aring #define TXPWRL_30	0x3
1227d840545SAlexander Aring #define TXPWRL_20	0x2
1237d840545SAlexander Aring #define TXPWRL_10	0x1
1247d840545SAlexander Aring #define TXPWRL_0	0x0
1257d840545SAlexander Aring 
1267d840545SAlexander Aring #define TXPWRS_MASK	0x38
1277d840545SAlexander Aring #define TXPWRS_SHIFT	3
1287d840545SAlexander Aring #define TXPWRS_6_3	0x7
1297d840545SAlexander Aring #define TXPWRS_4_9	0x6
1307d840545SAlexander Aring #define TXPWRS_3_7	0x5
1317d840545SAlexander Aring #define TXPWRS_2_8	0x4
1327d840545SAlexander Aring #define TXPWRS_1_9	0x3
1337d840545SAlexander Aring #define TXPWRS_1_2	0x2
1347d840545SAlexander Aring #define TXPWRS_0_5	0x1
1357d840545SAlexander Aring #define TXPWRS_0	0x0
1367d840545SAlexander Aring 
1373731a334SAlan Ott #define REG_RFCON5	0x205
1383731a334SAlan Ott #define REG_RFCON6	0x206
1393731a334SAlan Ott #define REG_RFCON7	0x207
1403731a334SAlan Ott #define REG_RFCON8	0x208
141554b4949SAlexander Aring #define REG_SLPCAL0	0x209
142554b4949SAlexander Aring #define REG_SLPCAL1	0x20A
143554b4949SAlexander Aring #define REG_SLPCAL2	0x20B
144554b4949SAlexander Aring #define REG_RFSTATE	0x20F
1453731a334SAlan Ott #define REG_RSSI	0x210
1463731a334SAlan Ott #define REG_SLPCON0	0x211  /* Sleep Clock Control Registers */
1477d840545SAlexander Aring #define BIT_INTEDGE	BIT(1)
1487d840545SAlexander Aring 
1493731a334SAlan Ott #define REG_SLPCON1	0x220
1503731a334SAlan Ott #define REG_WAKETIMEL	0x222  /* Wake-up Time Match Value Low */
1513731a334SAlan Ott #define REG_WAKETIMEH	0x223  /* Wake-up Time Match Value High */
152554b4949SAlexander Aring #define REG_REMCNTL	0x224
153554b4949SAlexander Aring #define REG_REMCNTH	0x225
154554b4949SAlexander Aring #define REG_MAINCNT0	0x226
155554b4949SAlexander Aring #define REG_MAINCNT1	0x227
156554b4949SAlexander Aring #define REG_MAINCNT2	0x228
157554b4949SAlexander Aring #define REG_MAINCNT3	0x229
158db9e0ee8SSimon Vincent #define REG_TESTMODE	0x22F  /* Test mode */
159554b4949SAlexander Aring #define REG_ASSOEAR0	0x230
160554b4949SAlexander Aring #define REG_ASSOEAR1	0x231
161554b4949SAlexander Aring #define REG_ASSOEAR2	0x232
162554b4949SAlexander Aring #define REG_ASSOEAR3	0x233
163554b4949SAlexander Aring #define REG_ASSOEAR4	0x234
164554b4949SAlexander Aring #define REG_ASSOEAR5	0x235
165554b4949SAlexander Aring #define REG_ASSOEAR6	0x236
166554b4949SAlexander Aring #define REG_ASSOEAR7	0x237
167554b4949SAlexander Aring #define REG_ASSOSAR0	0x238
168554b4949SAlexander Aring #define REG_ASSOSAR1	0x239
169554b4949SAlexander Aring #define REG_UNONCE0	0x240
170554b4949SAlexander Aring #define REG_UNONCE1	0x241
171554b4949SAlexander Aring #define REG_UNONCE2	0x242
172554b4949SAlexander Aring #define REG_UNONCE3	0x243
173554b4949SAlexander Aring #define REG_UNONCE4	0x244
174554b4949SAlexander Aring #define REG_UNONCE5	0x245
175554b4949SAlexander Aring #define REG_UNONCE6	0x246
176554b4949SAlexander Aring #define REG_UNONCE7	0x247
177554b4949SAlexander Aring #define REG_UNONCE8	0x248
178554b4949SAlexander Aring #define REG_UNONCE9	0x249
179554b4949SAlexander Aring #define REG_UNONCE10	0x24A
180554b4949SAlexander Aring #define REG_UNONCE11	0x24B
181554b4949SAlexander Aring #define REG_UNONCE12	0x24C
1823731a334SAlan Ott #define REG_RX_FIFO	0x300  /* Receive FIFO */
1833731a334SAlan Ott 
1843731a334SAlan Ott /* Device configuration: Only channels 11-26 on page 0 are supported. */
1853731a334SAlan Ott #define MRF24J40_CHAN_MIN 11
1863731a334SAlan Ott #define MRF24J40_CHAN_MAX 26
1873731a334SAlan Ott #define CHANNEL_MASK (((u32)1 << (MRF24J40_CHAN_MAX + 1)) \
1883731a334SAlan Ott 		      - ((u32)1 << MRF24J40_CHAN_MIN))
1893731a334SAlan Ott 
1903731a334SAlan Ott #define TX_FIFO_SIZE 128 /* From datasheet */
1913731a334SAlan Ott #define RX_FIFO_SIZE 144 /* From datasheet */
1923731a334SAlan Ott #define SET_CHANNEL_DELAY_US 192 /* From datasheet */
1933731a334SAlan Ott 
194db9e0ee8SSimon Vincent enum mrf24j40_modules { MRF24J40, MRF24J40MA, MRF24J40MC };
195db9e0ee8SSimon Vincent 
1963731a334SAlan Ott /* Device Private Data */
1973731a334SAlan Ott struct mrf24j40 {
1983731a334SAlan Ott 	struct spi_device *spi;
1995a504397SAlexander Aring 	struct ieee802154_hw *hw;
2003731a334SAlan Ott 
201b0156792SAlexander Aring 	struct regmap *regmap_short;
202b0156792SAlexander Aring 	struct regmap *regmap_long;
2036844a0e4SAlexander Aring 
2046844a0e4SAlexander Aring 	/* for writing txfifo */
2056844a0e4SAlexander Aring 	struct spi_message tx_msg;
2066844a0e4SAlexander Aring 	u8 tx_hdr_buf[2];
2076844a0e4SAlexander Aring 	struct spi_transfer tx_hdr_trx;
2086844a0e4SAlexander Aring 	u8 tx_len_buf[2];
2096844a0e4SAlexander Aring 	struct spi_transfer tx_len_trx;
2106844a0e4SAlexander Aring 	struct spi_transfer tx_buf_trx;
2116844a0e4SAlexander Aring 	struct sk_buff *tx_skb;
2126844a0e4SAlexander Aring 
2136844a0e4SAlexander Aring 	/* post transmit message to send frame out  */
2146844a0e4SAlexander Aring 	struct spi_message tx_post_msg;
2156844a0e4SAlexander Aring 	u8 tx_post_buf[2];
2166844a0e4SAlexander Aring 	struct spi_transfer tx_post_trx;
2176844a0e4SAlexander Aring 
218c91a3011SAlexander Aring 	/* for protect/unprotect/read length rxfifo */
219c91a3011SAlexander Aring 	struct spi_message rx_msg;
220c91a3011SAlexander Aring 	u8 rx_buf[3];
221c91a3011SAlexander Aring 	struct spi_transfer rx_trx;
222c91a3011SAlexander Aring 
223c91a3011SAlexander Aring 	/* receive handling */
224c91a3011SAlexander Aring 	struct spi_message rx_buf_msg;
225c91a3011SAlexander Aring 	u8 rx_addr_buf[2];
226c91a3011SAlexander Aring 	struct spi_transfer rx_addr_trx;
227c91a3011SAlexander Aring 	u8 rx_lqi_buf[2];
228c91a3011SAlexander Aring 	struct spi_transfer rx_lqi_trx;
229c91a3011SAlexander Aring 	u8 rx_fifo_buf[RX_FIFO_SIZE];
230c91a3011SAlexander Aring 	struct spi_transfer rx_fifo_buf_trx;
231c91a3011SAlexander Aring 
23237441611SAlexander Aring 	/* isr handling for reading intstat */
23337441611SAlexander Aring 	struct spi_message irq_msg;
23437441611SAlexander Aring 	u8 irq_buf[2];
23537441611SAlexander Aring 	struct spi_transfer irq_trx;
2363731a334SAlan Ott };
2373731a334SAlan Ott 
238b0156792SAlexander Aring /* regmap information for short address register access */
239b0156792SAlexander Aring #define MRF24J40_SHORT_WRITE	0x01
240b0156792SAlexander Aring #define MRF24J40_SHORT_READ	0x00
241b0156792SAlexander Aring #define MRF24J40_SHORT_NUMREGS	0x3F
242b0156792SAlexander Aring 
243b0156792SAlexander Aring /* regmap information for long address register access */
244b0156792SAlexander Aring #define MRF24J40_LONG_ACCESS	0x80
245b0156792SAlexander Aring #define MRF24J40_LONG_NUMREGS	0x38F
246b0156792SAlexander Aring 
2473731a334SAlan Ott /* Read/Write SPI Commands for Short and Long Address registers. */
2483731a334SAlan Ott #define MRF24J40_READSHORT(reg) ((reg) << 1)
2493731a334SAlan Ott #define MRF24J40_WRITESHORT(reg) ((reg) << 1 | 1)
2503731a334SAlan Ott #define MRF24J40_READLONG(reg) (1 << 15 | (reg) << 5)
2513731a334SAlan Ott #define MRF24J40_WRITELONG(reg) (1 << 15 | (reg) << 5 | 1 << 4)
2523731a334SAlan Ott 
253cf82dabdSAlan Ott /* The datasheet indicates the theoretical maximum for SCK to be 10MHz */
254cf82dabdSAlan Ott #define MAX_SPI_SPEED_HZ 10000000
2553731a334SAlan Ott 
2563731a334SAlan Ott #define printdev(X) (&X->spi->dev)
2573731a334SAlan Ott 
258b0156792SAlexander Aring static bool
mrf24j40_short_reg_writeable(struct device * dev,unsigned int reg)259b0156792SAlexander Aring mrf24j40_short_reg_writeable(struct device *dev, unsigned int reg)
260b0156792SAlexander Aring {
261b0156792SAlexander Aring 	switch (reg) {
262b0156792SAlexander Aring 	case REG_RXMCR:
263b0156792SAlexander Aring 	case REG_PANIDL:
264b0156792SAlexander Aring 	case REG_PANIDH:
265b0156792SAlexander Aring 	case REG_SADRL:
266b0156792SAlexander Aring 	case REG_SADRH:
267b0156792SAlexander Aring 	case REG_EADR0:
268b0156792SAlexander Aring 	case REG_EADR1:
269b0156792SAlexander Aring 	case REG_EADR2:
270b0156792SAlexander Aring 	case REG_EADR3:
271b0156792SAlexander Aring 	case REG_EADR4:
272b0156792SAlexander Aring 	case REG_EADR5:
273b0156792SAlexander Aring 	case REG_EADR6:
274b0156792SAlexander Aring 	case REG_EADR7:
275b0156792SAlexander Aring 	case REG_RXFLUSH:
276b0156792SAlexander Aring 	case REG_ORDER:
277b0156792SAlexander Aring 	case REG_TXMCR:
278b0156792SAlexander Aring 	case REG_ACKTMOUT:
279b0156792SAlexander Aring 	case REG_ESLOTG1:
280b0156792SAlexander Aring 	case REG_SYMTICKL:
281b0156792SAlexander Aring 	case REG_SYMTICKH:
282b0156792SAlexander Aring 	case REG_PACON0:
283b0156792SAlexander Aring 	case REG_PACON1:
284b0156792SAlexander Aring 	case REG_PACON2:
285b0156792SAlexander Aring 	case REG_TXBCON0:
286b0156792SAlexander Aring 	case REG_TXNCON:
287b0156792SAlexander Aring 	case REG_TXG1CON:
288b0156792SAlexander Aring 	case REG_TXG2CON:
289b0156792SAlexander Aring 	case REG_ESLOTG23:
290b0156792SAlexander Aring 	case REG_ESLOTG45:
291b0156792SAlexander Aring 	case REG_ESLOTG67:
292b0156792SAlexander Aring 	case REG_TXPEND:
293b0156792SAlexander Aring 	case REG_WAKECON:
294b0156792SAlexander Aring 	case REG_FROMOFFSET:
295b0156792SAlexander Aring 	case REG_TXBCON1:
296b0156792SAlexander Aring 	case REG_GATECLK:
297b0156792SAlexander Aring 	case REG_TXTIME:
298b0156792SAlexander Aring 	case REG_HSYMTMRL:
299b0156792SAlexander Aring 	case REG_HSYMTMRH:
300b0156792SAlexander Aring 	case REG_SOFTRST:
301b0156792SAlexander Aring 	case REG_SECCON0:
302b0156792SAlexander Aring 	case REG_SECCON1:
303b0156792SAlexander Aring 	case REG_TXSTBL:
304b0156792SAlexander Aring 	case REG_RXSR:
305b0156792SAlexander Aring 	case REG_INTCON:
306b0156792SAlexander Aring 	case REG_TRISGPIO:
307b0156792SAlexander Aring 	case REG_GPIO:
308b0156792SAlexander Aring 	case REG_RFCTL:
3096367551fSAlexander Aring 	case REG_SECCR2:
310b0156792SAlexander Aring 	case REG_SLPACK:
311b0156792SAlexander Aring 	case REG_BBREG0:
312b0156792SAlexander Aring 	case REG_BBREG1:
313b0156792SAlexander Aring 	case REG_BBREG2:
314b0156792SAlexander Aring 	case REG_BBREG3:
315b0156792SAlexander Aring 	case REG_BBREG4:
316b0156792SAlexander Aring 	case REG_BBREG6:
317b0156792SAlexander Aring 	case REG_CCAEDTH:
318b0156792SAlexander Aring 		return true;
319b0156792SAlexander Aring 	default:
320b0156792SAlexander Aring 		return false;
321b0156792SAlexander Aring 	}
322b0156792SAlexander Aring }
323b0156792SAlexander Aring 
324b0156792SAlexander Aring static bool
mrf24j40_short_reg_readable(struct device * dev,unsigned int reg)325b0156792SAlexander Aring mrf24j40_short_reg_readable(struct device *dev, unsigned int reg)
326b0156792SAlexander Aring {
327b0156792SAlexander Aring 	bool rc;
328b0156792SAlexander Aring 
329b0156792SAlexander Aring 	/* all writeable are also readable */
330b0156792SAlexander Aring 	rc = mrf24j40_short_reg_writeable(dev, reg);
331b0156792SAlexander Aring 	if (rc)
332b0156792SAlexander Aring 		return rc;
333b0156792SAlexander Aring 
334b0156792SAlexander Aring 	/* readonly regs */
335b0156792SAlexander Aring 	switch (reg) {
336b0156792SAlexander Aring 	case REG_TXSTAT:
337b0156792SAlexander Aring 	case REG_INTSTAT:
338b0156792SAlexander Aring 		return true;
339b0156792SAlexander Aring 	default:
340b0156792SAlexander Aring 		return false;
341b0156792SAlexander Aring 	}
342b0156792SAlexander Aring }
343b0156792SAlexander Aring 
344b0156792SAlexander Aring static bool
mrf24j40_short_reg_volatile(struct device * dev,unsigned int reg)345b0156792SAlexander Aring mrf24j40_short_reg_volatile(struct device *dev, unsigned int reg)
346b0156792SAlexander Aring {
347b0156792SAlexander Aring 	/* can be changed during runtime */
348b0156792SAlexander Aring 	switch (reg) {
349b0156792SAlexander Aring 	case REG_TXSTAT:
350b0156792SAlexander Aring 	case REG_INTSTAT:
351b0156792SAlexander Aring 	case REG_RXFLUSH:
352b0156792SAlexander Aring 	case REG_TXNCON:
353b0156792SAlexander Aring 	case REG_SOFTRST:
354b0156792SAlexander Aring 	case REG_RFCTL:
355b0156792SAlexander Aring 	case REG_TXBCON0:
356b0156792SAlexander Aring 	case REG_TXG1CON:
357b0156792SAlexander Aring 	case REG_TXG2CON:
358b0156792SAlexander Aring 	case REG_TXBCON1:
359b0156792SAlexander Aring 	case REG_SECCON0:
360b0156792SAlexander Aring 	case REG_RXSR:
361b0156792SAlexander Aring 	case REG_SLPACK:
362b0156792SAlexander Aring 	case REG_SECCR2:
363b0156792SAlexander Aring 	case REG_BBREG6:
364b0156792SAlexander Aring 	/* use them in spi_async and regmap so it's volatile */
365b0156792SAlexander Aring 	case REG_BBREG1:
366b0156792SAlexander Aring 		return true;
367b0156792SAlexander Aring 	default:
368b0156792SAlexander Aring 		return false;
369b0156792SAlexander Aring 	}
370b0156792SAlexander Aring }
371b0156792SAlexander Aring 
372b0156792SAlexander Aring static bool
mrf24j40_short_reg_precious(struct device * dev,unsigned int reg)373b0156792SAlexander Aring mrf24j40_short_reg_precious(struct device *dev, unsigned int reg)
374b0156792SAlexander Aring {
375b0156792SAlexander Aring 	/* don't clear irq line on read */
376b0156792SAlexander Aring 	switch (reg) {
377b0156792SAlexander Aring 	case REG_INTSTAT:
378b0156792SAlexander Aring 		return true;
379b0156792SAlexander Aring 	default:
380b0156792SAlexander Aring 		return false;
381b0156792SAlexander Aring 	}
382b0156792SAlexander Aring }
383b0156792SAlexander Aring 
384b0156792SAlexander Aring static const struct regmap_config mrf24j40_short_regmap = {
385b0156792SAlexander Aring 	.name = "mrf24j40_short",
386b0156792SAlexander Aring 	.reg_bits = 7,
387b0156792SAlexander Aring 	.val_bits = 8,
388b0156792SAlexander Aring 	.pad_bits = 1,
389b0156792SAlexander Aring 	.write_flag_mask = MRF24J40_SHORT_WRITE,
390b0156792SAlexander Aring 	.read_flag_mask = MRF24J40_SHORT_READ,
391b0156792SAlexander Aring 	.cache_type = REGCACHE_RBTREE,
392b0156792SAlexander Aring 	.max_register = MRF24J40_SHORT_NUMREGS,
393b0156792SAlexander Aring 	.writeable_reg = mrf24j40_short_reg_writeable,
394b0156792SAlexander Aring 	.readable_reg = mrf24j40_short_reg_readable,
395b0156792SAlexander Aring 	.volatile_reg = mrf24j40_short_reg_volatile,
396b0156792SAlexander Aring 	.precious_reg = mrf24j40_short_reg_precious,
397b0156792SAlexander Aring };
398b0156792SAlexander Aring 
399b0156792SAlexander Aring static bool
mrf24j40_long_reg_writeable(struct device * dev,unsigned int reg)400b0156792SAlexander Aring mrf24j40_long_reg_writeable(struct device *dev, unsigned int reg)
401b0156792SAlexander Aring {
402b0156792SAlexander Aring 	switch (reg) {
403b0156792SAlexander Aring 	case REG_RFCON0:
404b0156792SAlexander Aring 	case REG_RFCON1:
405b0156792SAlexander Aring 	case REG_RFCON2:
406b0156792SAlexander Aring 	case REG_RFCON3:
407b0156792SAlexander Aring 	case REG_RFCON5:
408b0156792SAlexander Aring 	case REG_RFCON6:
409b0156792SAlexander Aring 	case REG_RFCON7:
410b0156792SAlexander Aring 	case REG_RFCON8:
411b0156792SAlexander Aring 	case REG_SLPCAL2:
412b0156792SAlexander Aring 	case REG_SLPCON0:
413b0156792SAlexander Aring 	case REG_SLPCON1:
414b0156792SAlexander Aring 	case REG_WAKETIMEL:
415b0156792SAlexander Aring 	case REG_WAKETIMEH:
416b0156792SAlexander Aring 	case REG_REMCNTL:
417b0156792SAlexander Aring 	case REG_REMCNTH:
418b0156792SAlexander Aring 	case REG_MAINCNT0:
419b0156792SAlexander Aring 	case REG_MAINCNT1:
420b0156792SAlexander Aring 	case REG_MAINCNT2:
421b0156792SAlexander Aring 	case REG_MAINCNT3:
422b0156792SAlexander Aring 	case REG_TESTMODE:
423b0156792SAlexander Aring 	case REG_ASSOEAR0:
424b0156792SAlexander Aring 	case REG_ASSOEAR1:
425b0156792SAlexander Aring 	case REG_ASSOEAR2:
426b0156792SAlexander Aring 	case REG_ASSOEAR3:
427b0156792SAlexander Aring 	case REG_ASSOEAR4:
428b0156792SAlexander Aring 	case REG_ASSOEAR5:
429b0156792SAlexander Aring 	case REG_ASSOEAR6:
430b0156792SAlexander Aring 	case REG_ASSOEAR7:
431b0156792SAlexander Aring 	case REG_ASSOSAR0:
432b0156792SAlexander Aring 	case REG_ASSOSAR1:
433b0156792SAlexander Aring 	case REG_UNONCE0:
434b0156792SAlexander Aring 	case REG_UNONCE1:
435b0156792SAlexander Aring 	case REG_UNONCE2:
436b0156792SAlexander Aring 	case REG_UNONCE3:
437b0156792SAlexander Aring 	case REG_UNONCE4:
438b0156792SAlexander Aring 	case REG_UNONCE5:
439b0156792SAlexander Aring 	case REG_UNONCE6:
440b0156792SAlexander Aring 	case REG_UNONCE7:
441b0156792SAlexander Aring 	case REG_UNONCE8:
442b0156792SAlexander Aring 	case REG_UNONCE9:
443b0156792SAlexander Aring 	case REG_UNONCE10:
444b0156792SAlexander Aring 	case REG_UNONCE11:
445b0156792SAlexander Aring 	case REG_UNONCE12:
446b0156792SAlexander Aring 		return true;
447b0156792SAlexander Aring 	default:
448b0156792SAlexander Aring 		return false;
449b0156792SAlexander Aring 	}
450b0156792SAlexander Aring }
451b0156792SAlexander Aring 
452b0156792SAlexander Aring static bool
mrf24j40_long_reg_readable(struct device * dev,unsigned int reg)453b0156792SAlexander Aring mrf24j40_long_reg_readable(struct device *dev, unsigned int reg)
454b0156792SAlexander Aring {
455b0156792SAlexander Aring 	bool rc;
456b0156792SAlexander Aring 
457b0156792SAlexander Aring 	/* all writeable are also readable */
458b0156792SAlexander Aring 	rc = mrf24j40_long_reg_writeable(dev, reg);
459b0156792SAlexander Aring 	if (rc)
460b0156792SAlexander Aring 		return rc;
461b0156792SAlexander Aring 
462b0156792SAlexander Aring 	/* readonly regs */
463b0156792SAlexander Aring 	switch (reg) {
464b0156792SAlexander Aring 	case REG_SLPCAL0:
465b0156792SAlexander Aring 	case REG_SLPCAL1:
466b0156792SAlexander Aring 	case REG_RFSTATE:
467b0156792SAlexander Aring 	case REG_RSSI:
468b0156792SAlexander Aring 		return true;
469b0156792SAlexander Aring 	default:
470b0156792SAlexander Aring 		return false;
471b0156792SAlexander Aring 	}
472b0156792SAlexander Aring }
473b0156792SAlexander Aring 
474b0156792SAlexander Aring static bool
mrf24j40_long_reg_volatile(struct device * dev,unsigned int reg)475b0156792SAlexander Aring mrf24j40_long_reg_volatile(struct device *dev, unsigned int reg)
476b0156792SAlexander Aring {
477b0156792SAlexander Aring 	/* can be changed during runtime */
478b0156792SAlexander Aring 	switch (reg) {
479b0156792SAlexander Aring 	case REG_SLPCAL0:
480b0156792SAlexander Aring 	case REG_SLPCAL1:
481b0156792SAlexander Aring 	case REG_SLPCAL2:
482b0156792SAlexander Aring 	case REG_RFSTATE:
483b0156792SAlexander Aring 	case REG_RSSI:
484b0156792SAlexander Aring 	case REG_MAINCNT3:
485b0156792SAlexander Aring 		return true;
486b0156792SAlexander Aring 	default:
487b0156792SAlexander Aring 		return false;
488b0156792SAlexander Aring 	}
489b0156792SAlexander Aring }
490b0156792SAlexander Aring 
491b0156792SAlexander Aring static const struct regmap_config mrf24j40_long_regmap = {
492b0156792SAlexander Aring 	.name = "mrf24j40_long",
493b0156792SAlexander Aring 	.reg_bits = 11,
494b0156792SAlexander Aring 	.val_bits = 8,
495b0156792SAlexander Aring 	.pad_bits = 5,
496b0156792SAlexander Aring 	.write_flag_mask = MRF24J40_LONG_ACCESS,
497b0156792SAlexander Aring 	.read_flag_mask = MRF24J40_LONG_ACCESS,
498b0156792SAlexander Aring 	.cache_type = REGCACHE_RBTREE,
499b0156792SAlexander Aring 	.max_register = MRF24J40_LONG_NUMREGS,
500b0156792SAlexander Aring 	.writeable_reg = mrf24j40_long_reg_writeable,
501b0156792SAlexander Aring 	.readable_reg = mrf24j40_long_reg_readable,
502b0156792SAlexander Aring 	.volatile_reg = mrf24j40_long_reg_volatile,
503b0156792SAlexander Aring };
504b0156792SAlexander Aring 
mrf24j40_long_regmap_write(void * context,const void * data,size_t count)505b0156792SAlexander Aring static int mrf24j40_long_regmap_write(void *context, const void *data,
506b0156792SAlexander Aring 				      size_t count)
507b0156792SAlexander Aring {
508b0156792SAlexander Aring 	struct spi_device *spi = context;
509b0156792SAlexander Aring 	u8 buf[3];
510b0156792SAlexander Aring 
511b0156792SAlexander Aring 	if (count > 3)
512b0156792SAlexander Aring 		return -EINVAL;
513b0156792SAlexander Aring 
514b0156792SAlexander Aring 	/* regmap supports read/write mask only in frist byte
515b0156792SAlexander Aring 	 * long write access need to set the 12th bit, so we
516b0156792SAlexander Aring 	 * make special handling for write.
517b0156792SAlexander Aring 	 */
518b0156792SAlexander Aring 	memcpy(buf, data, count);
519b0156792SAlexander Aring 	buf[1] |= (1 << 4);
520b0156792SAlexander Aring 
521b0156792SAlexander Aring 	return spi_write(spi, buf, count);
522b0156792SAlexander Aring }
523b0156792SAlexander Aring 
524b0156792SAlexander Aring static int
mrf24j40_long_regmap_read(void * context,const void * reg,size_t reg_size,void * val,size_t val_size)525b0156792SAlexander Aring mrf24j40_long_regmap_read(void *context, const void *reg, size_t reg_size,
526b0156792SAlexander Aring 			  void *val, size_t val_size)
527b0156792SAlexander Aring {
528b0156792SAlexander Aring 	struct spi_device *spi = context;
529b0156792SAlexander Aring 
530b0156792SAlexander Aring 	return spi_write_then_read(spi, reg, reg_size, val, val_size);
531b0156792SAlexander Aring }
532b0156792SAlexander Aring 
533b0156792SAlexander Aring static const struct regmap_bus mrf24j40_long_regmap_bus = {
534b0156792SAlexander Aring 	.write = mrf24j40_long_regmap_write,
535b0156792SAlexander Aring 	.read = mrf24j40_long_regmap_read,
536b0156792SAlexander Aring 	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
537b0156792SAlexander Aring 	.val_format_endian_default = REGMAP_ENDIAN_BIG,
538b0156792SAlexander Aring };
539b0156792SAlexander Aring 
write_tx_buf_complete(void * context)5406844a0e4SAlexander Aring static void write_tx_buf_complete(void *context)
5416844a0e4SAlexander Aring {
5426844a0e4SAlexander Aring 	struct mrf24j40 *devrec = context;
5436844a0e4SAlexander Aring 	__le16 fc = ieee802154_get_fc_from_skb(devrec->tx_skb);
5447d840545SAlexander Aring 	u8 val = BIT_TXNTRIG;
5456844a0e4SAlexander Aring 	int ret;
5466844a0e4SAlexander Aring 
54787820441SAlexandre Macabies 	if (ieee802154_is_secen(fc))
54887820441SAlexandre Macabies 		val |= BIT_TXNSECEN;
54987820441SAlexandre Macabies 
5506844a0e4SAlexander Aring 	if (ieee802154_is_ackreq(fc))
5517d840545SAlexander Aring 		val |= BIT_TXNACKREQ;
5526844a0e4SAlexander Aring 
5536844a0e4SAlexander Aring 	devrec->tx_post_msg.complete = NULL;
5546844a0e4SAlexander Aring 	devrec->tx_post_buf[0] = MRF24J40_WRITESHORT(REG_TXNCON);
5556844a0e4SAlexander Aring 	devrec->tx_post_buf[1] = val;
5566844a0e4SAlexander Aring 
5576844a0e4SAlexander Aring 	ret = spi_async(devrec->spi, &devrec->tx_post_msg);
5586844a0e4SAlexander Aring 	if (ret)
5596844a0e4SAlexander Aring 		dev_err(printdev(devrec), "SPI write Failed for transmit buf\n");
5606844a0e4SAlexander Aring }
5616844a0e4SAlexander Aring 
5623731a334SAlan Ott /* This function relies on an undocumented write method. Once a write command
5633731a334SAlan Ott    and address is set, as many bytes of data as desired can be clocked into
5643731a334SAlan Ott    the device. The datasheet only shows setting one byte at a time. */
write_tx_buf(struct mrf24j40 * devrec,u16 reg,const u8 * data,size_t length)5653731a334SAlan Ott static int write_tx_buf(struct mrf24j40 *devrec, u16 reg,
5663731a334SAlan Ott 			const u8 *data, size_t length)
5673731a334SAlan Ott {
5683731a334SAlan Ott 	u16 cmd;
5696844a0e4SAlexander Aring 	int ret;
5703731a334SAlan Ott 
5713731a334SAlan Ott 	/* Range check the length. 2 bytes are used for the length fields.*/
5723731a334SAlan Ott 	if (length > TX_FIFO_SIZE-2) {
5733731a334SAlan Ott 		dev_err(printdev(devrec), "write_tx_buf() was passed too large a buffer. Performing short write.\n");
5743731a334SAlan Ott 		length = TX_FIFO_SIZE-2;
5753731a334SAlan Ott 	}
5763731a334SAlan Ott 
5773731a334SAlan Ott 	cmd = MRF24J40_WRITELONG(reg);
5786844a0e4SAlexander Aring 	devrec->tx_hdr_buf[0] = cmd >> 8 & 0xff;
5796844a0e4SAlexander Aring 	devrec->tx_hdr_buf[1] = cmd & 0xff;
5806844a0e4SAlexander Aring 	devrec->tx_len_buf[0] = 0x0; /* Header Length. Set to 0 for now. TODO */
5816844a0e4SAlexander Aring 	devrec->tx_len_buf[1] = length; /* Total length */
5826844a0e4SAlexander Aring 	devrec->tx_buf_trx.tx_buf = data;
5836844a0e4SAlexander Aring 	devrec->tx_buf_trx.len = length;
5843731a334SAlan Ott 
5856844a0e4SAlexander Aring 	ret = spi_async(devrec->spi, &devrec->tx_msg);
5863731a334SAlan Ott 	if (ret)
5873731a334SAlan Ott 		dev_err(printdev(devrec), "SPI write Failed for TX buf\n");
5883731a334SAlan Ott 
5893731a334SAlan Ott 	return ret;
5903731a334SAlan Ott }
5913731a334SAlan Ott 
mrf24j40_tx(struct ieee802154_hw * hw,struct sk_buff * skb)5926844a0e4SAlexander Aring static int mrf24j40_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
5936844a0e4SAlexander Aring {
5946844a0e4SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
5956844a0e4SAlexander Aring 
5966844a0e4SAlexander Aring 	dev_dbg(printdev(devrec), "tx packet of %d bytes\n", skb->len);
5976844a0e4SAlexander Aring 	devrec->tx_skb = skb;
5986844a0e4SAlexander Aring 
5996844a0e4SAlexander Aring 	return write_tx_buf(devrec, 0x000, skb->data, skb->len);
6006844a0e4SAlexander Aring }
6016844a0e4SAlexander Aring 
mrf24j40_ed(struct ieee802154_hw * hw,u8 * level)6025a504397SAlexander Aring static int mrf24j40_ed(struct ieee802154_hw *hw, u8 *level)
6033731a334SAlan Ott {
6043731a334SAlan Ott 	/* TODO: */
605ca079ad6SVarka Bhadram 	pr_warn("mrf24j40: ed not implemented\n");
6063731a334SAlan Ott 	*level = 0;
6073731a334SAlan Ott 	return 0;
6083731a334SAlan Ott }
6093731a334SAlan Ott 
mrf24j40_start(struct ieee802154_hw * hw)6105a504397SAlexander Aring static int mrf24j40_start(struct ieee802154_hw *hw)
6113731a334SAlan Ott {
6125a504397SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
6133731a334SAlan Ott 
6143731a334SAlan Ott 	dev_dbg(printdev(devrec), "start\n");
6153731a334SAlan Ott 
61642c7148eSAlexander Aring 	/* Clear TXNIE and RXIE. Enable interrupts */
61742c7148eSAlexander Aring 	return regmap_update_bits(devrec->regmap_short, REG_INTCON,
6185a62f3c6SAlexandre Macabies 				  BIT_TXNIE | BIT_RXIE | BIT_SECIE, 0);
6193731a334SAlan Ott }
6203731a334SAlan Ott 
mrf24j40_stop(struct ieee802154_hw * hw)6215a504397SAlexander Aring static void mrf24j40_stop(struct ieee802154_hw *hw)
6223731a334SAlan Ott {
6235a504397SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
624529160dcSVarka Bhadram 
6253731a334SAlan Ott 	dev_dbg(printdev(devrec), "stop\n");
6263731a334SAlan Ott 
62742c7148eSAlexander Aring 	/* Set TXNIE and RXIE. Disable Interrupts */
6287d840545SAlexander Aring 	regmap_update_bits(devrec->regmap_short, REG_INTCON,
6290be7fc7eSGustavo A. R. Silva 			   BIT_TXNIE | BIT_RXIE, BIT_TXNIE | BIT_RXIE);
6303731a334SAlan Ott }
6313731a334SAlan Ott 
mrf24j40_set_channel(struct ieee802154_hw * hw,u8 page,u8 channel)632e37d2ec8SAlexander Aring static int mrf24j40_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
6333731a334SAlan Ott {
6345a504397SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
6353731a334SAlan Ott 	u8 val;
6363731a334SAlan Ott 	int ret;
6373731a334SAlan Ott 
6383731a334SAlan Ott 	dev_dbg(printdev(devrec), "Set Channel %d\n", channel);
6393731a334SAlan Ott 
6403731a334SAlan Ott 	WARN_ON(page != 0);
6413731a334SAlan Ott 	WARN_ON(channel < MRF24J40_CHAN_MIN);
6423731a334SAlan Ott 	WARN_ON(channel > MRF24J40_CHAN_MAX);
6433731a334SAlan Ott 
6443731a334SAlan Ott 	/* Set Channel TODO */
6457d840545SAlexander Aring 	val = (channel - 11) << RFCON0_CH_SHIFT | RFOPT_RECOMMEND;
6467d840545SAlexander Aring 	ret = regmap_update_bits(devrec->regmap_long, REG_RFCON0,
6477d840545SAlexander Aring 				 RFCON0_CH_MASK, val);
6483731a334SAlan Ott 	if (ret)
6493731a334SAlan Ott 		return ret;
6503731a334SAlan Ott 
65142c7148eSAlexander Aring 	/* RF Reset */
6527d840545SAlexander Aring 	ret = regmap_update_bits(devrec->regmap_short, REG_RFCTL, BIT_RFRST,
6537d840545SAlexander Aring 				 BIT_RFRST);
65442c7148eSAlexander Aring 	if (ret)
65542c7148eSAlexander Aring 		return ret;
65642c7148eSAlexander Aring 
6577d840545SAlexander Aring 	ret = regmap_update_bits(devrec->regmap_short, REG_RFCTL, BIT_RFRST, 0);
65842c7148eSAlexander Aring 	if (!ret)
6593731a334SAlan Ott 		udelay(SET_CHANNEL_DELAY_US); /* per datasheet */
6603731a334SAlan Ott 
66142c7148eSAlexander Aring 	return ret;
6623731a334SAlan Ott }
6633731a334SAlan Ott 
mrf24j40_filter(struct ieee802154_hw * hw,struct ieee802154_hw_addr_filt * filt,unsigned long changed)6645a504397SAlexander Aring static int mrf24j40_filter(struct ieee802154_hw *hw,
6653731a334SAlan Ott 			   struct ieee802154_hw_addr_filt *filt,
6663731a334SAlan Ott 			   unsigned long changed)
6673731a334SAlan Ott {
6685a504397SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
6693731a334SAlan Ott 
6703731a334SAlan Ott 	dev_dbg(printdev(devrec), "filter\n");
6713731a334SAlan Ott 
67257205c14SAlexander Aring 	if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
6733731a334SAlan Ott 		/* Short Addr */
6743731a334SAlan Ott 		u8 addrh, addrl;
675529160dcSVarka Bhadram 
676b70ab2e8SPhoebe Buckheister 		addrh = le16_to_cpu(filt->short_addr) >> 8 & 0xff;
677b70ab2e8SPhoebe Buckheister 		addrl = le16_to_cpu(filt->short_addr) & 0xff;
6783731a334SAlan Ott 
67942c7148eSAlexander Aring 		regmap_write(devrec->regmap_short, REG_SADRH, addrh);
68042c7148eSAlexander Aring 		regmap_write(devrec->regmap_short, REG_SADRL, addrl);
6813731a334SAlan Ott 		dev_dbg(printdev(devrec),
6823731a334SAlan Ott 			"Set short addr to %04hx\n", filt->short_addr);
6833731a334SAlan Ott 	}
6843731a334SAlan Ott 
68557205c14SAlexander Aring 	if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
6863731a334SAlan Ott 		/* Device Address */
687b70ab2e8SPhoebe Buckheister 		u8 i, addr[8];
688b70ab2e8SPhoebe Buckheister 
689b70ab2e8SPhoebe Buckheister 		memcpy(addr, &filt->ieee_addr, 8);
6903731a334SAlan Ott 		for (i = 0; i < 8; i++)
69142c7148eSAlexander Aring 			regmap_write(devrec->regmap_short, REG_EADR0 + i,
69242c7148eSAlexander Aring 				     addr[i]);
6933731a334SAlan Ott 
6943731a334SAlan Ott #ifdef DEBUG
695ca079ad6SVarka Bhadram 		pr_debug("Set long addr to: ");
6963731a334SAlan Ott 		for (i = 0; i < 8; i++)
697ca079ad6SVarka Bhadram 			pr_debug("%02hhx ", addr[7 - i]);
698ca079ad6SVarka Bhadram 		pr_debug("\n");
6993731a334SAlan Ott #endif
7003731a334SAlan Ott 	}
7013731a334SAlan Ott 
70257205c14SAlexander Aring 	if (changed & IEEE802154_AFILT_PANID_CHANGED) {
7033731a334SAlan Ott 		/* PAN ID */
7043731a334SAlan Ott 		u8 panidl, panidh;
705529160dcSVarka Bhadram 
706b70ab2e8SPhoebe Buckheister 		panidh = le16_to_cpu(filt->pan_id) >> 8 & 0xff;
707b70ab2e8SPhoebe Buckheister 		panidl = le16_to_cpu(filt->pan_id) & 0xff;
70842c7148eSAlexander Aring 		regmap_write(devrec->regmap_short, REG_PANIDH, panidh);
70942c7148eSAlexander Aring 		regmap_write(devrec->regmap_short, REG_PANIDL, panidl);
7103731a334SAlan Ott 
7113731a334SAlan Ott 		dev_dbg(printdev(devrec), "Set PANID to %04hx\n", filt->pan_id);
7123731a334SAlan Ott 	}
7133731a334SAlan Ott 
71457205c14SAlexander Aring 	if (changed & IEEE802154_AFILT_PANC_CHANGED) {
7153731a334SAlan Ott 		/* Pan Coordinator */
7163731a334SAlan Ott 		u8 val;
7173731a334SAlan Ott 		int ret;
7183731a334SAlan Ott 
71942c7148eSAlexander Aring 		if (filt->pan_coord)
7207d840545SAlexander Aring 			val = BIT_PANCOORD;
72142c7148eSAlexander Aring 		else
7227d840545SAlexander Aring 			val = 0;
7237d840545SAlexander Aring 		ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR,
7247d840545SAlexander Aring 					 BIT_PANCOORD, val);
7253731a334SAlan Ott 		if (ret)
7263731a334SAlan Ott 			return ret;
7273731a334SAlan Ott 
7283731a334SAlan Ott 		/* REG_SLOTTED is maintained as default (unslotted/CSMA-CA).
7293731a334SAlan Ott 		 * REG_ORDER is maintained as default (no beacon/superframe).
7303731a334SAlan Ott 		 */
7313731a334SAlan Ott 
7323731a334SAlan Ott 		dev_dbg(printdev(devrec), "Set Pan Coord to %s\n",
7333731a334SAlan Ott 			filt->pan_coord ? "on" : "off");
7343731a334SAlan Ott 	}
7353731a334SAlan Ott 
7363731a334SAlan Ott 	return 0;
7373731a334SAlan Ott }
7383731a334SAlan Ott 
mrf24j40_handle_rx_read_buf_unlock(struct mrf24j40 * devrec)739c91a3011SAlexander Aring static void mrf24j40_handle_rx_read_buf_unlock(struct mrf24j40 *devrec)
7403731a334SAlan Ott {
741c91a3011SAlexander Aring 	int ret;
742c91a3011SAlexander Aring 
743c91a3011SAlexander Aring 	/* Turn back on reception of packets off the air. */
744c91a3011SAlexander Aring 	devrec->rx_msg.complete = NULL;
745c91a3011SAlexander Aring 	devrec->rx_buf[0] = MRF24J40_WRITESHORT(REG_BBREG1);
746c91a3011SAlexander Aring 	devrec->rx_buf[1] = 0x00; /* CLR RXDECINV */
747c91a3011SAlexander Aring 	ret = spi_async(devrec->spi, &devrec->rx_msg);
748c91a3011SAlexander Aring 	if (ret)
749c91a3011SAlexander Aring 		dev_err(printdev(devrec), "failed to unlock rx buffer\n");
750c91a3011SAlexander Aring }
751c91a3011SAlexander Aring 
mrf24j40_handle_rx_read_buf_complete(void * context)752c91a3011SAlexander Aring static void mrf24j40_handle_rx_read_buf_complete(void *context)
753c91a3011SAlexander Aring {
754c91a3011SAlexander Aring 	struct mrf24j40 *devrec = context;
755c91a3011SAlexander Aring 	u8 len = devrec->rx_buf[2];
756c91a3011SAlexander Aring 	u8 rx_local_buf[RX_FIFO_SIZE];
7573731a334SAlan Ott 	struct sk_buff *skb;
7583731a334SAlan Ott 
759c91a3011SAlexander Aring 	memcpy(rx_local_buf, devrec->rx_fifo_buf, len);
760c91a3011SAlexander Aring 	mrf24j40_handle_rx_read_buf_unlock(devrec);
7613731a334SAlan Ott 
762c91a3011SAlexander Aring 	skb = dev_alloc_skb(IEEE802154_MTU);
7633731a334SAlan Ott 	if (!skb) {
764c91a3011SAlexander Aring 		dev_err(printdev(devrec), "failed to allocate skb\n");
765c91a3011SAlexander Aring 		return;
7663731a334SAlan Ott 	}
7673731a334SAlan Ott 
76859ae1d12SJohannes Berg 	skb_put_data(skb, rx_local_buf, len);
769c91a3011SAlexander Aring 	ieee802154_rx_irqsafe(devrec->hw, skb, 0);
770c91a3011SAlexander Aring 
771c91a3011SAlexander Aring #ifdef DEBUG
772c91a3011SAlexander Aring 	 print_hex_dump(KERN_DEBUG, "mrf24j40 rx: ", DUMP_PREFIX_OFFSET, 16, 1,
773c91a3011SAlexander Aring 			rx_local_buf, len, 0);
774c91a3011SAlexander Aring 	 pr_debug("mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n",
775c91a3011SAlexander Aring 		  devrec->rx_lqi_buf[0], devrec->rx_lqi_buf[1]);
776c91a3011SAlexander Aring #endif
7773731a334SAlan Ott }
7783731a334SAlan Ott 
mrf24j40_handle_rx_read_buf(void * context)779c91a3011SAlexander Aring static void mrf24j40_handle_rx_read_buf(void *context)
780c91a3011SAlexander Aring {
781c91a3011SAlexander Aring 	struct mrf24j40 *devrec = context;
782c91a3011SAlexander Aring 	u16 cmd;
783c91a3011SAlexander Aring 	int ret;
7843731a334SAlan Ott 
785c91a3011SAlexander Aring 	/* if length is invalid read the full MTU */
786c91a3011SAlexander Aring 	if (!ieee802154_is_valid_psdu_len(devrec->rx_buf[2]))
787c91a3011SAlexander Aring 		devrec->rx_buf[2] = IEEE802154_MTU;
7883731a334SAlan Ott 
789c91a3011SAlexander Aring 	cmd = MRF24J40_READLONG(REG_RX_FIFO + 1);
790c91a3011SAlexander Aring 	devrec->rx_addr_buf[0] = cmd >> 8 & 0xff;
791c91a3011SAlexander Aring 	devrec->rx_addr_buf[1] = cmd & 0xff;
792c91a3011SAlexander Aring 	devrec->rx_fifo_buf_trx.len = devrec->rx_buf[2];
793c91a3011SAlexander Aring 	ret = spi_async(devrec->spi, &devrec->rx_buf_msg);
794c91a3011SAlexander Aring 	if (ret) {
795c91a3011SAlexander Aring 		dev_err(printdev(devrec), "failed to read rx buffer\n");
796c91a3011SAlexander Aring 		mrf24j40_handle_rx_read_buf_unlock(devrec);
797c91a3011SAlexander Aring 	}
798c91a3011SAlexander Aring }
7993731a334SAlan Ott 
mrf24j40_handle_rx_read_len(void * context)800c91a3011SAlexander Aring static void mrf24j40_handle_rx_read_len(void *context)
801c91a3011SAlexander Aring {
802c91a3011SAlexander Aring 	struct mrf24j40 *devrec = context;
803c91a3011SAlexander Aring 	u16 cmd;
804c91a3011SAlexander Aring 	int ret;
805c91a3011SAlexander Aring 
806c91a3011SAlexander Aring 	/* read the length of received frame */
807c91a3011SAlexander Aring 	devrec->rx_msg.complete = mrf24j40_handle_rx_read_buf;
808c91a3011SAlexander Aring 	devrec->rx_trx.len = 3;
809c91a3011SAlexander Aring 	cmd = MRF24J40_READLONG(REG_RX_FIFO);
810c91a3011SAlexander Aring 	devrec->rx_buf[0] = cmd >> 8 & 0xff;
811c91a3011SAlexander Aring 	devrec->rx_buf[1] = cmd & 0xff;
812c91a3011SAlexander Aring 
813c91a3011SAlexander Aring 	ret = spi_async(devrec->spi, &devrec->rx_msg);
814c91a3011SAlexander Aring 	if (ret) {
815c91a3011SAlexander Aring 		dev_err(printdev(devrec), "failed to read rx buffer length\n");
816c91a3011SAlexander Aring 		mrf24j40_handle_rx_read_buf_unlock(devrec);
817c91a3011SAlexander Aring 	}
818c91a3011SAlexander Aring }
819c91a3011SAlexander Aring 
mrf24j40_handle_rx(struct mrf24j40 * devrec)820c91a3011SAlexander Aring static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
821c91a3011SAlexander Aring {
822c91a3011SAlexander Aring 	/* Turn off reception of packets off the air. This prevents the
823c91a3011SAlexander Aring 	 * device from overwriting the buffer while we're reading it.
824c91a3011SAlexander Aring 	 */
825c91a3011SAlexander Aring 	devrec->rx_msg.complete = mrf24j40_handle_rx_read_len;
826c91a3011SAlexander Aring 	devrec->rx_trx.len = 2;
827c91a3011SAlexander Aring 	devrec->rx_buf[0] = MRF24J40_WRITESHORT(REG_BBREG1);
8287d840545SAlexander Aring 	devrec->rx_buf[1] = BIT_RXDECINV; /* SET RXDECINV */
829c91a3011SAlexander Aring 
830c91a3011SAlexander Aring 	return spi_async(devrec->spi, &devrec->rx_msg);
8313731a334SAlan Ott }
8323731a334SAlan Ott 
8332323cf38SAlexander Aring static int
mrf24j40_csma_params(struct ieee802154_hw * hw,u8 min_be,u8 max_be,u8 retries)8342323cf38SAlexander Aring mrf24j40_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be,
8352323cf38SAlexander Aring 		     u8 retries)
8362323cf38SAlexander Aring {
8372323cf38SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
8382323cf38SAlexander Aring 	u8 val;
8392323cf38SAlexander Aring 
8402323cf38SAlexander Aring 	/* min_be */
8417d840545SAlexander Aring 	val = min_be << TXMCR_MIN_BE_SHIFT;
8422323cf38SAlexander Aring 	/* csma backoffs */
8437d840545SAlexander Aring 	val |= retries << TXMCR_CSMA_RETRIES_SHIFT;
8442323cf38SAlexander Aring 
8457d840545SAlexander Aring 	return regmap_update_bits(devrec->regmap_short, REG_TXMCR,
8467d840545SAlexander Aring 				  TXMCR_MIN_BE_MASK | TXMCR_CSMA_RETRIES_MASK,
8477d840545SAlexander Aring 				  val);
8482323cf38SAlexander Aring }
8492323cf38SAlexander Aring 
mrf24j40_set_cca_mode(struct ieee802154_hw * hw,const struct wpan_phy_cca * cca)850f1d78127SAlexander Aring static int mrf24j40_set_cca_mode(struct ieee802154_hw *hw,
851f1d78127SAlexander Aring 				 const struct wpan_phy_cca *cca)
852f1d78127SAlexander Aring {
853f1d78127SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
854f1d78127SAlexander Aring 	u8 val;
855f1d78127SAlexander Aring 
856f1d78127SAlexander Aring 	/* mapping 802.15.4 to driver spec */
857f1d78127SAlexander Aring 	switch (cca->mode) {
858f1d78127SAlexander Aring 	case NL802154_CCA_ENERGY:
859f1d78127SAlexander Aring 		val = 2;
860f1d78127SAlexander Aring 		break;
861f1d78127SAlexander Aring 	case NL802154_CCA_CARRIER:
862f1d78127SAlexander Aring 		val = 1;
863f1d78127SAlexander Aring 		break;
864f1d78127SAlexander Aring 	case NL802154_CCA_ENERGY_CARRIER:
865f1d78127SAlexander Aring 		switch (cca->opt) {
866f1d78127SAlexander Aring 		case NL802154_CCA_OPT_ENERGY_CARRIER_AND:
867f1d78127SAlexander Aring 			val = 3;
868f1d78127SAlexander Aring 			break;
869f1d78127SAlexander Aring 		default:
870f1d78127SAlexander Aring 			return -EINVAL;
871f1d78127SAlexander Aring 		}
872f1d78127SAlexander Aring 		break;
873f1d78127SAlexander Aring 	default:
874f1d78127SAlexander Aring 		return -EINVAL;
875f1d78127SAlexander Aring 	}
876f1d78127SAlexander Aring 
8777d840545SAlexander Aring 	return regmap_update_bits(devrec->regmap_short, REG_BBREG2,
8787d840545SAlexander Aring 				  BBREG2_CCA_MODE_MASK,
8797d840545SAlexander Aring 				  val << BBREG2_CCA_MODE_SHIFT);
880f1d78127SAlexander Aring }
881f1d78127SAlexander Aring 
882e33a0f96SAlexander Aring /* array for representing ed levels */
883e33a0f96SAlexander Aring static const s32 mrf24j40_ed_levels[] = {
884e33a0f96SAlexander Aring 	-9000, -8900, -8800, -8700, -8600, -8500, -8400, -8300, -8200, -8100,
885e33a0f96SAlexander Aring 	-8000, -7900, -7800, -7700, -7600, -7500, -7400, -7300, -7200, -7100,
886e33a0f96SAlexander Aring 	-7000, -6900, -6800, -6700, -6600, -6500, -6400, -6300, -6200, -6100,
887e33a0f96SAlexander Aring 	-6000, -5900, -5800, -5700, -5600, -5500, -5400, -5300, -5200, -5100,
888e33a0f96SAlexander Aring 	-5000, -4900, -4800, -4700, -4600, -4500, -4400, -4300, -4200, -4100,
889e33a0f96SAlexander Aring 	-4000, -3900, -3800, -3700, -3600, -3500
890e33a0f96SAlexander Aring };
891e33a0f96SAlexander Aring 
892e33a0f96SAlexander Aring /* map ed levels to register value */
893e33a0f96SAlexander Aring static const s32 mrf24j40_ed_levels_map[][2] = {
894e33a0f96SAlexander Aring 	{ -9000, 0 }, { -8900, 1 }, { -8800, 2 }, { -8700, 5 }, { -8600, 9 },
895e33a0f96SAlexander Aring 	{ -8500, 13 }, { -8400, 18 }, { -8300, 23 }, { -8200, 27 },
896e33a0f96SAlexander Aring 	{ -8100, 32 }, { -8000, 37 }, { -7900, 43 }, { -7800, 48 },
897e33a0f96SAlexander Aring 	{ -7700, 53 }, { -7600, 58 }, { -7500, 63 }, { -7400, 68 },
898e33a0f96SAlexander Aring 	{ -7300, 73 }, { -7200, 78 }, { -7100, 83 }, { -7000, 89 },
899e33a0f96SAlexander Aring 	{ -6900, 95 }, { -6800, 100 }, { -6700, 107 }, { -6600, 111 },
900e33a0f96SAlexander Aring 	{ -6500, 117 }, { -6400, 121 }, { -6300, 125 }, { -6200, 129 },
901e33a0f96SAlexander Aring 	{ -6100, 133 },	{ -6000, 138 }, { -5900, 143 }, { -5800, 148 },
902e33a0f96SAlexander Aring 	{ -5700, 153 }, { -5600, 159 },	{ -5500, 165 }, { -5400, 170 },
903e33a0f96SAlexander Aring 	{ -5300, 176 }, { -5200, 183 }, { -5100, 188 }, { -5000, 193 },
904e33a0f96SAlexander Aring 	{ -4900, 198 }, { -4800, 203 }, { -4700, 207 }, { -4600, 212 },
905e33a0f96SAlexander Aring 	{ -4500, 216 }, { -4400, 221 }, { -4300, 225 }, { -4200, 228 },
906e33a0f96SAlexander Aring 	{ -4100, 233 }, { -4000, 239 }, { -3900, 245 }, { -3800, 250 },
907e33a0f96SAlexander Aring 	{ -3700, 253 }, { -3600, 254 }, { -3500, 255 },
908e33a0f96SAlexander Aring };
909e33a0f96SAlexander Aring 
mrf24j40_set_cca_ed_level(struct ieee802154_hw * hw,s32 mbm)910e33a0f96SAlexander Aring static int mrf24j40_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
911e33a0f96SAlexander Aring {
912e33a0f96SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
913e33a0f96SAlexander Aring 	int i;
914e33a0f96SAlexander Aring 
915e33a0f96SAlexander Aring 	for (i = 0; i < ARRAY_SIZE(mrf24j40_ed_levels_map); i++) {
916e33a0f96SAlexander Aring 		if (mrf24j40_ed_levels_map[i][0] == mbm)
917e33a0f96SAlexander Aring 			return regmap_write(devrec->regmap_short, REG_CCAEDTH,
918e33a0f96SAlexander Aring 					    mrf24j40_ed_levels_map[i][1]);
919e33a0f96SAlexander Aring 	}
920e33a0f96SAlexander Aring 
921e33a0f96SAlexander Aring 	return -EINVAL;
922e33a0f96SAlexander Aring }
923e33a0f96SAlexander Aring 
92400250f78SAlexander Aring static const s32 mrf24j40ma_powers[] = {
92500250f78SAlexander Aring 	0, -50, -120, -190, -280, -370, -490, -630, -1000, -1050, -1120, -1190,
92600250f78SAlexander Aring 	-1280, -1370, -1490, -1630, -2000, -2050, -2120, -2190, -2280, -2370,
92700250f78SAlexander Aring 	-2490, -2630, -3000, -3050, -3120, -3190, -3280, -3370, -3490, -3630,
92800250f78SAlexander Aring };
92900250f78SAlexander Aring 
mrf24j40_set_txpower(struct ieee802154_hw * hw,s32 mbm)93000250f78SAlexander Aring static int mrf24j40_set_txpower(struct ieee802154_hw *hw, s32 mbm)
93100250f78SAlexander Aring {
93200250f78SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
93300250f78SAlexander Aring 	s32 small_scale;
93400250f78SAlexander Aring 	u8 val;
93500250f78SAlexander Aring 
93600250f78SAlexander Aring 	if (0 >= mbm && mbm > -1000) {
9377d840545SAlexander Aring 		val = TXPWRL_0 << TXPWRL_SHIFT;
93800250f78SAlexander Aring 		small_scale = mbm;
93900250f78SAlexander Aring 	} else if (-1000 >= mbm && mbm > -2000) {
9407d840545SAlexander Aring 		val = TXPWRL_10 << TXPWRL_SHIFT;
94100250f78SAlexander Aring 		small_scale = mbm + 1000;
94200250f78SAlexander Aring 	} else if (-2000 >= mbm && mbm > -3000) {
9437d840545SAlexander Aring 		val = TXPWRL_20 << TXPWRL_SHIFT;
94400250f78SAlexander Aring 		small_scale = mbm + 2000;
94500250f78SAlexander Aring 	} else if (-3000 >= mbm && mbm > -4000) {
9467d840545SAlexander Aring 		val = TXPWRL_30 << TXPWRL_SHIFT;
94700250f78SAlexander Aring 		small_scale = mbm + 3000;
94800250f78SAlexander Aring 	} else {
94900250f78SAlexander Aring 		return -EINVAL;
95000250f78SAlexander Aring 	}
95100250f78SAlexander Aring 
95200250f78SAlexander Aring 	switch (small_scale) {
95300250f78SAlexander Aring 	case 0:
9547d840545SAlexander Aring 		val |= (TXPWRS_0 << TXPWRS_SHIFT);
95500250f78SAlexander Aring 		break;
95600250f78SAlexander Aring 	case -50:
9577d840545SAlexander Aring 		val |= (TXPWRS_0_5 << TXPWRS_SHIFT);
95800250f78SAlexander Aring 		break;
95900250f78SAlexander Aring 	case -120:
9607d840545SAlexander Aring 		val |= (TXPWRS_1_2 << TXPWRS_SHIFT);
96100250f78SAlexander Aring 		break;
96200250f78SAlexander Aring 	case -190:
9637d840545SAlexander Aring 		val |= (TXPWRS_1_9 << TXPWRS_SHIFT);
96400250f78SAlexander Aring 		break;
96500250f78SAlexander Aring 	case -280:
9667d840545SAlexander Aring 		val |= (TXPWRS_2_8 << TXPWRS_SHIFT);
96700250f78SAlexander Aring 		break;
96800250f78SAlexander Aring 	case -370:
9697d840545SAlexander Aring 		val |= (TXPWRS_3_7 << TXPWRS_SHIFT);
97000250f78SAlexander Aring 		break;
97100250f78SAlexander Aring 	case -490:
9727d840545SAlexander Aring 		val |= (TXPWRS_4_9 << TXPWRS_SHIFT);
97300250f78SAlexander Aring 		break;
97400250f78SAlexander Aring 	case -630:
9757d840545SAlexander Aring 		val |= (TXPWRS_6_3 << TXPWRS_SHIFT);
97600250f78SAlexander Aring 		break;
97700250f78SAlexander Aring 	default:
97800250f78SAlexander Aring 		return -EINVAL;
97900250f78SAlexander Aring 	}
98000250f78SAlexander Aring 
9817d840545SAlexander Aring 	return regmap_update_bits(devrec->regmap_long, REG_RFCON3,
9827d840545SAlexander Aring 				  TXPWRL_MASK | TXPWRS_MASK, val);
98300250f78SAlexander Aring }
98400250f78SAlexander Aring 
mrf24j40_set_promiscuous_mode(struct ieee802154_hw * hw,bool on)9858ba40417SAlexander Aring static int mrf24j40_set_promiscuous_mode(struct ieee802154_hw *hw, bool on)
9868ba40417SAlexander Aring {
9878ba40417SAlexander Aring 	struct mrf24j40 *devrec = hw->priv;
9888ba40417SAlexander Aring 	int ret;
9898ba40417SAlexander Aring 
9908ba40417SAlexander Aring 	if (on) {
9918ba40417SAlexander Aring 		/* set PROMI, ERRPKT and NOACKRSP */
9927d840545SAlexander Aring 		ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR,
9937d840545SAlexander Aring 					 BIT_PROMI | BIT_ERRPKT | BIT_NOACKRSP,
9947d840545SAlexander Aring 					 BIT_PROMI | BIT_ERRPKT | BIT_NOACKRSP);
9958ba40417SAlexander Aring 	} else {
9968ba40417SAlexander Aring 		/* clear PROMI, ERRPKT and NOACKRSP */
9977d840545SAlexander Aring 		ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR,
9987d840545SAlexander Aring 					 BIT_PROMI | BIT_ERRPKT | BIT_NOACKRSP,
9997d840545SAlexander Aring 					 0);
10008ba40417SAlexander Aring 	}
10018ba40417SAlexander Aring 
10028ba40417SAlexander Aring 	return ret;
10038ba40417SAlexander Aring }
10048ba40417SAlexander Aring 
100516301861SAlexander Aring static const struct ieee802154_ops mrf24j40_ops = {
10063731a334SAlan Ott 	.owner = THIS_MODULE,
10076844a0e4SAlexander Aring 	.xmit_async = mrf24j40_tx,
10083731a334SAlan Ott 	.ed = mrf24j40_ed,
10093731a334SAlan Ott 	.start = mrf24j40_start,
10103731a334SAlan Ott 	.stop = mrf24j40_stop,
10113731a334SAlan Ott 	.set_channel = mrf24j40_set_channel,
10123731a334SAlan Ott 	.set_hw_addr_filt = mrf24j40_filter,
10132323cf38SAlexander Aring 	.set_csma_params = mrf24j40_csma_params,
1014f1d78127SAlexander Aring 	.set_cca_mode = mrf24j40_set_cca_mode,
1015e33a0f96SAlexander Aring 	.set_cca_ed_level = mrf24j40_set_cca_ed_level,
101600250f78SAlexander Aring 	.set_txpower = mrf24j40_set_txpower,
10178ba40417SAlexander Aring 	.set_promiscuous_mode = mrf24j40_set_promiscuous_mode,
10183731a334SAlan Ott };
10193731a334SAlan Ott 
mrf24j40_intstat_complete(void * context)102037441611SAlexander Aring static void mrf24j40_intstat_complete(void *context)
10213731a334SAlan Ott {
102237441611SAlexander Aring 	struct mrf24j40 *devrec = context;
102337441611SAlexander Aring 	u8 intstat = devrec->irq_buf[1];
10243731a334SAlan Ott 
102537441611SAlexander Aring 	enable_irq(devrec->spi->irq);
10263731a334SAlan Ott 
10275a62f3c6SAlexandre Macabies 	/* Ignore Rx security decryption */
10285a62f3c6SAlexandre Macabies 	if (intstat & BIT_SECIF)
10295a62f3c6SAlexandre Macabies 		regmap_write_async(devrec->regmap_short, REG_SECCON0,
10305a62f3c6SAlexandre Macabies 				   BIT_SECIGNORE);
10315a62f3c6SAlexandre Macabies 
10323731a334SAlan Ott 	/* Check for TX complete */
10337d840545SAlexander Aring 	if (intstat & BIT_TXNIF)
10346844a0e4SAlexander Aring 		ieee802154_xmit_complete(devrec->hw, devrec->tx_skb, false);
10353731a334SAlan Ott 
10363731a334SAlan Ott 	/* Check for Rx */
10377d840545SAlexander Aring 	if (intstat & BIT_RXIF)
10383731a334SAlan Ott 		mrf24j40_handle_rx(devrec);
103937441611SAlexander Aring }
10403731a334SAlan Ott 
mrf24j40_isr(int irq,void * data)104137441611SAlexander Aring static irqreturn_t mrf24j40_isr(int irq, void *data)
104237441611SAlexander Aring {
104337441611SAlexander Aring 	struct mrf24j40 *devrec = data;
104437441611SAlexander Aring 	int ret;
104537441611SAlexander Aring 
104637441611SAlexander Aring 	disable_irq_nosync(irq);
104737441611SAlexander Aring 
104837441611SAlexander Aring 	devrec->irq_buf[0] = MRF24J40_READSHORT(REG_INTSTAT);
10493faf5643SWalter Mack 	devrec->irq_buf[1] = 0;
10503faf5643SWalter Mack 
105137441611SAlexander Aring 	/* Read the interrupt status */
105237441611SAlexander Aring 	ret = spi_async(devrec->spi, &devrec->irq_msg);
105337441611SAlexander Aring 	if (ret) {
105437441611SAlexander Aring 		enable_irq(irq);
105537441611SAlexander Aring 		return IRQ_NONE;
105637441611SAlexander Aring 	}
105737441611SAlexander Aring 
10584a4e1da8SAlan Ott 	return IRQ_HANDLED;
10593731a334SAlan Ott }
10603731a334SAlan Ott 
mrf24j40_hw_init(struct mrf24j40 * devrec)10613dac9a79SVarka Bhadram static int mrf24j40_hw_init(struct mrf24j40 *devrec)
10623dac9a79SVarka Bhadram {
1063afaf7fdeSAlexander Aring 	u32 irq_type;
10643dac9a79SVarka Bhadram 	int ret;
10653dac9a79SVarka Bhadram 
10663dac9a79SVarka Bhadram 	/* Initialize the device.
10673dac9a79SVarka Bhadram 		From datasheet section 3.2: Initialization. */
106842c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_short, REG_SOFTRST, 0x07);
10693dac9a79SVarka Bhadram 	if (ret)
10703dac9a79SVarka Bhadram 		goto err_ret;
10713dac9a79SVarka Bhadram 
107242c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_short, REG_PACON2, 0x98);
10733dac9a79SVarka Bhadram 	if (ret)
10743dac9a79SVarka Bhadram 		goto err_ret;
10753dac9a79SVarka Bhadram 
107642c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_short, REG_TXSTBL, 0x95);
10773dac9a79SVarka Bhadram 	if (ret)
10783dac9a79SVarka Bhadram 		goto err_ret;
10793dac9a79SVarka Bhadram 
108042c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_long, REG_RFCON0, 0x03);
10813dac9a79SVarka Bhadram 	if (ret)
10823dac9a79SVarka Bhadram 		goto err_ret;
10833dac9a79SVarka Bhadram 
108442c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_long, REG_RFCON1, 0x01);
10853dac9a79SVarka Bhadram 	if (ret)
10863dac9a79SVarka Bhadram 		goto err_ret;
10873dac9a79SVarka Bhadram 
108842c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_long, REG_RFCON2, 0x80);
10893dac9a79SVarka Bhadram 	if (ret)
10903dac9a79SVarka Bhadram 		goto err_ret;
10913dac9a79SVarka Bhadram 
109242c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_long, REG_RFCON6, 0x90);
10933dac9a79SVarka Bhadram 	if (ret)
10943dac9a79SVarka Bhadram 		goto err_ret;
10953dac9a79SVarka Bhadram 
109642c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_long, REG_RFCON7, 0x80);
10973dac9a79SVarka Bhadram 	if (ret)
10983dac9a79SVarka Bhadram 		goto err_ret;
10993dac9a79SVarka Bhadram 
110042c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_long, REG_RFCON8, 0x10);
11013dac9a79SVarka Bhadram 	if (ret)
11023dac9a79SVarka Bhadram 		goto err_ret;
11033dac9a79SVarka Bhadram 
110442c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_long, REG_SLPCON1, 0x21);
11053dac9a79SVarka Bhadram 	if (ret)
11063dac9a79SVarka Bhadram 		goto err_ret;
11073dac9a79SVarka Bhadram 
110842c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_short, REG_BBREG2, 0x80);
11093dac9a79SVarka Bhadram 	if (ret)
11103dac9a79SVarka Bhadram 		goto err_ret;
11113dac9a79SVarka Bhadram 
111242c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_short, REG_CCAEDTH, 0x60);
11133dac9a79SVarka Bhadram 	if (ret)
11143dac9a79SVarka Bhadram 		goto err_ret;
11153dac9a79SVarka Bhadram 
111642c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_short, REG_BBREG6, 0x40);
11173dac9a79SVarka Bhadram 	if (ret)
11183dac9a79SVarka Bhadram 		goto err_ret;
11193dac9a79SVarka Bhadram 
112042c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_short, REG_RFCTL, 0x04);
11213dac9a79SVarka Bhadram 	if (ret)
11223dac9a79SVarka Bhadram 		goto err_ret;
11233dac9a79SVarka Bhadram 
112442c7148eSAlexander Aring 	ret = regmap_write(devrec->regmap_short, REG_RFCTL, 0x0);
11253dac9a79SVarka Bhadram 	if (ret)
11263dac9a79SVarka Bhadram 		goto err_ret;
11273dac9a79SVarka Bhadram 
11283dac9a79SVarka Bhadram 	udelay(192);
11293dac9a79SVarka Bhadram 
11303dac9a79SVarka Bhadram 	/* Set RX Mode. RXMCR<1:0>: 0x0 normal, 0x1 promisc, 0x2 error */
113142c7148eSAlexander Aring 	ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR, 0x03, 0x00);
11323dac9a79SVarka Bhadram 	if (ret)
11333dac9a79SVarka Bhadram 		goto err_ret;
11343dac9a79SVarka Bhadram 
1135db9e0ee8SSimon Vincent 	if (spi_get_device_id(devrec->spi)->driver_data == MRF24J40MC) {
1136db9e0ee8SSimon Vincent 		/* Enable external amplifier.
1137db9e0ee8SSimon Vincent 		 * From MRF24J40MC datasheet section 1.3: Operation.
1138db9e0ee8SSimon Vincent 		 */
113942c7148eSAlexander Aring 		regmap_update_bits(devrec->regmap_long, REG_TESTMODE, 0x07,
114042c7148eSAlexander Aring 				   0x07);
1141db9e0ee8SSimon Vincent 
114242c7148eSAlexander Aring 		/* Set GPIO3 as output. */
114342c7148eSAlexander Aring 		regmap_update_bits(devrec->regmap_short, REG_TRISGPIO, 0x08,
114442c7148eSAlexander Aring 				   0x08);
1145db9e0ee8SSimon Vincent 
114642c7148eSAlexander Aring 		/* Set GPIO3 HIGH to enable U5 voltage regulator */
114742c7148eSAlexander Aring 		regmap_update_bits(devrec->regmap_short, REG_GPIO, 0x08, 0x08);
1148db9e0ee8SSimon Vincent 
1149db9e0ee8SSimon Vincent 		/* Reduce TX pwr to meet FCC requirements.
1150db9e0ee8SSimon Vincent 		 * From MRF24J40MC datasheet section 3.1.1
1151db9e0ee8SSimon Vincent 		 */
115242c7148eSAlexander Aring 		regmap_write(devrec->regmap_long, REG_RFCON3, 0x28);
1153db9e0ee8SSimon Vincent 	}
1154db9e0ee8SSimon Vincent 
1155afaf7fdeSAlexander Aring 	irq_type = irq_get_trigger_type(devrec->spi->irq);
1156afaf7fdeSAlexander Aring 	if (irq_type == IRQ_TYPE_EDGE_RISING ||
1157afaf7fdeSAlexander Aring 	    irq_type == IRQ_TYPE_EDGE_FALLING)
1158afaf7fdeSAlexander Aring 		dev_warn(&devrec->spi->dev,
1159afaf7fdeSAlexander Aring 			 "Using edge triggered irq's are not recommended, because it can cause races and result in a non-functional driver!\n");
1160afaf7fdeSAlexander Aring 	switch (irq_type) {
1161afaf7fdeSAlexander Aring 	case IRQ_TYPE_EDGE_RISING:
1162afaf7fdeSAlexander Aring 	case IRQ_TYPE_LEVEL_HIGH:
1163afaf7fdeSAlexander Aring 		/* set interrupt polarity to rising */
1164afaf7fdeSAlexander Aring 		ret = regmap_update_bits(devrec->regmap_long, REG_SLPCON0,
11657d840545SAlexander Aring 					 BIT_INTEDGE, BIT_INTEDGE);
1166afaf7fdeSAlexander Aring 		if (ret)
1167afaf7fdeSAlexander Aring 			goto err_ret;
1168afaf7fdeSAlexander Aring 		break;
1169afaf7fdeSAlexander Aring 	default:
1170afaf7fdeSAlexander Aring 		/* default is falling edge */
1171afaf7fdeSAlexander Aring 		break;
1172afaf7fdeSAlexander Aring 	}
1173afaf7fdeSAlexander Aring 
11743dac9a79SVarka Bhadram 	return 0;
11753dac9a79SVarka Bhadram 
11763dac9a79SVarka Bhadram err_ret:
11773dac9a79SVarka Bhadram 	return ret;
11783dac9a79SVarka Bhadram }
11793dac9a79SVarka Bhadram 
11806844a0e4SAlexander Aring static void
mrf24j40_setup_tx_spi_messages(struct mrf24j40 * devrec)11816844a0e4SAlexander Aring mrf24j40_setup_tx_spi_messages(struct mrf24j40 *devrec)
11826844a0e4SAlexander Aring {
11836844a0e4SAlexander Aring 	spi_message_init(&devrec->tx_msg);
11846844a0e4SAlexander Aring 	devrec->tx_msg.context = devrec;
11856844a0e4SAlexander Aring 	devrec->tx_msg.complete = write_tx_buf_complete;
11866844a0e4SAlexander Aring 	devrec->tx_hdr_trx.len = 2;
11876844a0e4SAlexander Aring 	devrec->tx_hdr_trx.tx_buf = devrec->tx_hdr_buf;
11886844a0e4SAlexander Aring 	spi_message_add_tail(&devrec->tx_hdr_trx, &devrec->tx_msg);
11896844a0e4SAlexander Aring 	devrec->tx_len_trx.len = 2;
11906844a0e4SAlexander Aring 	devrec->tx_len_trx.tx_buf = devrec->tx_len_buf;
11916844a0e4SAlexander Aring 	spi_message_add_tail(&devrec->tx_len_trx, &devrec->tx_msg);
11926844a0e4SAlexander Aring 	spi_message_add_tail(&devrec->tx_buf_trx, &devrec->tx_msg);
11936844a0e4SAlexander Aring 
11946844a0e4SAlexander Aring 	spi_message_init(&devrec->tx_post_msg);
11956844a0e4SAlexander Aring 	devrec->tx_post_msg.context = devrec;
11966844a0e4SAlexander Aring 	devrec->tx_post_trx.len = 2;
11976844a0e4SAlexander Aring 	devrec->tx_post_trx.tx_buf = devrec->tx_post_buf;
11986844a0e4SAlexander Aring 	spi_message_add_tail(&devrec->tx_post_trx, &devrec->tx_post_msg);
11996844a0e4SAlexander Aring }
12006844a0e4SAlexander Aring 
1201c91a3011SAlexander Aring static void
mrf24j40_setup_rx_spi_messages(struct mrf24j40 * devrec)1202c91a3011SAlexander Aring mrf24j40_setup_rx_spi_messages(struct mrf24j40 *devrec)
1203c91a3011SAlexander Aring {
1204c91a3011SAlexander Aring 	spi_message_init(&devrec->rx_msg);
1205c91a3011SAlexander Aring 	devrec->rx_msg.context = devrec;
1206c91a3011SAlexander Aring 	devrec->rx_trx.len = 2;
1207c91a3011SAlexander Aring 	devrec->rx_trx.tx_buf = devrec->rx_buf;
1208c91a3011SAlexander Aring 	devrec->rx_trx.rx_buf = devrec->rx_buf;
1209c91a3011SAlexander Aring 	spi_message_add_tail(&devrec->rx_trx, &devrec->rx_msg);
1210c91a3011SAlexander Aring 
1211c91a3011SAlexander Aring 	spi_message_init(&devrec->rx_buf_msg);
1212c91a3011SAlexander Aring 	devrec->rx_buf_msg.context = devrec;
1213c91a3011SAlexander Aring 	devrec->rx_buf_msg.complete = mrf24j40_handle_rx_read_buf_complete;
1214c91a3011SAlexander Aring 	devrec->rx_addr_trx.len = 2;
1215c91a3011SAlexander Aring 	devrec->rx_addr_trx.tx_buf = devrec->rx_addr_buf;
1216c91a3011SAlexander Aring 	spi_message_add_tail(&devrec->rx_addr_trx, &devrec->rx_buf_msg);
1217c91a3011SAlexander Aring 	devrec->rx_fifo_buf_trx.rx_buf = devrec->rx_fifo_buf;
1218c91a3011SAlexander Aring 	spi_message_add_tail(&devrec->rx_fifo_buf_trx, &devrec->rx_buf_msg);
1219c91a3011SAlexander Aring 	devrec->rx_lqi_trx.len = 2;
1220c91a3011SAlexander Aring 	devrec->rx_lqi_trx.rx_buf = devrec->rx_lqi_buf;
1221c91a3011SAlexander Aring 	spi_message_add_tail(&devrec->rx_lqi_trx, &devrec->rx_buf_msg);
1222c91a3011SAlexander Aring }
1223c91a3011SAlexander Aring 
122437441611SAlexander Aring static void
mrf24j40_setup_irq_spi_messages(struct mrf24j40 * devrec)122537441611SAlexander Aring mrf24j40_setup_irq_spi_messages(struct mrf24j40 *devrec)
122637441611SAlexander Aring {
122737441611SAlexander Aring 	spi_message_init(&devrec->irq_msg);
122837441611SAlexander Aring 	devrec->irq_msg.context = devrec;
122937441611SAlexander Aring 	devrec->irq_msg.complete = mrf24j40_intstat_complete;
123037441611SAlexander Aring 	devrec->irq_trx.len = 2;
123137441611SAlexander Aring 	devrec->irq_trx.tx_buf = devrec->irq_buf;
123237441611SAlexander Aring 	devrec->irq_trx.rx_buf = devrec->irq_buf;
123337441611SAlexander Aring 	spi_message_add_tail(&devrec->irq_trx, &devrec->irq_msg);
123437441611SAlexander Aring }
123537441611SAlexander Aring 
mrf24j40_phy_setup(struct mrf24j40 * devrec)1236766928fbSAlexander Aring static void  mrf24j40_phy_setup(struct mrf24j40 *devrec)
1237766928fbSAlexander Aring {
1238d344c912SAlexander Aring 	ieee802154_random_extended_addr(&devrec->hw->phy->perm_extended_addr);
1239766928fbSAlexander Aring 	devrec->hw->phy->current_channel = 11;
12402323cf38SAlexander Aring 
12412323cf38SAlexander Aring 	/* mrf24j40 supports max_minbe 0 - 3 */
12422323cf38SAlexander Aring 	devrec->hw->phy->supported.max_minbe = 3;
12432323cf38SAlexander Aring 	/* datasheet doesn't say anything about max_be, but we have min_be
12442323cf38SAlexander Aring 	 * So we assume the max_be default.
12452323cf38SAlexander Aring 	 */
12462323cf38SAlexander Aring 	devrec->hw->phy->supported.min_maxbe = 5;
12472323cf38SAlexander Aring 	devrec->hw->phy->supported.max_maxbe = 5;
1248f1d78127SAlexander Aring 
1249eb24d061SAlexander Aring 	devrec->hw->phy->cca.mode = NL802154_CCA_CARRIER;
1250f1d78127SAlexander Aring 	devrec->hw->phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) |
1251f1d78127SAlexander Aring 					       BIT(NL802154_CCA_CARRIER) |
1252f1d78127SAlexander Aring 					       BIT(NL802154_CCA_ENERGY_CARRIER);
1253f1d78127SAlexander Aring 	devrec->hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND);
1254e33a0f96SAlexander Aring 
1255e33a0f96SAlexander Aring 	devrec->hw->phy->cca_ed_level = -6900;
1256e33a0f96SAlexander Aring 	devrec->hw->phy->supported.cca_ed_levels = mrf24j40_ed_levels;
1257e33a0f96SAlexander Aring 	devrec->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(mrf24j40_ed_levels);
125800250f78SAlexander Aring 
125900250f78SAlexander Aring 	switch (spi_get_device_id(devrec->spi)->driver_data) {
126000250f78SAlexander Aring 	case MRF24J40:
126100250f78SAlexander Aring 	case MRF24J40MA:
126200250f78SAlexander Aring 		devrec->hw->phy->supported.tx_powers = mrf24j40ma_powers;
126300250f78SAlexander Aring 		devrec->hw->phy->supported.tx_powers_size = ARRAY_SIZE(mrf24j40ma_powers);
126400250f78SAlexander Aring 		devrec->hw->phy->flags |= WPAN_PHY_FLAG_TXPOWER;
126500250f78SAlexander Aring 		break;
126600250f78SAlexander Aring 	default:
126700250f78SAlexander Aring 		break;
126800250f78SAlexander Aring 	}
1269766928fbSAlexander Aring }
1270766928fbSAlexander Aring 
mrf24j40_probe(struct spi_device * spi)1271bb1f4606SBill Pemberton static int mrf24j40_probe(struct spi_device *spi)
12723731a334SAlan Ott {
1273afaf7fdeSAlexander Aring 	int ret = -ENOMEM, irq_type;
1274b2cfdf3cSAlexander Aring 	struct ieee802154_hw *hw;
12753731a334SAlan Ott 	struct mrf24j40 *devrec;
12763731a334SAlan Ott 
1277ca079ad6SVarka Bhadram 	dev_info(&spi->dev, "probe(). IRQ: %d\n", spi->irq);
12783731a334SAlan Ott 
1279b2cfdf3cSAlexander Aring 	/* Register with the 802154 subsystem */
1280b2cfdf3cSAlexander Aring 
1281b2cfdf3cSAlexander Aring 	hw = ieee802154_alloc_hw(sizeof(*devrec), &mrf24j40_ops);
1282b2cfdf3cSAlexander Aring 	if (!hw)
12830aaf43f5SVarka Bhadram 		goto err_ret;
1284b2cfdf3cSAlexander Aring 
1285b2cfdf3cSAlexander Aring 	devrec = hw->priv;
1286b2cfdf3cSAlexander Aring 	devrec->spi = spi;
1287b2cfdf3cSAlexander Aring 	spi_set_drvdata(spi, devrec);
1288b2cfdf3cSAlexander Aring 	devrec->hw = hw;
1289b2cfdf3cSAlexander Aring 	devrec->hw->parent = &spi->dev;
1290b2cfdf3cSAlexander Aring 	devrec->hw->phy->supported.channels[0] = CHANNEL_MASK;
12912323cf38SAlexander Aring 	devrec->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
12928ba40417SAlexander Aring 			    IEEE802154_HW_CSMA_PARAMS |
12938ba40417SAlexander Aring 			    IEEE802154_HW_PROMISCUOUS;
1294b2cfdf3cSAlexander Aring 
1295e33a0f96SAlexander Aring 	devrec->hw->phy->flags = WPAN_PHY_FLAG_CCA_MODE |
1296e33a0f96SAlexander Aring 				 WPAN_PHY_FLAG_CCA_ED_LEVEL;
1297f1d78127SAlexander Aring 
12986844a0e4SAlexander Aring 	mrf24j40_setup_tx_spi_messages(devrec);
1299c91a3011SAlexander Aring 	mrf24j40_setup_rx_spi_messages(devrec);
130037441611SAlexander Aring 	mrf24j40_setup_irq_spi_messages(devrec);
13016844a0e4SAlexander Aring 
1302b0156792SAlexander Aring 	devrec->regmap_short = devm_regmap_init_spi(spi,
1303b0156792SAlexander Aring 						    &mrf24j40_short_regmap);
1304b0156792SAlexander Aring 	if (IS_ERR(devrec->regmap_short)) {
1305b0156792SAlexander Aring 		ret = PTR_ERR(devrec->regmap_short);
1306b0156792SAlexander Aring 		dev_err(&spi->dev, "Failed to allocate short register map: %d\n",
1307b0156792SAlexander Aring 			ret);
1308b0156792SAlexander Aring 		goto err_register_device;
1309b0156792SAlexander Aring 	}
1310b0156792SAlexander Aring 
1311b0156792SAlexander Aring 	devrec->regmap_long = devm_regmap_init(&spi->dev,
1312b0156792SAlexander Aring 					       &mrf24j40_long_regmap_bus,
1313b0156792SAlexander Aring 					       spi, &mrf24j40_long_regmap);
1314b0156792SAlexander Aring 	if (IS_ERR(devrec->regmap_long)) {
1315b0156792SAlexander Aring 		ret = PTR_ERR(devrec->regmap_long);
1316b0156792SAlexander Aring 		dev_err(&spi->dev, "Failed to allocate long register map: %d\n",
1317b0156792SAlexander Aring 			ret);
1318b0156792SAlexander Aring 		goto err_register_device;
1319b0156792SAlexander Aring 	}
1320b0156792SAlexander Aring 
132178aedb6bSAlexander Aring 	if (spi->max_speed_hz > MAX_SPI_SPEED_HZ) {
132278aedb6bSAlexander Aring 		dev_warn(&spi->dev, "spi clock above possible maximum: %d",
132378aedb6bSAlexander Aring 			 MAX_SPI_SPEED_HZ);
132498b57984SChristophe JAILLET 		ret = -EINVAL;
132598b57984SChristophe JAILLET 		goto err_register_device;
132678aedb6bSAlexander Aring 	}
13273731a334SAlan Ott 
13283dac9a79SVarka Bhadram 	ret = mrf24j40_hw_init(devrec);
13293731a334SAlan Ott 	if (ret)
1330a339e184SAlexander Aring 		goto err_register_device;
13313731a334SAlan Ott 
1332766928fbSAlexander Aring 	mrf24j40_phy_setup(devrec);
1333766928fbSAlexander Aring 
1334afaf7fdeSAlexander Aring 	/* request IRQF_TRIGGER_LOW as fallback default */
1335afaf7fdeSAlexander Aring 	irq_type = irq_get_trigger_type(spi->irq);
1336afaf7fdeSAlexander Aring 	if (!irq_type)
1337afaf7fdeSAlexander Aring 		irq_type = IRQF_TRIGGER_LOW;
1338afaf7fdeSAlexander Aring 
133937441611SAlexander Aring 	ret = devm_request_irq(&spi->dev, spi->irq, mrf24j40_isr,
1340afaf7fdeSAlexander Aring 			       irq_type, dev_name(&spi->dev), devrec);
13413731a334SAlan Ott 	if (ret) {
13423731a334SAlan Ott 		dev_err(printdev(devrec), "Unable to get IRQ");
1343a339e184SAlexander Aring 		goto err_register_device;
13443731a334SAlan Ott 	}
13453731a334SAlan Ott 
1346a339e184SAlexander Aring 	dev_dbg(printdev(devrec), "registered mrf24j40\n");
1347a339e184SAlexander Aring 	ret = ieee802154_register_hw(devrec->hw);
1348a339e184SAlexander Aring 	if (ret)
1349a339e184SAlexander Aring 		goto err_register_device;
1350a339e184SAlexander Aring 
13513731a334SAlan Ott 	return 0;
13523731a334SAlan Ott 
13533731a334SAlan Ott err_register_device:
13545a504397SAlexander Aring 	ieee802154_free_hw(devrec->hw);
13550aaf43f5SVarka Bhadram err_ret:
13563731a334SAlan Ott 	return ret;
13573731a334SAlan Ott }
13583731a334SAlan Ott 
mrf24j40_remove(struct spi_device * spi)1359*a0386bbaSUwe Kleine-König static void mrf24j40_remove(struct spi_device *spi)
13603731a334SAlan Ott {
13614fa0a0efSJingoo Han 	struct mrf24j40 *devrec = spi_get_drvdata(spi);
13623731a334SAlan Ott 
13633731a334SAlan Ott 	dev_dbg(printdev(devrec), "remove\n");
13643731a334SAlan Ott 
13655a504397SAlexander Aring 	ieee802154_unregister_hw(devrec->hw);
13665a504397SAlexander Aring 	ieee802154_free_hw(devrec->hw);
13673731a334SAlan Ott 	/* TODO: Will ieee802154_free_device() wait until ->xmit() is
13683731a334SAlan Ott 	 * complete? */
13693731a334SAlan Ott }
13703731a334SAlan Ott 
13712e6fd648SAlexander Aring static const struct of_device_id mrf24j40_of_match[] = {
13722e6fd648SAlexander Aring 	{ .compatible = "microchip,mrf24j40", .data = (void *)MRF24J40 },
13732e6fd648SAlexander Aring 	{ .compatible = "microchip,mrf24j40ma", .data = (void *)MRF24J40MA },
13742e6fd648SAlexander Aring 	{ .compatible = "microchip,mrf24j40mc", .data = (void *)MRF24J40MC },
13752e6fd648SAlexander Aring 	{ },
13762e6fd648SAlexander Aring };
13772e6fd648SAlexander Aring MODULE_DEVICE_TABLE(of, mrf24j40_of_match);
13782e6fd648SAlexander Aring 
13793731a334SAlan Ott static const struct spi_device_id mrf24j40_ids[] = {
1380db9e0ee8SSimon Vincent 	{ "mrf24j40", MRF24J40 },
1381db9e0ee8SSimon Vincent 	{ "mrf24j40ma", MRF24J40MA },
1382db9e0ee8SSimon Vincent 	{ "mrf24j40mc", MRF24J40MC },
13833731a334SAlan Ott 	{ },
13843731a334SAlan Ott };
13853731a334SAlan Ott MODULE_DEVICE_TABLE(spi, mrf24j40_ids);
13863731a334SAlan Ott 
13873731a334SAlan Ott static struct spi_driver mrf24j40_driver = {
13883731a334SAlan Ott 	.driver = {
1389aab53e67SAndy Shevchenko 		.of_match_table = mrf24j40_of_match,
13903731a334SAlan Ott 		.name = "mrf24j40",
13913731a334SAlan Ott 	},
13923731a334SAlan Ott 	.id_table = mrf24j40_ids,
13933731a334SAlan Ott 	.probe = mrf24j40_probe,
1394bb1f4606SBill Pemberton 	.remove = mrf24j40_remove,
13953731a334SAlan Ott };
13963731a334SAlan Ott 
13973d4a1316SWei Yongjun module_spi_driver(mrf24j40_driver);
13983731a334SAlan Ott 
13993731a334SAlan Ott MODULE_LICENSE("GPL");
14003731a334SAlan Ott MODULE_AUTHOR("Alan Ott");
14013731a334SAlan Ott MODULE_DESCRIPTION("MRF24J40 SPI 802.15.4 Controller Driver");
1402