xref: /OK3568_Linux_fs/kernel/drivers/net/ieee802154/mrf24j40.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Driver for Microchip MRF24J40 802.15.4 Wireless-PAN Networking controller
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2012 Alan Ott <alan@signal11.us>
6*4882a593Smuzhiyun  *                    Signal 11 Software
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/spi/spi.h>
10*4882a593Smuzhiyun #include <linux/interrupt.h>
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/of.h>
13*4882a593Smuzhiyun #include <linux/regmap.h>
14*4882a593Smuzhiyun #include <linux/ieee802154.h>
15*4882a593Smuzhiyun #include <linux/irq.h>
16*4882a593Smuzhiyun #include <net/cfg802154.h>
17*4882a593Smuzhiyun #include <net/mac802154.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* MRF24J40 Short Address Registers */
20*4882a593Smuzhiyun #define REG_RXMCR	0x00  /* Receive MAC control */
21*4882a593Smuzhiyun #define BIT_PROMI	BIT(0)
22*4882a593Smuzhiyun #define BIT_ERRPKT	BIT(1)
23*4882a593Smuzhiyun #define BIT_NOACKRSP	BIT(5)
24*4882a593Smuzhiyun #define BIT_PANCOORD	BIT(3)
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #define REG_PANIDL	0x01  /* PAN ID (low) */
27*4882a593Smuzhiyun #define REG_PANIDH	0x02  /* PAN ID (high) */
28*4882a593Smuzhiyun #define REG_SADRL	0x03  /* Short address (low) */
29*4882a593Smuzhiyun #define REG_SADRH	0x04  /* Short address (high) */
30*4882a593Smuzhiyun #define REG_EADR0	0x05  /* Long address (low) (high is EADR7) */
31*4882a593Smuzhiyun #define REG_EADR1	0x06
32*4882a593Smuzhiyun #define REG_EADR2	0x07
33*4882a593Smuzhiyun #define REG_EADR3	0x08
34*4882a593Smuzhiyun #define REG_EADR4	0x09
35*4882a593Smuzhiyun #define REG_EADR5	0x0A
36*4882a593Smuzhiyun #define REG_EADR6	0x0B
37*4882a593Smuzhiyun #define REG_EADR7	0x0C
38*4882a593Smuzhiyun #define REG_RXFLUSH	0x0D
39*4882a593Smuzhiyun #define REG_ORDER	0x10
40*4882a593Smuzhiyun #define REG_TXMCR	0x11  /* Transmit MAC control */
41*4882a593Smuzhiyun #define TXMCR_MIN_BE_SHIFT		3
42*4882a593Smuzhiyun #define TXMCR_MIN_BE_MASK		0x18
43*4882a593Smuzhiyun #define TXMCR_CSMA_RETRIES_SHIFT	0
44*4882a593Smuzhiyun #define TXMCR_CSMA_RETRIES_MASK		0x07
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun #define REG_ACKTMOUT	0x12
47*4882a593Smuzhiyun #define REG_ESLOTG1	0x13
48*4882a593Smuzhiyun #define REG_SYMTICKL	0x14
49*4882a593Smuzhiyun #define REG_SYMTICKH	0x15
50*4882a593Smuzhiyun #define REG_PACON0	0x16  /* Power Amplifier Control */
51*4882a593Smuzhiyun #define REG_PACON1	0x17  /* Power Amplifier Control */
52*4882a593Smuzhiyun #define REG_PACON2	0x18  /* Power Amplifier Control */
53*4882a593Smuzhiyun #define REG_TXBCON0	0x1A
54*4882a593Smuzhiyun #define REG_TXNCON	0x1B  /* Transmit Normal FIFO Control */
55*4882a593Smuzhiyun #define BIT_TXNTRIG	BIT(0)
56*4882a593Smuzhiyun #define BIT_TXNSECEN	BIT(1)
57*4882a593Smuzhiyun #define BIT_TXNACKREQ	BIT(2)
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun #define REG_TXG1CON	0x1C
60*4882a593Smuzhiyun #define REG_TXG2CON	0x1D
61*4882a593Smuzhiyun #define REG_ESLOTG23	0x1E
62*4882a593Smuzhiyun #define REG_ESLOTG45	0x1F
63*4882a593Smuzhiyun #define REG_ESLOTG67	0x20
64*4882a593Smuzhiyun #define REG_TXPEND	0x21
65*4882a593Smuzhiyun #define REG_WAKECON	0x22
66*4882a593Smuzhiyun #define REG_FROMOFFSET	0x23
67*4882a593Smuzhiyun #define REG_TXSTAT	0x24  /* TX MAC Status Register */
68*4882a593Smuzhiyun #define REG_TXBCON1	0x25
69*4882a593Smuzhiyun #define REG_GATECLK	0x26
70*4882a593Smuzhiyun #define REG_TXTIME	0x27
71*4882a593Smuzhiyun #define REG_HSYMTMRL	0x28
72*4882a593Smuzhiyun #define REG_HSYMTMRH	0x29
73*4882a593Smuzhiyun #define REG_SOFTRST	0x2A  /* Soft Reset */
74*4882a593Smuzhiyun #define REG_SECCON0	0x2C
75*4882a593Smuzhiyun #define REG_SECCON1	0x2D
76*4882a593Smuzhiyun #define REG_TXSTBL	0x2E  /* TX Stabilization */
77*4882a593Smuzhiyun #define REG_RXSR	0x30
78*4882a593Smuzhiyun #define REG_INTSTAT	0x31  /* Interrupt Status */
79*4882a593Smuzhiyun #define BIT_TXNIF	BIT(0)
80*4882a593Smuzhiyun #define BIT_RXIF	BIT(3)
81*4882a593Smuzhiyun #define BIT_SECIF	BIT(4)
82*4882a593Smuzhiyun #define BIT_SECIGNORE	BIT(7)
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun #define REG_INTCON	0x32  /* Interrupt Control */
85*4882a593Smuzhiyun #define BIT_TXNIE	BIT(0)
86*4882a593Smuzhiyun #define BIT_RXIE	BIT(3)
87*4882a593Smuzhiyun #define BIT_SECIE	BIT(4)
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun #define REG_GPIO	0x33  /* GPIO */
90*4882a593Smuzhiyun #define REG_TRISGPIO	0x34  /* GPIO direction */
91*4882a593Smuzhiyun #define REG_SLPACK	0x35
92*4882a593Smuzhiyun #define REG_RFCTL	0x36  /* RF Control Mode Register */
93*4882a593Smuzhiyun #define BIT_RFRST	BIT(2)
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun #define REG_SECCR2	0x37
96*4882a593Smuzhiyun #define REG_BBREG0	0x38
97*4882a593Smuzhiyun #define REG_BBREG1	0x39  /* Baseband Registers */
98*4882a593Smuzhiyun #define BIT_RXDECINV	BIT(2)
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun #define REG_BBREG2	0x3A  /* */
101*4882a593Smuzhiyun #define BBREG2_CCA_MODE_SHIFT	6
102*4882a593Smuzhiyun #define BBREG2_CCA_MODE_MASK	0xc0
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun #define REG_BBREG3	0x3B
105*4882a593Smuzhiyun #define REG_BBREG4	0x3C
106*4882a593Smuzhiyun #define REG_BBREG6	0x3E  /* */
107*4882a593Smuzhiyun #define REG_CCAEDTH	0x3F  /* Energy Detection Threshold */
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun /* MRF24J40 Long Address Registers */
110*4882a593Smuzhiyun #define REG_RFCON0	0x200  /* RF Control Registers */
111*4882a593Smuzhiyun #define RFCON0_CH_SHIFT	4
112*4882a593Smuzhiyun #define RFCON0_CH_MASK	0xf0
113*4882a593Smuzhiyun #define RFOPT_RECOMMEND	3
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun #define REG_RFCON1	0x201
116*4882a593Smuzhiyun #define REG_RFCON2	0x202
117*4882a593Smuzhiyun #define REG_RFCON3	0x203
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun #define TXPWRL_MASK	0xc0
120*4882a593Smuzhiyun #define TXPWRL_SHIFT	6
121*4882a593Smuzhiyun #define TXPWRL_30	0x3
122*4882a593Smuzhiyun #define TXPWRL_20	0x2
123*4882a593Smuzhiyun #define TXPWRL_10	0x1
124*4882a593Smuzhiyun #define TXPWRL_0	0x0
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun #define TXPWRS_MASK	0x38
127*4882a593Smuzhiyun #define TXPWRS_SHIFT	3
128*4882a593Smuzhiyun #define TXPWRS_6_3	0x7
129*4882a593Smuzhiyun #define TXPWRS_4_9	0x6
130*4882a593Smuzhiyun #define TXPWRS_3_7	0x5
131*4882a593Smuzhiyun #define TXPWRS_2_8	0x4
132*4882a593Smuzhiyun #define TXPWRS_1_9	0x3
133*4882a593Smuzhiyun #define TXPWRS_1_2	0x2
134*4882a593Smuzhiyun #define TXPWRS_0_5	0x1
135*4882a593Smuzhiyun #define TXPWRS_0	0x0
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun #define REG_RFCON5	0x205
138*4882a593Smuzhiyun #define REG_RFCON6	0x206
139*4882a593Smuzhiyun #define REG_RFCON7	0x207
140*4882a593Smuzhiyun #define REG_RFCON8	0x208
141*4882a593Smuzhiyun #define REG_SLPCAL0	0x209
142*4882a593Smuzhiyun #define REG_SLPCAL1	0x20A
143*4882a593Smuzhiyun #define REG_SLPCAL2	0x20B
144*4882a593Smuzhiyun #define REG_RFSTATE	0x20F
145*4882a593Smuzhiyun #define REG_RSSI	0x210
146*4882a593Smuzhiyun #define REG_SLPCON0	0x211  /* Sleep Clock Control Registers */
147*4882a593Smuzhiyun #define BIT_INTEDGE	BIT(1)
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun #define REG_SLPCON1	0x220
150*4882a593Smuzhiyun #define REG_WAKETIMEL	0x222  /* Wake-up Time Match Value Low */
151*4882a593Smuzhiyun #define REG_WAKETIMEH	0x223  /* Wake-up Time Match Value High */
152*4882a593Smuzhiyun #define REG_REMCNTL	0x224
153*4882a593Smuzhiyun #define REG_REMCNTH	0x225
154*4882a593Smuzhiyun #define REG_MAINCNT0	0x226
155*4882a593Smuzhiyun #define REG_MAINCNT1	0x227
156*4882a593Smuzhiyun #define REG_MAINCNT2	0x228
157*4882a593Smuzhiyun #define REG_MAINCNT3	0x229
158*4882a593Smuzhiyun #define REG_TESTMODE	0x22F  /* Test mode */
159*4882a593Smuzhiyun #define REG_ASSOEAR0	0x230
160*4882a593Smuzhiyun #define REG_ASSOEAR1	0x231
161*4882a593Smuzhiyun #define REG_ASSOEAR2	0x232
162*4882a593Smuzhiyun #define REG_ASSOEAR3	0x233
163*4882a593Smuzhiyun #define REG_ASSOEAR4	0x234
164*4882a593Smuzhiyun #define REG_ASSOEAR5	0x235
165*4882a593Smuzhiyun #define REG_ASSOEAR6	0x236
166*4882a593Smuzhiyun #define REG_ASSOEAR7	0x237
167*4882a593Smuzhiyun #define REG_ASSOSAR0	0x238
168*4882a593Smuzhiyun #define REG_ASSOSAR1	0x239
169*4882a593Smuzhiyun #define REG_UNONCE0	0x240
170*4882a593Smuzhiyun #define REG_UNONCE1	0x241
171*4882a593Smuzhiyun #define REG_UNONCE2	0x242
172*4882a593Smuzhiyun #define REG_UNONCE3	0x243
173*4882a593Smuzhiyun #define REG_UNONCE4	0x244
174*4882a593Smuzhiyun #define REG_UNONCE5	0x245
175*4882a593Smuzhiyun #define REG_UNONCE6	0x246
176*4882a593Smuzhiyun #define REG_UNONCE7	0x247
177*4882a593Smuzhiyun #define REG_UNONCE8	0x248
178*4882a593Smuzhiyun #define REG_UNONCE9	0x249
179*4882a593Smuzhiyun #define REG_UNONCE10	0x24A
180*4882a593Smuzhiyun #define REG_UNONCE11	0x24B
181*4882a593Smuzhiyun #define REG_UNONCE12	0x24C
182*4882a593Smuzhiyun #define REG_RX_FIFO	0x300  /* Receive FIFO */
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun /* Device configuration: Only channels 11-26 on page 0 are supported. */
185*4882a593Smuzhiyun #define MRF24J40_CHAN_MIN 11
186*4882a593Smuzhiyun #define MRF24J40_CHAN_MAX 26
187*4882a593Smuzhiyun #define CHANNEL_MASK (((u32)1 << (MRF24J40_CHAN_MAX + 1)) \
188*4882a593Smuzhiyun 		      - ((u32)1 << MRF24J40_CHAN_MIN))
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun #define TX_FIFO_SIZE 128 /* From datasheet */
191*4882a593Smuzhiyun #define RX_FIFO_SIZE 144 /* From datasheet */
192*4882a593Smuzhiyun #define SET_CHANNEL_DELAY_US 192 /* From datasheet */
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun enum mrf24j40_modules { MRF24J40, MRF24J40MA, MRF24J40MC };
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun /* Device Private Data */
197*4882a593Smuzhiyun struct mrf24j40 {
198*4882a593Smuzhiyun 	struct spi_device *spi;
199*4882a593Smuzhiyun 	struct ieee802154_hw *hw;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	struct regmap *regmap_short;
202*4882a593Smuzhiyun 	struct regmap *regmap_long;
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	/* for writing txfifo */
205*4882a593Smuzhiyun 	struct spi_message tx_msg;
206*4882a593Smuzhiyun 	u8 tx_hdr_buf[2];
207*4882a593Smuzhiyun 	struct spi_transfer tx_hdr_trx;
208*4882a593Smuzhiyun 	u8 tx_len_buf[2];
209*4882a593Smuzhiyun 	struct spi_transfer tx_len_trx;
210*4882a593Smuzhiyun 	struct spi_transfer tx_buf_trx;
211*4882a593Smuzhiyun 	struct sk_buff *tx_skb;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	/* post transmit message to send frame out  */
214*4882a593Smuzhiyun 	struct spi_message tx_post_msg;
215*4882a593Smuzhiyun 	u8 tx_post_buf[2];
216*4882a593Smuzhiyun 	struct spi_transfer tx_post_trx;
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	/* for protect/unprotect/read length rxfifo */
219*4882a593Smuzhiyun 	struct spi_message rx_msg;
220*4882a593Smuzhiyun 	u8 rx_buf[3];
221*4882a593Smuzhiyun 	struct spi_transfer rx_trx;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	/* receive handling */
224*4882a593Smuzhiyun 	struct spi_message rx_buf_msg;
225*4882a593Smuzhiyun 	u8 rx_addr_buf[2];
226*4882a593Smuzhiyun 	struct spi_transfer rx_addr_trx;
227*4882a593Smuzhiyun 	u8 rx_lqi_buf[2];
228*4882a593Smuzhiyun 	struct spi_transfer rx_lqi_trx;
229*4882a593Smuzhiyun 	u8 rx_fifo_buf[RX_FIFO_SIZE];
230*4882a593Smuzhiyun 	struct spi_transfer rx_fifo_buf_trx;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	/* isr handling for reading intstat */
233*4882a593Smuzhiyun 	struct spi_message irq_msg;
234*4882a593Smuzhiyun 	u8 irq_buf[2];
235*4882a593Smuzhiyun 	struct spi_transfer irq_trx;
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /* regmap information for short address register access */
239*4882a593Smuzhiyun #define MRF24J40_SHORT_WRITE	0x01
240*4882a593Smuzhiyun #define MRF24J40_SHORT_READ	0x00
241*4882a593Smuzhiyun #define MRF24J40_SHORT_NUMREGS	0x3F
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun /* regmap information for long address register access */
244*4882a593Smuzhiyun #define MRF24J40_LONG_ACCESS	0x80
245*4882a593Smuzhiyun #define MRF24J40_LONG_NUMREGS	0x38F
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun /* Read/Write SPI Commands for Short and Long Address registers. */
248*4882a593Smuzhiyun #define MRF24J40_READSHORT(reg) ((reg) << 1)
249*4882a593Smuzhiyun #define MRF24J40_WRITESHORT(reg) ((reg) << 1 | 1)
250*4882a593Smuzhiyun #define MRF24J40_READLONG(reg) (1 << 15 | (reg) << 5)
251*4882a593Smuzhiyun #define MRF24J40_WRITELONG(reg) (1 << 15 | (reg) << 5 | 1 << 4)
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun /* The datasheet indicates the theoretical maximum for SCK to be 10MHz */
254*4882a593Smuzhiyun #define MAX_SPI_SPEED_HZ 10000000
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun #define printdev(X) (&X->spi->dev)
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun static bool
mrf24j40_short_reg_writeable(struct device * dev,unsigned int reg)259*4882a593Smuzhiyun mrf24j40_short_reg_writeable(struct device *dev, unsigned int reg)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun 	switch (reg) {
262*4882a593Smuzhiyun 	case REG_RXMCR:
263*4882a593Smuzhiyun 	case REG_PANIDL:
264*4882a593Smuzhiyun 	case REG_PANIDH:
265*4882a593Smuzhiyun 	case REG_SADRL:
266*4882a593Smuzhiyun 	case REG_SADRH:
267*4882a593Smuzhiyun 	case REG_EADR0:
268*4882a593Smuzhiyun 	case REG_EADR1:
269*4882a593Smuzhiyun 	case REG_EADR2:
270*4882a593Smuzhiyun 	case REG_EADR3:
271*4882a593Smuzhiyun 	case REG_EADR4:
272*4882a593Smuzhiyun 	case REG_EADR5:
273*4882a593Smuzhiyun 	case REG_EADR6:
274*4882a593Smuzhiyun 	case REG_EADR7:
275*4882a593Smuzhiyun 	case REG_RXFLUSH:
276*4882a593Smuzhiyun 	case REG_ORDER:
277*4882a593Smuzhiyun 	case REG_TXMCR:
278*4882a593Smuzhiyun 	case REG_ACKTMOUT:
279*4882a593Smuzhiyun 	case REG_ESLOTG1:
280*4882a593Smuzhiyun 	case REG_SYMTICKL:
281*4882a593Smuzhiyun 	case REG_SYMTICKH:
282*4882a593Smuzhiyun 	case REG_PACON0:
283*4882a593Smuzhiyun 	case REG_PACON1:
284*4882a593Smuzhiyun 	case REG_PACON2:
285*4882a593Smuzhiyun 	case REG_TXBCON0:
286*4882a593Smuzhiyun 	case REG_TXNCON:
287*4882a593Smuzhiyun 	case REG_TXG1CON:
288*4882a593Smuzhiyun 	case REG_TXG2CON:
289*4882a593Smuzhiyun 	case REG_ESLOTG23:
290*4882a593Smuzhiyun 	case REG_ESLOTG45:
291*4882a593Smuzhiyun 	case REG_ESLOTG67:
292*4882a593Smuzhiyun 	case REG_TXPEND:
293*4882a593Smuzhiyun 	case REG_WAKECON:
294*4882a593Smuzhiyun 	case REG_FROMOFFSET:
295*4882a593Smuzhiyun 	case REG_TXBCON1:
296*4882a593Smuzhiyun 	case REG_GATECLK:
297*4882a593Smuzhiyun 	case REG_TXTIME:
298*4882a593Smuzhiyun 	case REG_HSYMTMRL:
299*4882a593Smuzhiyun 	case REG_HSYMTMRH:
300*4882a593Smuzhiyun 	case REG_SOFTRST:
301*4882a593Smuzhiyun 	case REG_SECCON0:
302*4882a593Smuzhiyun 	case REG_SECCON1:
303*4882a593Smuzhiyun 	case REG_TXSTBL:
304*4882a593Smuzhiyun 	case REG_RXSR:
305*4882a593Smuzhiyun 	case REG_INTCON:
306*4882a593Smuzhiyun 	case REG_TRISGPIO:
307*4882a593Smuzhiyun 	case REG_GPIO:
308*4882a593Smuzhiyun 	case REG_RFCTL:
309*4882a593Smuzhiyun 	case REG_SECCR2:
310*4882a593Smuzhiyun 	case REG_SLPACK:
311*4882a593Smuzhiyun 	case REG_BBREG0:
312*4882a593Smuzhiyun 	case REG_BBREG1:
313*4882a593Smuzhiyun 	case REG_BBREG2:
314*4882a593Smuzhiyun 	case REG_BBREG3:
315*4882a593Smuzhiyun 	case REG_BBREG4:
316*4882a593Smuzhiyun 	case REG_BBREG6:
317*4882a593Smuzhiyun 	case REG_CCAEDTH:
318*4882a593Smuzhiyun 		return true;
319*4882a593Smuzhiyun 	default:
320*4882a593Smuzhiyun 		return false;
321*4882a593Smuzhiyun 	}
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun static bool
mrf24j40_short_reg_readable(struct device * dev,unsigned int reg)325*4882a593Smuzhiyun mrf24j40_short_reg_readable(struct device *dev, unsigned int reg)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun 	bool rc;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	/* all writeable are also readable */
330*4882a593Smuzhiyun 	rc = mrf24j40_short_reg_writeable(dev, reg);
331*4882a593Smuzhiyun 	if (rc)
332*4882a593Smuzhiyun 		return rc;
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	/* readonly regs */
335*4882a593Smuzhiyun 	switch (reg) {
336*4882a593Smuzhiyun 	case REG_TXSTAT:
337*4882a593Smuzhiyun 	case REG_INTSTAT:
338*4882a593Smuzhiyun 		return true;
339*4882a593Smuzhiyun 	default:
340*4882a593Smuzhiyun 		return false;
341*4882a593Smuzhiyun 	}
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun static bool
mrf24j40_short_reg_volatile(struct device * dev,unsigned int reg)345*4882a593Smuzhiyun mrf24j40_short_reg_volatile(struct device *dev, unsigned int reg)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun 	/* can be changed during runtime */
348*4882a593Smuzhiyun 	switch (reg) {
349*4882a593Smuzhiyun 	case REG_TXSTAT:
350*4882a593Smuzhiyun 	case REG_INTSTAT:
351*4882a593Smuzhiyun 	case REG_RXFLUSH:
352*4882a593Smuzhiyun 	case REG_TXNCON:
353*4882a593Smuzhiyun 	case REG_SOFTRST:
354*4882a593Smuzhiyun 	case REG_RFCTL:
355*4882a593Smuzhiyun 	case REG_TXBCON0:
356*4882a593Smuzhiyun 	case REG_TXG1CON:
357*4882a593Smuzhiyun 	case REG_TXG2CON:
358*4882a593Smuzhiyun 	case REG_TXBCON1:
359*4882a593Smuzhiyun 	case REG_SECCON0:
360*4882a593Smuzhiyun 	case REG_RXSR:
361*4882a593Smuzhiyun 	case REG_SLPACK:
362*4882a593Smuzhiyun 	case REG_SECCR2:
363*4882a593Smuzhiyun 	case REG_BBREG6:
364*4882a593Smuzhiyun 	/* use them in spi_async and regmap so it's volatile */
365*4882a593Smuzhiyun 	case REG_BBREG1:
366*4882a593Smuzhiyun 		return true;
367*4882a593Smuzhiyun 	default:
368*4882a593Smuzhiyun 		return false;
369*4882a593Smuzhiyun 	}
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun static bool
mrf24j40_short_reg_precious(struct device * dev,unsigned int reg)373*4882a593Smuzhiyun mrf24j40_short_reg_precious(struct device *dev, unsigned int reg)
374*4882a593Smuzhiyun {
375*4882a593Smuzhiyun 	/* don't clear irq line on read */
376*4882a593Smuzhiyun 	switch (reg) {
377*4882a593Smuzhiyun 	case REG_INTSTAT:
378*4882a593Smuzhiyun 		return true;
379*4882a593Smuzhiyun 	default:
380*4882a593Smuzhiyun 		return false;
381*4882a593Smuzhiyun 	}
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun static const struct regmap_config mrf24j40_short_regmap = {
385*4882a593Smuzhiyun 	.name = "mrf24j40_short",
386*4882a593Smuzhiyun 	.reg_bits = 7,
387*4882a593Smuzhiyun 	.val_bits = 8,
388*4882a593Smuzhiyun 	.pad_bits = 1,
389*4882a593Smuzhiyun 	.write_flag_mask = MRF24J40_SHORT_WRITE,
390*4882a593Smuzhiyun 	.read_flag_mask = MRF24J40_SHORT_READ,
391*4882a593Smuzhiyun 	.cache_type = REGCACHE_RBTREE,
392*4882a593Smuzhiyun 	.max_register = MRF24J40_SHORT_NUMREGS,
393*4882a593Smuzhiyun 	.writeable_reg = mrf24j40_short_reg_writeable,
394*4882a593Smuzhiyun 	.readable_reg = mrf24j40_short_reg_readable,
395*4882a593Smuzhiyun 	.volatile_reg = mrf24j40_short_reg_volatile,
396*4882a593Smuzhiyun 	.precious_reg = mrf24j40_short_reg_precious,
397*4882a593Smuzhiyun };
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun static bool
mrf24j40_long_reg_writeable(struct device * dev,unsigned int reg)400*4882a593Smuzhiyun mrf24j40_long_reg_writeable(struct device *dev, unsigned int reg)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun 	switch (reg) {
403*4882a593Smuzhiyun 	case REG_RFCON0:
404*4882a593Smuzhiyun 	case REG_RFCON1:
405*4882a593Smuzhiyun 	case REG_RFCON2:
406*4882a593Smuzhiyun 	case REG_RFCON3:
407*4882a593Smuzhiyun 	case REG_RFCON5:
408*4882a593Smuzhiyun 	case REG_RFCON6:
409*4882a593Smuzhiyun 	case REG_RFCON7:
410*4882a593Smuzhiyun 	case REG_RFCON8:
411*4882a593Smuzhiyun 	case REG_SLPCAL2:
412*4882a593Smuzhiyun 	case REG_SLPCON0:
413*4882a593Smuzhiyun 	case REG_SLPCON1:
414*4882a593Smuzhiyun 	case REG_WAKETIMEL:
415*4882a593Smuzhiyun 	case REG_WAKETIMEH:
416*4882a593Smuzhiyun 	case REG_REMCNTL:
417*4882a593Smuzhiyun 	case REG_REMCNTH:
418*4882a593Smuzhiyun 	case REG_MAINCNT0:
419*4882a593Smuzhiyun 	case REG_MAINCNT1:
420*4882a593Smuzhiyun 	case REG_MAINCNT2:
421*4882a593Smuzhiyun 	case REG_MAINCNT3:
422*4882a593Smuzhiyun 	case REG_TESTMODE:
423*4882a593Smuzhiyun 	case REG_ASSOEAR0:
424*4882a593Smuzhiyun 	case REG_ASSOEAR1:
425*4882a593Smuzhiyun 	case REG_ASSOEAR2:
426*4882a593Smuzhiyun 	case REG_ASSOEAR3:
427*4882a593Smuzhiyun 	case REG_ASSOEAR4:
428*4882a593Smuzhiyun 	case REG_ASSOEAR5:
429*4882a593Smuzhiyun 	case REG_ASSOEAR6:
430*4882a593Smuzhiyun 	case REG_ASSOEAR7:
431*4882a593Smuzhiyun 	case REG_ASSOSAR0:
432*4882a593Smuzhiyun 	case REG_ASSOSAR1:
433*4882a593Smuzhiyun 	case REG_UNONCE0:
434*4882a593Smuzhiyun 	case REG_UNONCE1:
435*4882a593Smuzhiyun 	case REG_UNONCE2:
436*4882a593Smuzhiyun 	case REG_UNONCE3:
437*4882a593Smuzhiyun 	case REG_UNONCE4:
438*4882a593Smuzhiyun 	case REG_UNONCE5:
439*4882a593Smuzhiyun 	case REG_UNONCE6:
440*4882a593Smuzhiyun 	case REG_UNONCE7:
441*4882a593Smuzhiyun 	case REG_UNONCE8:
442*4882a593Smuzhiyun 	case REG_UNONCE9:
443*4882a593Smuzhiyun 	case REG_UNONCE10:
444*4882a593Smuzhiyun 	case REG_UNONCE11:
445*4882a593Smuzhiyun 	case REG_UNONCE12:
446*4882a593Smuzhiyun 		return true;
447*4882a593Smuzhiyun 	default:
448*4882a593Smuzhiyun 		return false;
449*4882a593Smuzhiyun 	}
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun static bool
mrf24j40_long_reg_readable(struct device * dev,unsigned int reg)453*4882a593Smuzhiyun mrf24j40_long_reg_readable(struct device *dev, unsigned int reg)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun 	bool rc;
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	/* all writeable are also readable */
458*4882a593Smuzhiyun 	rc = mrf24j40_long_reg_writeable(dev, reg);
459*4882a593Smuzhiyun 	if (rc)
460*4882a593Smuzhiyun 		return rc;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	/* readonly regs */
463*4882a593Smuzhiyun 	switch (reg) {
464*4882a593Smuzhiyun 	case REG_SLPCAL0:
465*4882a593Smuzhiyun 	case REG_SLPCAL1:
466*4882a593Smuzhiyun 	case REG_RFSTATE:
467*4882a593Smuzhiyun 	case REG_RSSI:
468*4882a593Smuzhiyun 		return true;
469*4882a593Smuzhiyun 	default:
470*4882a593Smuzhiyun 		return false;
471*4882a593Smuzhiyun 	}
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun static bool
mrf24j40_long_reg_volatile(struct device * dev,unsigned int reg)475*4882a593Smuzhiyun mrf24j40_long_reg_volatile(struct device *dev, unsigned int reg)
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun 	/* can be changed during runtime */
478*4882a593Smuzhiyun 	switch (reg) {
479*4882a593Smuzhiyun 	case REG_SLPCAL0:
480*4882a593Smuzhiyun 	case REG_SLPCAL1:
481*4882a593Smuzhiyun 	case REG_SLPCAL2:
482*4882a593Smuzhiyun 	case REG_RFSTATE:
483*4882a593Smuzhiyun 	case REG_RSSI:
484*4882a593Smuzhiyun 	case REG_MAINCNT3:
485*4882a593Smuzhiyun 		return true;
486*4882a593Smuzhiyun 	default:
487*4882a593Smuzhiyun 		return false;
488*4882a593Smuzhiyun 	}
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun static const struct regmap_config mrf24j40_long_regmap = {
492*4882a593Smuzhiyun 	.name = "mrf24j40_long",
493*4882a593Smuzhiyun 	.reg_bits = 11,
494*4882a593Smuzhiyun 	.val_bits = 8,
495*4882a593Smuzhiyun 	.pad_bits = 5,
496*4882a593Smuzhiyun 	.write_flag_mask = MRF24J40_LONG_ACCESS,
497*4882a593Smuzhiyun 	.read_flag_mask = MRF24J40_LONG_ACCESS,
498*4882a593Smuzhiyun 	.cache_type = REGCACHE_RBTREE,
499*4882a593Smuzhiyun 	.max_register = MRF24J40_LONG_NUMREGS,
500*4882a593Smuzhiyun 	.writeable_reg = mrf24j40_long_reg_writeable,
501*4882a593Smuzhiyun 	.readable_reg = mrf24j40_long_reg_readable,
502*4882a593Smuzhiyun 	.volatile_reg = mrf24j40_long_reg_volatile,
503*4882a593Smuzhiyun };
504*4882a593Smuzhiyun 
mrf24j40_long_regmap_write(void * context,const void * data,size_t count)505*4882a593Smuzhiyun static int mrf24j40_long_regmap_write(void *context, const void *data,
506*4882a593Smuzhiyun 				      size_t count)
507*4882a593Smuzhiyun {
508*4882a593Smuzhiyun 	struct spi_device *spi = context;
509*4882a593Smuzhiyun 	u8 buf[3];
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	if (count > 3)
512*4882a593Smuzhiyun 		return -EINVAL;
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	/* regmap supports read/write mask only in frist byte
515*4882a593Smuzhiyun 	 * long write access need to set the 12th bit, so we
516*4882a593Smuzhiyun 	 * make special handling for write.
517*4882a593Smuzhiyun 	 */
518*4882a593Smuzhiyun 	memcpy(buf, data, count);
519*4882a593Smuzhiyun 	buf[1] |= (1 << 4);
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	return spi_write(spi, buf, count);
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun static int
mrf24j40_long_regmap_read(void * context,const void * reg,size_t reg_size,void * val,size_t val_size)525*4882a593Smuzhiyun mrf24j40_long_regmap_read(void *context, const void *reg, size_t reg_size,
526*4882a593Smuzhiyun 			  void *val, size_t val_size)
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun 	struct spi_device *spi = context;
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	return spi_write_then_read(spi, reg, reg_size, val, val_size);
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun static const struct regmap_bus mrf24j40_long_regmap_bus = {
534*4882a593Smuzhiyun 	.write = mrf24j40_long_regmap_write,
535*4882a593Smuzhiyun 	.read = mrf24j40_long_regmap_read,
536*4882a593Smuzhiyun 	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
537*4882a593Smuzhiyun 	.val_format_endian_default = REGMAP_ENDIAN_BIG,
538*4882a593Smuzhiyun };
539*4882a593Smuzhiyun 
write_tx_buf_complete(void * context)540*4882a593Smuzhiyun static void write_tx_buf_complete(void *context)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun 	struct mrf24j40 *devrec = context;
543*4882a593Smuzhiyun 	__le16 fc = ieee802154_get_fc_from_skb(devrec->tx_skb);
544*4882a593Smuzhiyun 	u8 val = BIT_TXNTRIG;
545*4882a593Smuzhiyun 	int ret;
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	if (ieee802154_is_secen(fc))
548*4882a593Smuzhiyun 		val |= BIT_TXNSECEN;
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun 	if (ieee802154_is_ackreq(fc))
551*4882a593Smuzhiyun 		val |= BIT_TXNACKREQ;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	devrec->tx_post_msg.complete = NULL;
554*4882a593Smuzhiyun 	devrec->tx_post_buf[0] = MRF24J40_WRITESHORT(REG_TXNCON);
555*4882a593Smuzhiyun 	devrec->tx_post_buf[1] = val;
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 	ret = spi_async(devrec->spi, &devrec->tx_post_msg);
558*4882a593Smuzhiyun 	if (ret)
559*4882a593Smuzhiyun 		dev_err(printdev(devrec), "SPI write Failed for transmit buf\n");
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun /* This function relies on an undocumented write method. Once a write command
563*4882a593Smuzhiyun    and address is set, as many bytes of data as desired can be clocked into
564*4882a593Smuzhiyun    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)565*4882a593Smuzhiyun static int write_tx_buf(struct mrf24j40 *devrec, u16 reg,
566*4882a593Smuzhiyun 			const u8 *data, size_t length)
567*4882a593Smuzhiyun {
568*4882a593Smuzhiyun 	u16 cmd;
569*4882a593Smuzhiyun 	int ret;
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 	/* Range check the length. 2 bytes are used for the length fields.*/
572*4882a593Smuzhiyun 	if (length > TX_FIFO_SIZE-2) {
573*4882a593Smuzhiyun 		dev_err(printdev(devrec), "write_tx_buf() was passed too large a buffer. Performing short write.\n");
574*4882a593Smuzhiyun 		length = TX_FIFO_SIZE-2;
575*4882a593Smuzhiyun 	}
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	cmd = MRF24J40_WRITELONG(reg);
578*4882a593Smuzhiyun 	devrec->tx_hdr_buf[0] = cmd >> 8 & 0xff;
579*4882a593Smuzhiyun 	devrec->tx_hdr_buf[1] = cmd & 0xff;
580*4882a593Smuzhiyun 	devrec->tx_len_buf[0] = 0x0; /* Header Length. Set to 0 for now. TODO */
581*4882a593Smuzhiyun 	devrec->tx_len_buf[1] = length; /* Total length */
582*4882a593Smuzhiyun 	devrec->tx_buf_trx.tx_buf = data;
583*4882a593Smuzhiyun 	devrec->tx_buf_trx.len = length;
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	ret = spi_async(devrec->spi, &devrec->tx_msg);
586*4882a593Smuzhiyun 	if (ret)
587*4882a593Smuzhiyun 		dev_err(printdev(devrec), "SPI write Failed for TX buf\n");
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	return ret;
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun 
mrf24j40_tx(struct ieee802154_hw * hw,struct sk_buff * skb)592*4882a593Smuzhiyun static int mrf24j40_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
593*4882a593Smuzhiyun {
594*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	dev_dbg(printdev(devrec), "tx packet of %d bytes\n", skb->len);
597*4882a593Smuzhiyun 	devrec->tx_skb = skb;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	return write_tx_buf(devrec, 0x000, skb->data, skb->len);
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun 
mrf24j40_ed(struct ieee802154_hw * hw,u8 * level)602*4882a593Smuzhiyun static int mrf24j40_ed(struct ieee802154_hw *hw, u8 *level)
603*4882a593Smuzhiyun {
604*4882a593Smuzhiyun 	/* TODO: */
605*4882a593Smuzhiyun 	pr_warn("mrf24j40: ed not implemented\n");
606*4882a593Smuzhiyun 	*level = 0;
607*4882a593Smuzhiyun 	return 0;
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun 
mrf24j40_start(struct ieee802154_hw * hw)610*4882a593Smuzhiyun static int mrf24j40_start(struct ieee802154_hw *hw)
611*4882a593Smuzhiyun {
612*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	dev_dbg(printdev(devrec), "start\n");
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	/* Clear TXNIE and RXIE. Enable interrupts */
617*4882a593Smuzhiyun 	return regmap_update_bits(devrec->regmap_short, REG_INTCON,
618*4882a593Smuzhiyun 				  BIT_TXNIE | BIT_RXIE | BIT_SECIE, 0);
619*4882a593Smuzhiyun }
620*4882a593Smuzhiyun 
mrf24j40_stop(struct ieee802154_hw * hw)621*4882a593Smuzhiyun static void mrf24j40_stop(struct ieee802154_hw *hw)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	dev_dbg(printdev(devrec), "stop\n");
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	/* Set TXNIE and RXIE. Disable Interrupts */
628*4882a593Smuzhiyun 	regmap_update_bits(devrec->regmap_short, REG_INTCON,
629*4882a593Smuzhiyun 			   BIT_TXNIE | BIT_RXIE, BIT_TXNIE | BIT_RXIE);
630*4882a593Smuzhiyun }
631*4882a593Smuzhiyun 
mrf24j40_set_channel(struct ieee802154_hw * hw,u8 page,u8 channel)632*4882a593Smuzhiyun static int mrf24j40_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
633*4882a593Smuzhiyun {
634*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
635*4882a593Smuzhiyun 	u8 val;
636*4882a593Smuzhiyun 	int ret;
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 	dev_dbg(printdev(devrec), "Set Channel %d\n", channel);
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun 	WARN_ON(page != 0);
641*4882a593Smuzhiyun 	WARN_ON(channel < MRF24J40_CHAN_MIN);
642*4882a593Smuzhiyun 	WARN_ON(channel > MRF24J40_CHAN_MAX);
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	/* Set Channel TODO */
645*4882a593Smuzhiyun 	val = (channel - 11) << RFCON0_CH_SHIFT | RFOPT_RECOMMEND;
646*4882a593Smuzhiyun 	ret = regmap_update_bits(devrec->regmap_long, REG_RFCON0,
647*4882a593Smuzhiyun 				 RFCON0_CH_MASK, val);
648*4882a593Smuzhiyun 	if (ret)
649*4882a593Smuzhiyun 		return ret;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	/* RF Reset */
652*4882a593Smuzhiyun 	ret = regmap_update_bits(devrec->regmap_short, REG_RFCTL, BIT_RFRST,
653*4882a593Smuzhiyun 				 BIT_RFRST);
654*4882a593Smuzhiyun 	if (ret)
655*4882a593Smuzhiyun 		return ret;
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	ret = regmap_update_bits(devrec->regmap_short, REG_RFCTL, BIT_RFRST, 0);
658*4882a593Smuzhiyun 	if (!ret)
659*4882a593Smuzhiyun 		udelay(SET_CHANNEL_DELAY_US); /* per datasheet */
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun 	return ret;
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun 
mrf24j40_filter(struct ieee802154_hw * hw,struct ieee802154_hw_addr_filt * filt,unsigned long changed)664*4882a593Smuzhiyun static int mrf24j40_filter(struct ieee802154_hw *hw,
665*4882a593Smuzhiyun 			   struct ieee802154_hw_addr_filt *filt,
666*4882a593Smuzhiyun 			   unsigned long changed)
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	dev_dbg(printdev(devrec), "filter\n");
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
673*4882a593Smuzhiyun 		/* Short Addr */
674*4882a593Smuzhiyun 		u8 addrh, addrl;
675*4882a593Smuzhiyun 
676*4882a593Smuzhiyun 		addrh = le16_to_cpu(filt->short_addr) >> 8 & 0xff;
677*4882a593Smuzhiyun 		addrl = le16_to_cpu(filt->short_addr) & 0xff;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 		regmap_write(devrec->regmap_short, REG_SADRH, addrh);
680*4882a593Smuzhiyun 		regmap_write(devrec->regmap_short, REG_SADRL, addrl);
681*4882a593Smuzhiyun 		dev_dbg(printdev(devrec),
682*4882a593Smuzhiyun 			"Set short addr to %04hx\n", filt->short_addr);
683*4882a593Smuzhiyun 	}
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 	if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
686*4882a593Smuzhiyun 		/* Device Address */
687*4882a593Smuzhiyun 		u8 i, addr[8];
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 		memcpy(addr, &filt->ieee_addr, 8);
690*4882a593Smuzhiyun 		for (i = 0; i < 8; i++)
691*4882a593Smuzhiyun 			regmap_write(devrec->regmap_short, REG_EADR0 + i,
692*4882a593Smuzhiyun 				     addr[i]);
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun #ifdef DEBUG
695*4882a593Smuzhiyun 		pr_debug("Set long addr to: ");
696*4882a593Smuzhiyun 		for (i = 0; i < 8; i++)
697*4882a593Smuzhiyun 			pr_debug("%02hhx ", addr[7 - i]);
698*4882a593Smuzhiyun 		pr_debug("\n");
699*4882a593Smuzhiyun #endif
700*4882a593Smuzhiyun 	}
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	if (changed & IEEE802154_AFILT_PANID_CHANGED) {
703*4882a593Smuzhiyun 		/* PAN ID */
704*4882a593Smuzhiyun 		u8 panidl, panidh;
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun 		panidh = le16_to_cpu(filt->pan_id) >> 8 & 0xff;
707*4882a593Smuzhiyun 		panidl = le16_to_cpu(filt->pan_id) & 0xff;
708*4882a593Smuzhiyun 		regmap_write(devrec->regmap_short, REG_PANIDH, panidh);
709*4882a593Smuzhiyun 		regmap_write(devrec->regmap_short, REG_PANIDL, panidl);
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun 		dev_dbg(printdev(devrec), "Set PANID to %04hx\n", filt->pan_id);
712*4882a593Smuzhiyun 	}
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	if (changed & IEEE802154_AFILT_PANC_CHANGED) {
715*4882a593Smuzhiyun 		/* Pan Coordinator */
716*4882a593Smuzhiyun 		u8 val;
717*4882a593Smuzhiyun 		int ret;
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun 		if (filt->pan_coord)
720*4882a593Smuzhiyun 			val = BIT_PANCOORD;
721*4882a593Smuzhiyun 		else
722*4882a593Smuzhiyun 			val = 0;
723*4882a593Smuzhiyun 		ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR,
724*4882a593Smuzhiyun 					 BIT_PANCOORD, val);
725*4882a593Smuzhiyun 		if (ret)
726*4882a593Smuzhiyun 			return ret;
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 		/* REG_SLOTTED is maintained as default (unslotted/CSMA-CA).
729*4882a593Smuzhiyun 		 * REG_ORDER is maintained as default (no beacon/superframe).
730*4882a593Smuzhiyun 		 */
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun 		dev_dbg(printdev(devrec), "Set Pan Coord to %s\n",
733*4882a593Smuzhiyun 			filt->pan_coord ? "on" : "off");
734*4882a593Smuzhiyun 	}
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun 	return 0;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun 
mrf24j40_handle_rx_read_buf_unlock(struct mrf24j40 * devrec)739*4882a593Smuzhiyun static void mrf24j40_handle_rx_read_buf_unlock(struct mrf24j40 *devrec)
740*4882a593Smuzhiyun {
741*4882a593Smuzhiyun 	int ret;
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun 	/* Turn back on reception of packets off the air. */
744*4882a593Smuzhiyun 	devrec->rx_msg.complete = NULL;
745*4882a593Smuzhiyun 	devrec->rx_buf[0] = MRF24J40_WRITESHORT(REG_BBREG1);
746*4882a593Smuzhiyun 	devrec->rx_buf[1] = 0x00; /* CLR RXDECINV */
747*4882a593Smuzhiyun 	ret = spi_async(devrec->spi, &devrec->rx_msg);
748*4882a593Smuzhiyun 	if (ret)
749*4882a593Smuzhiyun 		dev_err(printdev(devrec), "failed to unlock rx buffer\n");
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun 
mrf24j40_handle_rx_read_buf_complete(void * context)752*4882a593Smuzhiyun static void mrf24j40_handle_rx_read_buf_complete(void *context)
753*4882a593Smuzhiyun {
754*4882a593Smuzhiyun 	struct mrf24j40 *devrec = context;
755*4882a593Smuzhiyun 	u8 len = devrec->rx_buf[2];
756*4882a593Smuzhiyun 	u8 rx_local_buf[RX_FIFO_SIZE];
757*4882a593Smuzhiyun 	struct sk_buff *skb;
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	memcpy(rx_local_buf, devrec->rx_fifo_buf, len);
760*4882a593Smuzhiyun 	mrf24j40_handle_rx_read_buf_unlock(devrec);
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	skb = dev_alloc_skb(IEEE802154_MTU);
763*4882a593Smuzhiyun 	if (!skb) {
764*4882a593Smuzhiyun 		dev_err(printdev(devrec), "failed to allocate skb\n");
765*4882a593Smuzhiyun 		return;
766*4882a593Smuzhiyun 	}
767*4882a593Smuzhiyun 
768*4882a593Smuzhiyun 	skb_put_data(skb, rx_local_buf, len);
769*4882a593Smuzhiyun 	ieee802154_rx_irqsafe(devrec->hw, skb, 0);
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun #ifdef DEBUG
772*4882a593Smuzhiyun 	 print_hex_dump(KERN_DEBUG, "mrf24j40 rx: ", DUMP_PREFIX_OFFSET, 16, 1,
773*4882a593Smuzhiyun 			rx_local_buf, len, 0);
774*4882a593Smuzhiyun 	 pr_debug("mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n",
775*4882a593Smuzhiyun 		  devrec->rx_lqi_buf[0], devrec->rx_lqi_buf[1]);
776*4882a593Smuzhiyun #endif
777*4882a593Smuzhiyun }
778*4882a593Smuzhiyun 
mrf24j40_handle_rx_read_buf(void * context)779*4882a593Smuzhiyun static void mrf24j40_handle_rx_read_buf(void *context)
780*4882a593Smuzhiyun {
781*4882a593Smuzhiyun 	struct mrf24j40 *devrec = context;
782*4882a593Smuzhiyun 	u16 cmd;
783*4882a593Smuzhiyun 	int ret;
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	/* if length is invalid read the full MTU */
786*4882a593Smuzhiyun 	if (!ieee802154_is_valid_psdu_len(devrec->rx_buf[2]))
787*4882a593Smuzhiyun 		devrec->rx_buf[2] = IEEE802154_MTU;
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	cmd = MRF24J40_READLONG(REG_RX_FIFO + 1);
790*4882a593Smuzhiyun 	devrec->rx_addr_buf[0] = cmd >> 8 & 0xff;
791*4882a593Smuzhiyun 	devrec->rx_addr_buf[1] = cmd & 0xff;
792*4882a593Smuzhiyun 	devrec->rx_fifo_buf_trx.len = devrec->rx_buf[2];
793*4882a593Smuzhiyun 	ret = spi_async(devrec->spi, &devrec->rx_buf_msg);
794*4882a593Smuzhiyun 	if (ret) {
795*4882a593Smuzhiyun 		dev_err(printdev(devrec), "failed to read rx buffer\n");
796*4882a593Smuzhiyun 		mrf24j40_handle_rx_read_buf_unlock(devrec);
797*4882a593Smuzhiyun 	}
798*4882a593Smuzhiyun }
799*4882a593Smuzhiyun 
mrf24j40_handle_rx_read_len(void * context)800*4882a593Smuzhiyun static void mrf24j40_handle_rx_read_len(void *context)
801*4882a593Smuzhiyun {
802*4882a593Smuzhiyun 	struct mrf24j40 *devrec = context;
803*4882a593Smuzhiyun 	u16 cmd;
804*4882a593Smuzhiyun 	int ret;
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 	/* read the length of received frame */
807*4882a593Smuzhiyun 	devrec->rx_msg.complete = mrf24j40_handle_rx_read_buf;
808*4882a593Smuzhiyun 	devrec->rx_trx.len = 3;
809*4882a593Smuzhiyun 	cmd = MRF24J40_READLONG(REG_RX_FIFO);
810*4882a593Smuzhiyun 	devrec->rx_buf[0] = cmd >> 8 & 0xff;
811*4882a593Smuzhiyun 	devrec->rx_buf[1] = cmd & 0xff;
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun 	ret = spi_async(devrec->spi, &devrec->rx_msg);
814*4882a593Smuzhiyun 	if (ret) {
815*4882a593Smuzhiyun 		dev_err(printdev(devrec), "failed to read rx buffer length\n");
816*4882a593Smuzhiyun 		mrf24j40_handle_rx_read_buf_unlock(devrec);
817*4882a593Smuzhiyun 	}
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun 
mrf24j40_handle_rx(struct mrf24j40 * devrec)820*4882a593Smuzhiyun static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
821*4882a593Smuzhiyun {
822*4882a593Smuzhiyun 	/* Turn off reception of packets off the air. This prevents the
823*4882a593Smuzhiyun 	 * device from overwriting the buffer while we're reading it.
824*4882a593Smuzhiyun 	 */
825*4882a593Smuzhiyun 	devrec->rx_msg.complete = mrf24j40_handle_rx_read_len;
826*4882a593Smuzhiyun 	devrec->rx_trx.len = 2;
827*4882a593Smuzhiyun 	devrec->rx_buf[0] = MRF24J40_WRITESHORT(REG_BBREG1);
828*4882a593Smuzhiyun 	devrec->rx_buf[1] = BIT_RXDECINV; /* SET RXDECINV */
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 	return spi_async(devrec->spi, &devrec->rx_msg);
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun static int
mrf24j40_csma_params(struct ieee802154_hw * hw,u8 min_be,u8 max_be,u8 retries)834*4882a593Smuzhiyun mrf24j40_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be,
835*4882a593Smuzhiyun 		     u8 retries)
836*4882a593Smuzhiyun {
837*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
838*4882a593Smuzhiyun 	u8 val;
839*4882a593Smuzhiyun 
840*4882a593Smuzhiyun 	/* min_be */
841*4882a593Smuzhiyun 	val = min_be << TXMCR_MIN_BE_SHIFT;
842*4882a593Smuzhiyun 	/* csma backoffs */
843*4882a593Smuzhiyun 	val |= retries << TXMCR_CSMA_RETRIES_SHIFT;
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	return regmap_update_bits(devrec->regmap_short, REG_TXMCR,
846*4882a593Smuzhiyun 				  TXMCR_MIN_BE_MASK | TXMCR_CSMA_RETRIES_MASK,
847*4882a593Smuzhiyun 				  val);
848*4882a593Smuzhiyun }
849*4882a593Smuzhiyun 
mrf24j40_set_cca_mode(struct ieee802154_hw * hw,const struct wpan_phy_cca * cca)850*4882a593Smuzhiyun static int mrf24j40_set_cca_mode(struct ieee802154_hw *hw,
851*4882a593Smuzhiyun 				 const struct wpan_phy_cca *cca)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
854*4882a593Smuzhiyun 	u8 val;
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 	/* mapping 802.15.4 to driver spec */
857*4882a593Smuzhiyun 	switch (cca->mode) {
858*4882a593Smuzhiyun 	case NL802154_CCA_ENERGY:
859*4882a593Smuzhiyun 		val = 2;
860*4882a593Smuzhiyun 		break;
861*4882a593Smuzhiyun 	case NL802154_CCA_CARRIER:
862*4882a593Smuzhiyun 		val = 1;
863*4882a593Smuzhiyun 		break;
864*4882a593Smuzhiyun 	case NL802154_CCA_ENERGY_CARRIER:
865*4882a593Smuzhiyun 		switch (cca->opt) {
866*4882a593Smuzhiyun 		case NL802154_CCA_OPT_ENERGY_CARRIER_AND:
867*4882a593Smuzhiyun 			val = 3;
868*4882a593Smuzhiyun 			break;
869*4882a593Smuzhiyun 		default:
870*4882a593Smuzhiyun 			return -EINVAL;
871*4882a593Smuzhiyun 		}
872*4882a593Smuzhiyun 		break;
873*4882a593Smuzhiyun 	default:
874*4882a593Smuzhiyun 		return -EINVAL;
875*4882a593Smuzhiyun 	}
876*4882a593Smuzhiyun 
877*4882a593Smuzhiyun 	return regmap_update_bits(devrec->regmap_short, REG_BBREG2,
878*4882a593Smuzhiyun 				  BBREG2_CCA_MODE_MASK,
879*4882a593Smuzhiyun 				  val << BBREG2_CCA_MODE_SHIFT);
880*4882a593Smuzhiyun }
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun /* array for representing ed levels */
883*4882a593Smuzhiyun static const s32 mrf24j40_ed_levels[] = {
884*4882a593Smuzhiyun 	-9000, -8900, -8800, -8700, -8600, -8500, -8400, -8300, -8200, -8100,
885*4882a593Smuzhiyun 	-8000, -7900, -7800, -7700, -7600, -7500, -7400, -7300, -7200, -7100,
886*4882a593Smuzhiyun 	-7000, -6900, -6800, -6700, -6600, -6500, -6400, -6300, -6200, -6100,
887*4882a593Smuzhiyun 	-6000, -5900, -5800, -5700, -5600, -5500, -5400, -5300, -5200, -5100,
888*4882a593Smuzhiyun 	-5000, -4900, -4800, -4700, -4600, -4500, -4400, -4300, -4200, -4100,
889*4882a593Smuzhiyun 	-4000, -3900, -3800, -3700, -3600, -3500
890*4882a593Smuzhiyun };
891*4882a593Smuzhiyun 
892*4882a593Smuzhiyun /* map ed levels to register value */
893*4882a593Smuzhiyun static const s32 mrf24j40_ed_levels_map[][2] = {
894*4882a593Smuzhiyun 	{ -9000, 0 }, { -8900, 1 }, { -8800, 2 }, { -8700, 5 }, { -8600, 9 },
895*4882a593Smuzhiyun 	{ -8500, 13 }, { -8400, 18 }, { -8300, 23 }, { -8200, 27 },
896*4882a593Smuzhiyun 	{ -8100, 32 }, { -8000, 37 }, { -7900, 43 }, { -7800, 48 },
897*4882a593Smuzhiyun 	{ -7700, 53 }, { -7600, 58 }, { -7500, 63 }, { -7400, 68 },
898*4882a593Smuzhiyun 	{ -7300, 73 }, { -7200, 78 }, { -7100, 83 }, { -7000, 89 },
899*4882a593Smuzhiyun 	{ -6900, 95 }, { -6800, 100 }, { -6700, 107 }, { -6600, 111 },
900*4882a593Smuzhiyun 	{ -6500, 117 }, { -6400, 121 }, { -6300, 125 }, { -6200, 129 },
901*4882a593Smuzhiyun 	{ -6100, 133 },	{ -6000, 138 }, { -5900, 143 }, { -5800, 148 },
902*4882a593Smuzhiyun 	{ -5700, 153 }, { -5600, 159 },	{ -5500, 165 }, { -5400, 170 },
903*4882a593Smuzhiyun 	{ -5300, 176 }, { -5200, 183 }, { -5100, 188 }, { -5000, 193 },
904*4882a593Smuzhiyun 	{ -4900, 198 }, { -4800, 203 }, { -4700, 207 }, { -4600, 212 },
905*4882a593Smuzhiyun 	{ -4500, 216 }, { -4400, 221 }, { -4300, 225 }, { -4200, 228 },
906*4882a593Smuzhiyun 	{ -4100, 233 }, { -4000, 239 }, { -3900, 245 }, { -3800, 250 },
907*4882a593Smuzhiyun 	{ -3700, 253 }, { -3600, 254 }, { -3500, 255 },
908*4882a593Smuzhiyun };
909*4882a593Smuzhiyun 
mrf24j40_set_cca_ed_level(struct ieee802154_hw * hw,s32 mbm)910*4882a593Smuzhiyun static int mrf24j40_set_cca_ed_level(struct ieee802154_hw *hw, s32 mbm)
911*4882a593Smuzhiyun {
912*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
913*4882a593Smuzhiyun 	int i;
914*4882a593Smuzhiyun 
915*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(mrf24j40_ed_levels_map); i++) {
916*4882a593Smuzhiyun 		if (mrf24j40_ed_levels_map[i][0] == mbm)
917*4882a593Smuzhiyun 			return regmap_write(devrec->regmap_short, REG_CCAEDTH,
918*4882a593Smuzhiyun 					    mrf24j40_ed_levels_map[i][1]);
919*4882a593Smuzhiyun 	}
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun 	return -EINVAL;
922*4882a593Smuzhiyun }
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun static const s32 mrf24j40ma_powers[] = {
925*4882a593Smuzhiyun 	0, -50, -120, -190, -280, -370, -490, -630, -1000, -1050, -1120, -1190,
926*4882a593Smuzhiyun 	-1280, -1370, -1490, -1630, -2000, -2050, -2120, -2190, -2280, -2370,
927*4882a593Smuzhiyun 	-2490, -2630, -3000, -3050, -3120, -3190, -3280, -3370, -3490, -3630,
928*4882a593Smuzhiyun };
929*4882a593Smuzhiyun 
mrf24j40_set_txpower(struct ieee802154_hw * hw,s32 mbm)930*4882a593Smuzhiyun static int mrf24j40_set_txpower(struct ieee802154_hw *hw, s32 mbm)
931*4882a593Smuzhiyun {
932*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
933*4882a593Smuzhiyun 	s32 small_scale;
934*4882a593Smuzhiyun 	u8 val;
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun 	if (0 >= mbm && mbm > -1000) {
937*4882a593Smuzhiyun 		val = TXPWRL_0 << TXPWRL_SHIFT;
938*4882a593Smuzhiyun 		small_scale = mbm;
939*4882a593Smuzhiyun 	} else if (-1000 >= mbm && mbm > -2000) {
940*4882a593Smuzhiyun 		val = TXPWRL_10 << TXPWRL_SHIFT;
941*4882a593Smuzhiyun 		small_scale = mbm + 1000;
942*4882a593Smuzhiyun 	} else if (-2000 >= mbm && mbm > -3000) {
943*4882a593Smuzhiyun 		val = TXPWRL_20 << TXPWRL_SHIFT;
944*4882a593Smuzhiyun 		small_scale = mbm + 2000;
945*4882a593Smuzhiyun 	} else if (-3000 >= mbm && mbm > -4000) {
946*4882a593Smuzhiyun 		val = TXPWRL_30 << TXPWRL_SHIFT;
947*4882a593Smuzhiyun 		small_scale = mbm + 3000;
948*4882a593Smuzhiyun 	} else {
949*4882a593Smuzhiyun 		return -EINVAL;
950*4882a593Smuzhiyun 	}
951*4882a593Smuzhiyun 
952*4882a593Smuzhiyun 	switch (small_scale) {
953*4882a593Smuzhiyun 	case 0:
954*4882a593Smuzhiyun 		val |= (TXPWRS_0 << TXPWRS_SHIFT);
955*4882a593Smuzhiyun 		break;
956*4882a593Smuzhiyun 	case -50:
957*4882a593Smuzhiyun 		val |= (TXPWRS_0_5 << TXPWRS_SHIFT);
958*4882a593Smuzhiyun 		break;
959*4882a593Smuzhiyun 	case -120:
960*4882a593Smuzhiyun 		val |= (TXPWRS_1_2 << TXPWRS_SHIFT);
961*4882a593Smuzhiyun 		break;
962*4882a593Smuzhiyun 	case -190:
963*4882a593Smuzhiyun 		val |= (TXPWRS_1_9 << TXPWRS_SHIFT);
964*4882a593Smuzhiyun 		break;
965*4882a593Smuzhiyun 	case -280:
966*4882a593Smuzhiyun 		val |= (TXPWRS_2_8 << TXPWRS_SHIFT);
967*4882a593Smuzhiyun 		break;
968*4882a593Smuzhiyun 	case -370:
969*4882a593Smuzhiyun 		val |= (TXPWRS_3_7 << TXPWRS_SHIFT);
970*4882a593Smuzhiyun 		break;
971*4882a593Smuzhiyun 	case -490:
972*4882a593Smuzhiyun 		val |= (TXPWRS_4_9 << TXPWRS_SHIFT);
973*4882a593Smuzhiyun 		break;
974*4882a593Smuzhiyun 	case -630:
975*4882a593Smuzhiyun 		val |= (TXPWRS_6_3 << TXPWRS_SHIFT);
976*4882a593Smuzhiyun 		break;
977*4882a593Smuzhiyun 	default:
978*4882a593Smuzhiyun 		return -EINVAL;
979*4882a593Smuzhiyun 	}
980*4882a593Smuzhiyun 
981*4882a593Smuzhiyun 	return regmap_update_bits(devrec->regmap_long, REG_RFCON3,
982*4882a593Smuzhiyun 				  TXPWRL_MASK | TXPWRS_MASK, val);
983*4882a593Smuzhiyun }
984*4882a593Smuzhiyun 
mrf24j40_set_promiscuous_mode(struct ieee802154_hw * hw,bool on)985*4882a593Smuzhiyun static int mrf24j40_set_promiscuous_mode(struct ieee802154_hw *hw, bool on)
986*4882a593Smuzhiyun {
987*4882a593Smuzhiyun 	struct mrf24j40 *devrec = hw->priv;
988*4882a593Smuzhiyun 	int ret;
989*4882a593Smuzhiyun 
990*4882a593Smuzhiyun 	if (on) {
991*4882a593Smuzhiyun 		/* set PROMI, ERRPKT and NOACKRSP */
992*4882a593Smuzhiyun 		ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR,
993*4882a593Smuzhiyun 					 BIT_PROMI | BIT_ERRPKT | BIT_NOACKRSP,
994*4882a593Smuzhiyun 					 BIT_PROMI | BIT_ERRPKT | BIT_NOACKRSP);
995*4882a593Smuzhiyun 	} else {
996*4882a593Smuzhiyun 		/* clear PROMI, ERRPKT and NOACKRSP */
997*4882a593Smuzhiyun 		ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR,
998*4882a593Smuzhiyun 					 BIT_PROMI | BIT_ERRPKT | BIT_NOACKRSP,
999*4882a593Smuzhiyun 					 0);
1000*4882a593Smuzhiyun 	}
1001*4882a593Smuzhiyun 
1002*4882a593Smuzhiyun 	return ret;
1003*4882a593Smuzhiyun }
1004*4882a593Smuzhiyun 
1005*4882a593Smuzhiyun static const struct ieee802154_ops mrf24j40_ops = {
1006*4882a593Smuzhiyun 	.owner = THIS_MODULE,
1007*4882a593Smuzhiyun 	.xmit_async = mrf24j40_tx,
1008*4882a593Smuzhiyun 	.ed = mrf24j40_ed,
1009*4882a593Smuzhiyun 	.start = mrf24j40_start,
1010*4882a593Smuzhiyun 	.stop = mrf24j40_stop,
1011*4882a593Smuzhiyun 	.set_channel = mrf24j40_set_channel,
1012*4882a593Smuzhiyun 	.set_hw_addr_filt = mrf24j40_filter,
1013*4882a593Smuzhiyun 	.set_csma_params = mrf24j40_csma_params,
1014*4882a593Smuzhiyun 	.set_cca_mode = mrf24j40_set_cca_mode,
1015*4882a593Smuzhiyun 	.set_cca_ed_level = mrf24j40_set_cca_ed_level,
1016*4882a593Smuzhiyun 	.set_txpower = mrf24j40_set_txpower,
1017*4882a593Smuzhiyun 	.set_promiscuous_mode = mrf24j40_set_promiscuous_mode,
1018*4882a593Smuzhiyun };
1019*4882a593Smuzhiyun 
mrf24j40_intstat_complete(void * context)1020*4882a593Smuzhiyun static void mrf24j40_intstat_complete(void *context)
1021*4882a593Smuzhiyun {
1022*4882a593Smuzhiyun 	struct mrf24j40 *devrec = context;
1023*4882a593Smuzhiyun 	u8 intstat = devrec->irq_buf[1];
1024*4882a593Smuzhiyun 
1025*4882a593Smuzhiyun 	enable_irq(devrec->spi->irq);
1026*4882a593Smuzhiyun 
1027*4882a593Smuzhiyun 	/* Ignore Rx security decryption */
1028*4882a593Smuzhiyun 	if (intstat & BIT_SECIF)
1029*4882a593Smuzhiyun 		regmap_write_async(devrec->regmap_short, REG_SECCON0,
1030*4882a593Smuzhiyun 				   BIT_SECIGNORE);
1031*4882a593Smuzhiyun 
1032*4882a593Smuzhiyun 	/* Check for TX complete */
1033*4882a593Smuzhiyun 	if (intstat & BIT_TXNIF)
1034*4882a593Smuzhiyun 		ieee802154_xmit_complete(devrec->hw, devrec->tx_skb, false);
1035*4882a593Smuzhiyun 
1036*4882a593Smuzhiyun 	/* Check for Rx */
1037*4882a593Smuzhiyun 	if (intstat & BIT_RXIF)
1038*4882a593Smuzhiyun 		mrf24j40_handle_rx(devrec);
1039*4882a593Smuzhiyun }
1040*4882a593Smuzhiyun 
mrf24j40_isr(int irq,void * data)1041*4882a593Smuzhiyun static irqreturn_t mrf24j40_isr(int irq, void *data)
1042*4882a593Smuzhiyun {
1043*4882a593Smuzhiyun 	struct mrf24j40 *devrec = data;
1044*4882a593Smuzhiyun 	int ret;
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 	disable_irq_nosync(irq);
1047*4882a593Smuzhiyun 
1048*4882a593Smuzhiyun 	devrec->irq_buf[0] = MRF24J40_READSHORT(REG_INTSTAT);
1049*4882a593Smuzhiyun 	devrec->irq_buf[1] = 0;
1050*4882a593Smuzhiyun 
1051*4882a593Smuzhiyun 	/* Read the interrupt status */
1052*4882a593Smuzhiyun 	ret = spi_async(devrec->spi, &devrec->irq_msg);
1053*4882a593Smuzhiyun 	if (ret) {
1054*4882a593Smuzhiyun 		enable_irq(irq);
1055*4882a593Smuzhiyun 		return IRQ_NONE;
1056*4882a593Smuzhiyun 	}
1057*4882a593Smuzhiyun 
1058*4882a593Smuzhiyun 	return IRQ_HANDLED;
1059*4882a593Smuzhiyun }
1060*4882a593Smuzhiyun 
mrf24j40_hw_init(struct mrf24j40 * devrec)1061*4882a593Smuzhiyun static int mrf24j40_hw_init(struct mrf24j40 *devrec)
1062*4882a593Smuzhiyun {
1063*4882a593Smuzhiyun 	u32 irq_type;
1064*4882a593Smuzhiyun 	int ret;
1065*4882a593Smuzhiyun 
1066*4882a593Smuzhiyun 	/* Initialize the device.
1067*4882a593Smuzhiyun 		From datasheet section 3.2: Initialization. */
1068*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_short, REG_SOFTRST, 0x07);
1069*4882a593Smuzhiyun 	if (ret)
1070*4882a593Smuzhiyun 		goto err_ret;
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_short, REG_PACON2, 0x98);
1073*4882a593Smuzhiyun 	if (ret)
1074*4882a593Smuzhiyun 		goto err_ret;
1075*4882a593Smuzhiyun 
1076*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_short, REG_TXSTBL, 0x95);
1077*4882a593Smuzhiyun 	if (ret)
1078*4882a593Smuzhiyun 		goto err_ret;
1079*4882a593Smuzhiyun 
1080*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_long, REG_RFCON0, 0x03);
1081*4882a593Smuzhiyun 	if (ret)
1082*4882a593Smuzhiyun 		goto err_ret;
1083*4882a593Smuzhiyun 
1084*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_long, REG_RFCON1, 0x01);
1085*4882a593Smuzhiyun 	if (ret)
1086*4882a593Smuzhiyun 		goto err_ret;
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_long, REG_RFCON2, 0x80);
1089*4882a593Smuzhiyun 	if (ret)
1090*4882a593Smuzhiyun 		goto err_ret;
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_long, REG_RFCON6, 0x90);
1093*4882a593Smuzhiyun 	if (ret)
1094*4882a593Smuzhiyun 		goto err_ret;
1095*4882a593Smuzhiyun 
1096*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_long, REG_RFCON7, 0x80);
1097*4882a593Smuzhiyun 	if (ret)
1098*4882a593Smuzhiyun 		goto err_ret;
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_long, REG_RFCON8, 0x10);
1101*4882a593Smuzhiyun 	if (ret)
1102*4882a593Smuzhiyun 		goto err_ret;
1103*4882a593Smuzhiyun 
1104*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_long, REG_SLPCON1, 0x21);
1105*4882a593Smuzhiyun 	if (ret)
1106*4882a593Smuzhiyun 		goto err_ret;
1107*4882a593Smuzhiyun 
1108*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_short, REG_BBREG2, 0x80);
1109*4882a593Smuzhiyun 	if (ret)
1110*4882a593Smuzhiyun 		goto err_ret;
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_short, REG_CCAEDTH, 0x60);
1113*4882a593Smuzhiyun 	if (ret)
1114*4882a593Smuzhiyun 		goto err_ret;
1115*4882a593Smuzhiyun 
1116*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_short, REG_BBREG6, 0x40);
1117*4882a593Smuzhiyun 	if (ret)
1118*4882a593Smuzhiyun 		goto err_ret;
1119*4882a593Smuzhiyun 
1120*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_short, REG_RFCTL, 0x04);
1121*4882a593Smuzhiyun 	if (ret)
1122*4882a593Smuzhiyun 		goto err_ret;
1123*4882a593Smuzhiyun 
1124*4882a593Smuzhiyun 	ret = regmap_write(devrec->regmap_short, REG_RFCTL, 0x0);
1125*4882a593Smuzhiyun 	if (ret)
1126*4882a593Smuzhiyun 		goto err_ret;
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun 	udelay(192);
1129*4882a593Smuzhiyun 
1130*4882a593Smuzhiyun 	/* Set RX Mode. RXMCR<1:0>: 0x0 normal, 0x1 promisc, 0x2 error */
1131*4882a593Smuzhiyun 	ret = regmap_update_bits(devrec->regmap_short, REG_RXMCR, 0x03, 0x00);
1132*4882a593Smuzhiyun 	if (ret)
1133*4882a593Smuzhiyun 		goto err_ret;
1134*4882a593Smuzhiyun 
1135*4882a593Smuzhiyun 	if (spi_get_device_id(devrec->spi)->driver_data == MRF24J40MC) {
1136*4882a593Smuzhiyun 		/* Enable external amplifier.
1137*4882a593Smuzhiyun 		 * From MRF24J40MC datasheet section 1.3: Operation.
1138*4882a593Smuzhiyun 		 */
1139*4882a593Smuzhiyun 		regmap_update_bits(devrec->regmap_long, REG_TESTMODE, 0x07,
1140*4882a593Smuzhiyun 				   0x07);
1141*4882a593Smuzhiyun 
1142*4882a593Smuzhiyun 		/* Set GPIO3 as output. */
1143*4882a593Smuzhiyun 		regmap_update_bits(devrec->regmap_short, REG_TRISGPIO, 0x08,
1144*4882a593Smuzhiyun 				   0x08);
1145*4882a593Smuzhiyun 
1146*4882a593Smuzhiyun 		/* Set GPIO3 HIGH to enable U5 voltage regulator */
1147*4882a593Smuzhiyun 		regmap_update_bits(devrec->regmap_short, REG_GPIO, 0x08, 0x08);
1148*4882a593Smuzhiyun 
1149*4882a593Smuzhiyun 		/* Reduce TX pwr to meet FCC requirements.
1150*4882a593Smuzhiyun 		 * From MRF24J40MC datasheet section 3.1.1
1151*4882a593Smuzhiyun 		 */
1152*4882a593Smuzhiyun 		regmap_write(devrec->regmap_long, REG_RFCON3, 0x28);
1153*4882a593Smuzhiyun 	}
1154*4882a593Smuzhiyun 
1155*4882a593Smuzhiyun 	irq_type = irq_get_trigger_type(devrec->spi->irq);
1156*4882a593Smuzhiyun 	if (irq_type == IRQ_TYPE_EDGE_RISING ||
1157*4882a593Smuzhiyun 	    irq_type == IRQ_TYPE_EDGE_FALLING)
1158*4882a593Smuzhiyun 		dev_warn(&devrec->spi->dev,
1159*4882a593Smuzhiyun 			 "Using edge triggered irq's are not recommended, because it can cause races and result in a non-functional driver!\n");
1160*4882a593Smuzhiyun 	switch (irq_type) {
1161*4882a593Smuzhiyun 	case IRQ_TYPE_EDGE_RISING:
1162*4882a593Smuzhiyun 	case IRQ_TYPE_LEVEL_HIGH:
1163*4882a593Smuzhiyun 		/* set interrupt polarity to rising */
1164*4882a593Smuzhiyun 		ret = regmap_update_bits(devrec->regmap_long, REG_SLPCON0,
1165*4882a593Smuzhiyun 					 BIT_INTEDGE, BIT_INTEDGE);
1166*4882a593Smuzhiyun 		if (ret)
1167*4882a593Smuzhiyun 			goto err_ret;
1168*4882a593Smuzhiyun 		break;
1169*4882a593Smuzhiyun 	default:
1170*4882a593Smuzhiyun 		/* default is falling edge */
1171*4882a593Smuzhiyun 		break;
1172*4882a593Smuzhiyun 	}
1173*4882a593Smuzhiyun 
1174*4882a593Smuzhiyun 	return 0;
1175*4882a593Smuzhiyun 
1176*4882a593Smuzhiyun err_ret:
1177*4882a593Smuzhiyun 	return ret;
1178*4882a593Smuzhiyun }
1179*4882a593Smuzhiyun 
1180*4882a593Smuzhiyun static void
mrf24j40_setup_tx_spi_messages(struct mrf24j40 * devrec)1181*4882a593Smuzhiyun mrf24j40_setup_tx_spi_messages(struct mrf24j40 *devrec)
1182*4882a593Smuzhiyun {
1183*4882a593Smuzhiyun 	spi_message_init(&devrec->tx_msg);
1184*4882a593Smuzhiyun 	devrec->tx_msg.context = devrec;
1185*4882a593Smuzhiyun 	devrec->tx_msg.complete = write_tx_buf_complete;
1186*4882a593Smuzhiyun 	devrec->tx_hdr_trx.len = 2;
1187*4882a593Smuzhiyun 	devrec->tx_hdr_trx.tx_buf = devrec->tx_hdr_buf;
1188*4882a593Smuzhiyun 	spi_message_add_tail(&devrec->tx_hdr_trx, &devrec->tx_msg);
1189*4882a593Smuzhiyun 	devrec->tx_len_trx.len = 2;
1190*4882a593Smuzhiyun 	devrec->tx_len_trx.tx_buf = devrec->tx_len_buf;
1191*4882a593Smuzhiyun 	spi_message_add_tail(&devrec->tx_len_trx, &devrec->tx_msg);
1192*4882a593Smuzhiyun 	spi_message_add_tail(&devrec->tx_buf_trx, &devrec->tx_msg);
1193*4882a593Smuzhiyun 
1194*4882a593Smuzhiyun 	spi_message_init(&devrec->tx_post_msg);
1195*4882a593Smuzhiyun 	devrec->tx_post_msg.context = devrec;
1196*4882a593Smuzhiyun 	devrec->tx_post_trx.len = 2;
1197*4882a593Smuzhiyun 	devrec->tx_post_trx.tx_buf = devrec->tx_post_buf;
1198*4882a593Smuzhiyun 	spi_message_add_tail(&devrec->tx_post_trx, &devrec->tx_post_msg);
1199*4882a593Smuzhiyun }
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun static void
mrf24j40_setup_rx_spi_messages(struct mrf24j40 * devrec)1202*4882a593Smuzhiyun mrf24j40_setup_rx_spi_messages(struct mrf24j40 *devrec)
1203*4882a593Smuzhiyun {
1204*4882a593Smuzhiyun 	spi_message_init(&devrec->rx_msg);
1205*4882a593Smuzhiyun 	devrec->rx_msg.context = devrec;
1206*4882a593Smuzhiyun 	devrec->rx_trx.len = 2;
1207*4882a593Smuzhiyun 	devrec->rx_trx.tx_buf = devrec->rx_buf;
1208*4882a593Smuzhiyun 	devrec->rx_trx.rx_buf = devrec->rx_buf;
1209*4882a593Smuzhiyun 	spi_message_add_tail(&devrec->rx_trx, &devrec->rx_msg);
1210*4882a593Smuzhiyun 
1211*4882a593Smuzhiyun 	spi_message_init(&devrec->rx_buf_msg);
1212*4882a593Smuzhiyun 	devrec->rx_buf_msg.context = devrec;
1213*4882a593Smuzhiyun 	devrec->rx_buf_msg.complete = mrf24j40_handle_rx_read_buf_complete;
1214*4882a593Smuzhiyun 	devrec->rx_addr_trx.len = 2;
1215*4882a593Smuzhiyun 	devrec->rx_addr_trx.tx_buf = devrec->rx_addr_buf;
1216*4882a593Smuzhiyun 	spi_message_add_tail(&devrec->rx_addr_trx, &devrec->rx_buf_msg);
1217*4882a593Smuzhiyun 	devrec->rx_fifo_buf_trx.rx_buf = devrec->rx_fifo_buf;
1218*4882a593Smuzhiyun 	spi_message_add_tail(&devrec->rx_fifo_buf_trx, &devrec->rx_buf_msg);
1219*4882a593Smuzhiyun 	devrec->rx_lqi_trx.len = 2;
1220*4882a593Smuzhiyun 	devrec->rx_lqi_trx.rx_buf = devrec->rx_lqi_buf;
1221*4882a593Smuzhiyun 	spi_message_add_tail(&devrec->rx_lqi_trx, &devrec->rx_buf_msg);
1222*4882a593Smuzhiyun }
1223*4882a593Smuzhiyun 
1224*4882a593Smuzhiyun static void
mrf24j40_setup_irq_spi_messages(struct mrf24j40 * devrec)1225*4882a593Smuzhiyun mrf24j40_setup_irq_spi_messages(struct mrf24j40 *devrec)
1226*4882a593Smuzhiyun {
1227*4882a593Smuzhiyun 	spi_message_init(&devrec->irq_msg);
1228*4882a593Smuzhiyun 	devrec->irq_msg.context = devrec;
1229*4882a593Smuzhiyun 	devrec->irq_msg.complete = mrf24j40_intstat_complete;
1230*4882a593Smuzhiyun 	devrec->irq_trx.len = 2;
1231*4882a593Smuzhiyun 	devrec->irq_trx.tx_buf = devrec->irq_buf;
1232*4882a593Smuzhiyun 	devrec->irq_trx.rx_buf = devrec->irq_buf;
1233*4882a593Smuzhiyun 	spi_message_add_tail(&devrec->irq_trx, &devrec->irq_msg);
1234*4882a593Smuzhiyun }
1235*4882a593Smuzhiyun 
mrf24j40_phy_setup(struct mrf24j40 * devrec)1236*4882a593Smuzhiyun static void  mrf24j40_phy_setup(struct mrf24j40 *devrec)
1237*4882a593Smuzhiyun {
1238*4882a593Smuzhiyun 	ieee802154_random_extended_addr(&devrec->hw->phy->perm_extended_addr);
1239*4882a593Smuzhiyun 	devrec->hw->phy->current_channel = 11;
1240*4882a593Smuzhiyun 
1241*4882a593Smuzhiyun 	/* mrf24j40 supports max_minbe 0 - 3 */
1242*4882a593Smuzhiyun 	devrec->hw->phy->supported.max_minbe = 3;
1243*4882a593Smuzhiyun 	/* datasheet doesn't say anything about max_be, but we have min_be
1244*4882a593Smuzhiyun 	 * So we assume the max_be default.
1245*4882a593Smuzhiyun 	 */
1246*4882a593Smuzhiyun 	devrec->hw->phy->supported.min_maxbe = 5;
1247*4882a593Smuzhiyun 	devrec->hw->phy->supported.max_maxbe = 5;
1248*4882a593Smuzhiyun 
1249*4882a593Smuzhiyun 	devrec->hw->phy->cca.mode = NL802154_CCA_CARRIER;
1250*4882a593Smuzhiyun 	devrec->hw->phy->supported.cca_modes = BIT(NL802154_CCA_ENERGY) |
1251*4882a593Smuzhiyun 					       BIT(NL802154_CCA_CARRIER) |
1252*4882a593Smuzhiyun 					       BIT(NL802154_CCA_ENERGY_CARRIER);
1253*4882a593Smuzhiyun 	devrec->hw->phy->supported.cca_opts = BIT(NL802154_CCA_OPT_ENERGY_CARRIER_AND);
1254*4882a593Smuzhiyun 
1255*4882a593Smuzhiyun 	devrec->hw->phy->cca_ed_level = -6900;
1256*4882a593Smuzhiyun 	devrec->hw->phy->supported.cca_ed_levels = mrf24j40_ed_levels;
1257*4882a593Smuzhiyun 	devrec->hw->phy->supported.cca_ed_levels_size = ARRAY_SIZE(mrf24j40_ed_levels);
1258*4882a593Smuzhiyun 
1259*4882a593Smuzhiyun 	switch (spi_get_device_id(devrec->spi)->driver_data) {
1260*4882a593Smuzhiyun 	case MRF24J40:
1261*4882a593Smuzhiyun 	case MRF24J40MA:
1262*4882a593Smuzhiyun 		devrec->hw->phy->supported.tx_powers = mrf24j40ma_powers;
1263*4882a593Smuzhiyun 		devrec->hw->phy->supported.tx_powers_size = ARRAY_SIZE(mrf24j40ma_powers);
1264*4882a593Smuzhiyun 		devrec->hw->phy->flags |= WPAN_PHY_FLAG_TXPOWER;
1265*4882a593Smuzhiyun 		break;
1266*4882a593Smuzhiyun 	default:
1267*4882a593Smuzhiyun 		break;
1268*4882a593Smuzhiyun 	}
1269*4882a593Smuzhiyun }
1270*4882a593Smuzhiyun 
mrf24j40_probe(struct spi_device * spi)1271*4882a593Smuzhiyun static int mrf24j40_probe(struct spi_device *spi)
1272*4882a593Smuzhiyun {
1273*4882a593Smuzhiyun 	int ret = -ENOMEM, irq_type;
1274*4882a593Smuzhiyun 	struct ieee802154_hw *hw;
1275*4882a593Smuzhiyun 	struct mrf24j40 *devrec;
1276*4882a593Smuzhiyun 
1277*4882a593Smuzhiyun 	dev_info(&spi->dev, "probe(). IRQ: %d\n", spi->irq);
1278*4882a593Smuzhiyun 
1279*4882a593Smuzhiyun 	/* Register with the 802154 subsystem */
1280*4882a593Smuzhiyun 
1281*4882a593Smuzhiyun 	hw = ieee802154_alloc_hw(sizeof(*devrec), &mrf24j40_ops);
1282*4882a593Smuzhiyun 	if (!hw)
1283*4882a593Smuzhiyun 		goto err_ret;
1284*4882a593Smuzhiyun 
1285*4882a593Smuzhiyun 	devrec = hw->priv;
1286*4882a593Smuzhiyun 	devrec->spi = spi;
1287*4882a593Smuzhiyun 	spi_set_drvdata(spi, devrec);
1288*4882a593Smuzhiyun 	devrec->hw = hw;
1289*4882a593Smuzhiyun 	devrec->hw->parent = &spi->dev;
1290*4882a593Smuzhiyun 	devrec->hw->phy->supported.channels[0] = CHANNEL_MASK;
1291*4882a593Smuzhiyun 	devrec->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT |
1292*4882a593Smuzhiyun 			    IEEE802154_HW_CSMA_PARAMS |
1293*4882a593Smuzhiyun 			    IEEE802154_HW_PROMISCUOUS;
1294*4882a593Smuzhiyun 
1295*4882a593Smuzhiyun 	devrec->hw->phy->flags = WPAN_PHY_FLAG_CCA_MODE |
1296*4882a593Smuzhiyun 				 WPAN_PHY_FLAG_CCA_ED_LEVEL;
1297*4882a593Smuzhiyun 
1298*4882a593Smuzhiyun 	mrf24j40_setup_tx_spi_messages(devrec);
1299*4882a593Smuzhiyun 	mrf24j40_setup_rx_spi_messages(devrec);
1300*4882a593Smuzhiyun 	mrf24j40_setup_irq_spi_messages(devrec);
1301*4882a593Smuzhiyun 
1302*4882a593Smuzhiyun 	devrec->regmap_short = devm_regmap_init_spi(spi,
1303*4882a593Smuzhiyun 						    &mrf24j40_short_regmap);
1304*4882a593Smuzhiyun 	if (IS_ERR(devrec->regmap_short)) {
1305*4882a593Smuzhiyun 		ret = PTR_ERR(devrec->regmap_short);
1306*4882a593Smuzhiyun 		dev_err(&spi->dev, "Failed to allocate short register map: %d\n",
1307*4882a593Smuzhiyun 			ret);
1308*4882a593Smuzhiyun 		goto err_register_device;
1309*4882a593Smuzhiyun 	}
1310*4882a593Smuzhiyun 
1311*4882a593Smuzhiyun 	devrec->regmap_long = devm_regmap_init(&spi->dev,
1312*4882a593Smuzhiyun 					       &mrf24j40_long_regmap_bus,
1313*4882a593Smuzhiyun 					       spi, &mrf24j40_long_regmap);
1314*4882a593Smuzhiyun 	if (IS_ERR(devrec->regmap_long)) {
1315*4882a593Smuzhiyun 		ret = PTR_ERR(devrec->regmap_long);
1316*4882a593Smuzhiyun 		dev_err(&spi->dev, "Failed to allocate long register map: %d\n",
1317*4882a593Smuzhiyun 			ret);
1318*4882a593Smuzhiyun 		goto err_register_device;
1319*4882a593Smuzhiyun 	}
1320*4882a593Smuzhiyun 
1321*4882a593Smuzhiyun 	if (spi->max_speed_hz > MAX_SPI_SPEED_HZ) {
1322*4882a593Smuzhiyun 		dev_warn(&spi->dev, "spi clock above possible maximum: %d",
1323*4882a593Smuzhiyun 			 MAX_SPI_SPEED_HZ);
1324*4882a593Smuzhiyun 		ret = -EINVAL;
1325*4882a593Smuzhiyun 		goto err_register_device;
1326*4882a593Smuzhiyun 	}
1327*4882a593Smuzhiyun 
1328*4882a593Smuzhiyun 	ret = mrf24j40_hw_init(devrec);
1329*4882a593Smuzhiyun 	if (ret)
1330*4882a593Smuzhiyun 		goto err_register_device;
1331*4882a593Smuzhiyun 
1332*4882a593Smuzhiyun 	mrf24j40_phy_setup(devrec);
1333*4882a593Smuzhiyun 
1334*4882a593Smuzhiyun 	/* request IRQF_TRIGGER_LOW as fallback default */
1335*4882a593Smuzhiyun 	irq_type = irq_get_trigger_type(spi->irq);
1336*4882a593Smuzhiyun 	if (!irq_type)
1337*4882a593Smuzhiyun 		irq_type = IRQF_TRIGGER_LOW;
1338*4882a593Smuzhiyun 
1339*4882a593Smuzhiyun 	ret = devm_request_irq(&spi->dev, spi->irq, mrf24j40_isr,
1340*4882a593Smuzhiyun 			       irq_type, dev_name(&spi->dev), devrec);
1341*4882a593Smuzhiyun 	if (ret) {
1342*4882a593Smuzhiyun 		dev_err(printdev(devrec), "Unable to get IRQ");
1343*4882a593Smuzhiyun 		goto err_register_device;
1344*4882a593Smuzhiyun 	}
1345*4882a593Smuzhiyun 
1346*4882a593Smuzhiyun 	dev_dbg(printdev(devrec), "registered mrf24j40\n");
1347*4882a593Smuzhiyun 	ret = ieee802154_register_hw(devrec->hw);
1348*4882a593Smuzhiyun 	if (ret)
1349*4882a593Smuzhiyun 		goto err_register_device;
1350*4882a593Smuzhiyun 
1351*4882a593Smuzhiyun 	return 0;
1352*4882a593Smuzhiyun 
1353*4882a593Smuzhiyun err_register_device:
1354*4882a593Smuzhiyun 	ieee802154_free_hw(devrec->hw);
1355*4882a593Smuzhiyun err_ret:
1356*4882a593Smuzhiyun 	return ret;
1357*4882a593Smuzhiyun }
1358*4882a593Smuzhiyun 
mrf24j40_remove(struct spi_device * spi)1359*4882a593Smuzhiyun static int mrf24j40_remove(struct spi_device *spi)
1360*4882a593Smuzhiyun {
1361*4882a593Smuzhiyun 	struct mrf24j40 *devrec = spi_get_drvdata(spi);
1362*4882a593Smuzhiyun 
1363*4882a593Smuzhiyun 	dev_dbg(printdev(devrec), "remove\n");
1364*4882a593Smuzhiyun 
1365*4882a593Smuzhiyun 	ieee802154_unregister_hw(devrec->hw);
1366*4882a593Smuzhiyun 	ieee802154_free_hw(devrec->hw);
1367*4882a593Smuzhiyun 	/* TODO: Will ieee802154_free_device() wait until ->xmit() is
1368*4882a593Smuzhiyun 	 * complete? */
1369*4882a593Smuzhiyun 
1370*4882a593Smuzhiyun 	return 0;
1371*4882a593Smuzhiyun }
1372*4882a593Smuzhiyun 
1373*4882a593Smuzhiyun static const struct of_device_id mrf24j40_of_match[] = {
1374*4882a593Smuzhiyun 	{ .compatible = "microchip,mrf24j40", .data = (void *)MRF24J40 },
1375*4882a593Smuzhiyun 	{ .compatible = "microchip,mrf24j40ma", .data = (void *)MRF24J40MA },
1376*4882a593Smuzhiyun 	{ .compatible = "microchip,mrf24j40mc", .data = (void *)MRF24J40MC },
1377*4882a593Smuzhiyun 	{ },
1378*4882a593Smuzhiyun };
1379*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, mrf24j40_of_match);
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun static const struct spi_device_id mrf24j40_ids[] = {
1382*4882a593Smuzhiyun 	{ "mrf24j40", MRF24J40 },
1383*4882a593Smuzhiyun 	{ "mrf24j40ma", MRF24J40MA },
1384*4882a593Smuzhiyun 	{ "mrf24j40mc", MRF24J40MC },
1385*4882a593Smuzhiyun 	{ },
1386*4882a593Smuzhiyun };
1387*4882a593Smuzhiyun MODULE_DEVICE_TABLE(spi, mrf24j40_ids);
1388*4882a593Smuzhiyun 
1389*4882a593Smuzhiyun static struct spi_driver mrf24j40_driver = {
1390*4882a593Smuzhiyun 	.driver = {
1391*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(mrf24j40_of_match),
1392*4882a593Smuzhiyun 		.name = "mrf24j40",
1393*4882a593Smuzhiyun 	},
1394*4882a593Smuzhiyun 	.id_table = mrf24j40_ids,
1395*4882a593Smuzhiyun 	.probe = mrf24j40_probe,
1396*4882a593Smuzhiyun 	.remove = mrf24j40_remove,
1397*4882a593Smuzhiyun };
1398*4882a593Smuzhiyun 
1399*4882a593Smuzhiyun module_spi_driver(mrf24j40_driver);
1400*4882a593Smuzhiyun 
1401*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1402*4882a593Smuzhiyun MODULE_AUTHOR("Alan Ott");
1403*4882a593Smuzhiyun MODULE_DESCRIPTION("MRF24J40 SPI 802.15.4 Controller Driver");
1404