ieee802154: add support for setting CCA energy detection levels
[deliverable/linux.git] / drivers / net / ieee802154 / at86rf230.c
CommitLineData
7b8e19b6 1/*
2 * AT86RF230/RF231 driver
3 *
4 * Copyright (C) 2009-2012 Siemens AG
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Written by:
20 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
21 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
22 */
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/interrupt.h>
26#include <linux/gpio.h>
27#include <linux/delay.h>
28#include <linux/mutex.h>
29#include <linux/workqueue.h>
30#include <linux/spinlock.h>
31#include <linux/spi/spi.h>
32#include <linux/spi/at86rf230.h>
33#include <linux/skbuff.h>
34
35#include <net/mac802154.h>
36#include <net/wpan-phy.h>
37
38struct at86rf230_local {
39 struct spi_device *spi;
7b8e19b6 40
41 u8 part;
42 u8 vers;
43
44 u8 buf[2];
45 struct mutex bmux;
46
47 struct work_struct irqwork;
48 struct completion tx_complete;
49
50 struct ieee802154_dev *dev;
51
52 spinlock_t lock;
057dad6f 53 bool irq_busy;
7b8e19b6 54 bool is_tx;
6ca00197
PB
55
56 int rssi_base_val;
7b8e19b6 57};
58
8fad346f
PB
59static inline int is_rf212(struct at86rf230_local *local)
60{
61 return local->part == 7;
62}
63
7b8e19b6 64#define RG_TRX_STATUS (0x01)
65#define SR_TRX_STATUS 0x01, 0x1f, 0
66#define SR_RESERVED_01_3 0x01, 0x20, 5
67#define SR_CCA_STATUS 0x01, 0x40, 6
68#define SR_CCA_DONE 0x01, 0x80, 7
69#define RG_TRX_STATE (0x02)
70#define SR_TRX_CMD 0x02, 0x1f, 0
71#define SR_TRAC_STATUS 0x02, 0xe0, 5
72#define RG_TRX_CTRL_0 (0x03)
73#define SR_CLKM_CTRL 0x03, 0x07, 0
74#define SR_CLKM_SHA_SEL 0x03, 0x08, 3
75#define SR_PAD_IO_CLKM 0x03, 0x30, 4
76#define SR_PAD_IO 0x03, 0xc0, 6
77#define RG_TRX_CTRL_1 (0x04)
78#define SR_IRQ_POLARITY 0x04, 0x01, 0
79#define SR_IRQ_MASK_MODE 0x04, 0x02, 1
80#define SR_SPI_CMD_MODE 0x04, 0x0c, 2
81#define SR_RX_BL_CTRL 0x04, 0x10, 4
82#define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5
83#define SR_IRQ_2_EXT_EN 0x04, 0x40, 6
84#define SR_PA_EXT_EN 0x04, 0x80, 7
85#define RG_PHY_TX_PWR (0x05)
86#define SR_TX_PWR 0x05, 0x0f, 0
87#define SR_PA_LT 0x05, 0x30, 4
88#define SR_PA_BUF_LT 0x05, 0xc0, 6
89#define RG_PHY_RSSI (0x06)
90#define SR_RSSI 0x06, 0x1f, 0
91#define SR_RND_VALUE 0x06, 0x60, 5
92#define SR_RX_CRC_VALID 0x06, 0x80, 7
93#define RG_PHY_ED_LEVEL (0x07)
94#define SR_ED_LEVEL 0x07, 0xff, 0
95#define RG_PHY_CC_CCA (0x08)
96#define SR_CHANNEL 0x08, 0x1f, 0
97#define SR_CCA_MODE 0x08, 0x60, 5
98#define SR_CCA_REQUEST 0x08, 0x80, 7
99#define RG_CCA_THRES (0x09)
100#define SR_CCA_ED_THRES 0x09, 0x0f, 0
101#define SR_RESERVED_09_1 0x09, 0xf0, 4
102#define RG_RX_CTRL (0x0a)
103#define SR_PDT_THRES 0x0a, 0x0f, 0
104#define SR_RESERVED_0a_1 0x0a, 0xf0, 4
105#define RG_SFD_VALUE (0x0b)
106#define SR_SFD_VALUE 0x0b, 0xff, 0
107#define RG_TRX_CTRL_2 (0x0c)
108#define SR_OQPSK_DATA_RATE 0x0c, 0x03, 0
8fad346f
PB
109#define SR_SUB_MODE 0x0c, 0x04, 2
110#define SR_BPSK_QPSK 0x0c, 0x08, 3
643e53c2
PB
111#define SR_OQPSK_SUB1_RC_EN 0x0c, 0x10, 4
112#define SR_RESERVED_0c_5 0x0c, 0x60, 5
7b8e19b6 113#define SR_RX_SAFE_MODE 0x0c, 0x80, 7
114#define RG_ANT_DIV (0x0d)
115#define SR_ANT_CTRL 0x0d, 0x03, 0
116#define SR_ANT_EXT_SW_EN 0x0d, 0x04, 2
117#define SR_ANT_DIV_EN 0x0d, 0x08, 3
118#define SR_RESERVED_0d_2 0x0d, 0x70, 4
119#define SR_ANT_SEL 0x0d, 0x80, 7
120#define RG_IRQ_MASK (0x0e)
121#define SR_IRQ_MASK 0x0e, 0xff, 0
122#define RG_IRQ_STATUS (0x0f)
123#define SR_IRQ_0_PLL_LOCK 0x0f, 0x01, 0
124#define SR_IRQ_1_PLL_UNLOCK 0x0f, 0x02, 1
125#define SR_IRQ_2_RX_START 0x0f, 0x04, 2
126#define SR_IRQ_3_TRX_END 0x0f, 0x08, 3
127#define SR_IRQ_4_CCA_ED_DONE 0x0f, 0x10, 4
128#define SR_IRQ_5_AMI 0x0f, 0x20, 5
129#define SR_IRQ_6_TRX_UR 0x0f, 0x40, 6
130#define SR_IRQ_7_BAT_LOW 0x0f, 0x80, 7
131#define RG_VREG_CTRL (0x10)
132#define SR_RESERVED_10_6 0x10, 0x03, 0
133#define SR_DVDD_OK 0x10, 0x04, 2
134#define SR_DVREG_EXT 0x10, 0x08, 3
135#define SR_RESERVED_10_3 0x10, 0x30, 4
136#define SR_AVDD_OK 0x10, 0x40, 6
137#define SR_AVREG_EXT 0x10, 0x80, 7
138#define RG_BATMON (0x11)
139#define SR_BATMON_VTH 0x11, 0x0f, 0
140#define SR_BATMON_HR 0x11, 0x10, 4
141#define SR_BATMON_OK 0x11, 0x20, 5
142#define SR_RESERVED_11_1 0x11, 0xc0, 6
143#define RG_XOSC_CTRL (0x12)
144#define SR_XTAL_TRIM 0x12, 0x0f, 0
145#define SR_XTAL_MODE 0x12, 0xf0, 4
146#define RG_RX_SYN (0x15)
147#define SR_RX_PDT_LEVEL 0x15, 0x0f, 0
148#define SR_RESERVED_15_2 0x15, 0x70, 4
149#define SR_RX_PDT_DIS 0x15, 0x80, 7
150#define RG_XAH_CTRL_1 (0x17)
151#define SR_RESERVED_17_8 0x17, 0x01, 0
152#define SR_AACK_PROM_MODE 0x17, 0x02, 1
153#define SR_AACK_ACK_TIME 0x17, 0x04, 2
154#define SR_RESERVED_17_5 0x17, 0x08, 3
155#define SR_AACK_UPLD_RES_FT 0x17, 0x10, 4
156#define SR_AACK_FLTR_RES_FT 0x17, 0x20, 5
84dda3c6 157#define SR_CSMA_LBT_MODE 0x17, 0x40, 6
7b8e19b6 158#define SR_RESERVED_17_1 0x17, 0x80, 7
159#define RG_FTN_CTRL (0x18)
160#define SR_RESERVED_18_2 0x18, 0x7f, 0
161#define SR_FTN_START 0x18, 0x80, 7
162#define RG_PLL_CF (0x1a)
163#define SR_RESERVED_1a_2 0x1a, 0x7f, 0
164#define SR_PLL_CF_START 0x1a, 0x80, 7
165#define RG_PLL_DCU (0x1b)
166#define SR_RESERVED_1b_3 0x1b, 0x3f, 0
167#define SR_RESERVED_1b_2 0x1b, 0x40, 6
168#define SR_PLL_DCU_START 0x1b, 0x80, 7
169#define RG_PART_NUM (0x1c)
170#define SR_PART_NUM 0x1c, 0xff, 0
171#define RG_VERSION_NUM (0x1d)
172#define SR_VERSION_NUM 0x1d, 0xff, 0
173#define RG_MAN_ID_0 (0x1e)
174#define SR_MAN_ID_0 0x1e, 0xff, 0
175#define RG_MAN_ID_1 (0x1f)
176#define SR_MAN_ID_1 0x1f, 0xff, 0
177#define RG_SHORT_ADDR_0 (0x20)
178#define SR_SHORT_ADDR_0 0x20, 0xff, 0
179#define RG_SHORT_ADDR_1 (0x21)
180#define SR_SHORT_ADDR_1 0x21, 0xff, 0
181#define RG_PAN_ID_0 (0x22)
182#define SR_PAN_ID_0 0x22, 0xff, 0
183#define RG_PAN_ID_1 (0x23)
184#define SR_PAN_ID_1 0x23, 0xff, 0
185#define RG_IEEE_ADDR_0 (0x24)
186#define SR_IEEE_ADDR_0 0x24, 0xff, 0
187#define RG_IEEE_ADDR_1 (0x25)
188#define SR_IEEE_ADDR_1 0x25, 0xff, 0
189#define RG_IEEE_ADDR_2 (0x26)
190#define SR_IEEE_ADDR_2 0x26, 0xff, 0
191#define RG_IEEE_ADDR_3 (0x27)
192#define SR_IEEE_ADDR_3 0x27, 0xff, 0
193#define RG_IEEE_ADDR_4 (0x28)
194#define SR_IEEE_ADDR_4 0x28, 0xff, 0
195#define RG_IEEE_ADDR_5 (0x29)
196#define SR_IEEE_ADDR_5 0x29, 0xff, 0
197#define RG_IEEE_ADDR_6 (0x2a)
198#define SR_IEEE_ADDR_6 0x2a, 0xff, 0
199#define RG_IEEE_ADDR_7 (0x2b)
200#define SR_IEEE_ADDR_7 0x2b, 0xff, 0
201#define RG_XAH_CTRL_0 (0x2c)
202#define SR_SLOTTED_OPERATION 0x2c, 0x01, 0
203#define SR_MAX_CSMA_RETRIES 0x2c, 0x0e, 1
204#define SR_MAX_FRAME_RETRIES 0x2c, 0xf0, 4
205#define RG_CSMA_SEED_0 (0x2d)
206#define SR_CSMA_SEED_0 0x2d, 0xff, 0
207#define RG_CSMA_SEED_1 (0x2e)
208#define SR_CSMA_SEED_1 0x2e, 0x07, 0
209#define SR_AACK_I_AM_COORD 0x2e, 0x08, 3
210#define SR_AACK_DIS_ACK 0x2e, 0x10, 4
211#define SR_AACK_SET_PD 0x2e, 0x20, 5
212#define SR_AACK_FVN_MODE 0x2e, 0xc0, 6
213#define RG_CSMA_BE (0x2f)
214#define SR_MIN_BE 0x2f, 0x0f, 0
215#define SR_MAX_BE 0x2f, 0xf0, 4
216
217#define CMD_REG 0x80
218#define CMD_REG_MASK 0x3f
219#define CMD_WRITE 0x40
220#define CMD_FB 0x20
221
222#define IRQ_BAT_LOW (1 << 7)
223#define IRQ_TRX_UR (1 << 6)
224#define IRQ_AMI (1 << 5)
225#define IRQ_CCA_ED (1 << 4)
226#define IRQ_TRX_END (1 << 3)
227#define IRQ_RX_START (1 << 2)
228#define IRQ_PLL_UNL (1 << 1)
229#define IRQ_PLL_LOCK (1 << 0)
230
43b5abe0
SH
231#define IRQ_ACTIVE_HIGH 0
232#define IRQ_ACTIVE_LOW 1
233
7b8e19b6 234#define STATE_P_ON 0x00 /* BUSY */
235#define STATE_BUSY_RX 0x01
236#define STATE_BUSY_TX 0x02
237#define STATE_FORCE_TRX_OFF 0x03
238#define STATE_FORCE_TX_ON 0x04 /* IDLE */
239/* 0x05 */ /* INVALID_PARAMETER */
240#define STATE_RX_ON 0x06
241/* 0x07 */ /* SUCCESS */
242#define STATE_TRX_OFF 0x08
243#define STATE_TX_ON 0x09
244/* 0x0a - 0x0e */ /* 0x0a - UNSUPPORTED_ATTRIBUTE */
245#define STATE_SLEEP 0x0F
246#define STATE_BUSY_RX_AACK 0x11
247#define STATE_BUSY_TX_ARET 0x12
028889b0 248#define STATE_RX_AACK_ON 0x16
249#define STATE_TX_ARET_ON 0x19
7b8e19b6 250#define STATE_RX_ON_NOCLK 0x1C
251#define STATE_RX_AACK_ON_NOCLK 0x1D
252#define STATE_BUSY_RX_AACK_NOCLK 0x1E
253#define STATE_TRANSITION_IN_PROGRESS 0x1F
254
8fad346f
PB
255static int
256__at86rf230_detect_device(struct spi_device *spi, u16 *man_id, u8 *part,
257 u8 *version)
258{
259 u8 data[4];
260 u8 *buf = kmalloc(2, GFP_KERNEL);
261 int status;
262 struct spi_message msg;
263 struct spi_transfer xfer = {
264 .len = 2,
265 .tx_buf = buf,
266 .rx_buf = buf,
267 };
268 u8 reg;
269
270 if (!buf)
271 return -ENOMEM;
272
273 for (reg = RG_PART_NUM; reg <= RG_MAN_ID_1; reg++) {
274 buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
275 buf[1] = 0xff;
276 dev_vdbg(&spi->dev, "buf[0] = %02x\n", buf[0]);
277 spi_message_init(&msg);
278 spi_message_add_tail(&xfer, &msg);
279
280 status = spi_sync(spi, &msg);
281 dev_vdbg(&spi->dev, "status = %d\n", status);
282 if (msg.status)
283 status = msg.status;
284
285 dev_vdbg(&spi->dev, "status = %d\n", status);
286 dev_vdbg(&spi->dev, "buf[0] = %02x\n", buf[0]);
287 dev_vdbg(&spi->dev, "buf[1] = %02x\n", buf[1]);
288
289 if (status == 0)
290 data[reg - RG_PART_NUM] = buf[1];
291 else
292 break;
293 }
294
295 if (status == 0) {
296 *part = data[0];
297 *version = data[1];
298 *man_id = (data[3] << 8) | data[2];
299 }
300
301 kfree(buf);
302
303 return status;
304}
305
7b8e19b6 306static int
307__at86rf230_write(struct at86rf230_local *lp, u8 addr, u8 data)
308{
309 u8 *buf = lp->buf;
310 int status;
311 struct spi_message msg;
312 struct spi_transfer xfer = {
313 .len = 2,
314 .tx_buf = buf,
315 };
316
317 buf[0] = (addr & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
318 buf[1] = data;
319 dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
320 dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
321 spi_message_init(&msg);
322 spi_message_add_tail(&xfer, &msg);
323
324 status = spi_sync(lp->spi, &msg);
325 dev_vdbg(&lp->spi->dev, "status = %d\n", status);
326 if (msg.status)
327 status = msg.status;
328
329 dev_vdbg(&lp->spi->dev, "status = %d\n", status);
330 dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
331 dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
332
333 return status;
334}
335
336static int
337__at86rf230_read_subreg(struct at86rf230_local *lp,
338 u8 addr, u8 mask, int shift, u8 *data)
339{
340 u8 *buf = lp->buf;
341 int status;
342 struct spi_message msg;
343 struct spi_transfer xfer = {
344 .len = 2,
345 .tx_buf = buf,
346 .rx_buf = buf,
347 };
348
349 buf[0] = (addr & CMD_REG_MASK) | CMD_REG;
350 buf[1] = 0xff;
351 dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
352 spi_message_init(&msg);
353 spi_message_add_tail(&xfer, &msg);
354
355 status = spi_sync(lp->spi, &msg);
356 dev_vdbg(&lp->spi->dev, "status = %d\n", status);
357 if (msg.status)
358 status = msg.status;
359
360 dev_vdbg(&lp->spi->dev, "status = %d\n", status);
361 dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
362 dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
363
364 if (status == 0)
365 *data = buf[1];
366
367 return status;
368}
369
370static int
371at86rf230_read_subreg(struct at86rf230_local *lp,
372 u8 addr, u8 mask, int shift, u8 *data)
373{
374 int status;
375
376 mutex_lock(&lp->bmux);
377 status = __at86rf230_read_subreg(lp, addr, mask, shift, data);
378 mutex_unlock(&lp->bmux);
379
380 return status;
381}
382
383static int
384at86rf230_write_subreg(struct at86rf230_local *lp,
385 u8 addr, u8 mask, int shift, u8 data)
386{
387 int status;
388 u8 val;
389
390 mutex_lock(&lp->bmux);
391 status = __at86rf230_read_subreg(lp, addr, 0xff, 0, &val);
392 if (status)
393 goto out;
394
395 val &= ~mask;
396 val |= (data << shift) & mask;
397
398 status = __at86rf230_write(lp, addr, val);
399out:
400 mutex_unlock(&lp->bmux);
401
402 return status;
403}
404
405static int
406at86rf230_write_fbuf(struct at86rf230_local *lp, u8 *data, u8 len)
407{
408 u8 *buf = lp->buf;
409 int status;
410 struct spi_message msg;
411 struct spi_transfer xfer_head = {
412 .len = 2,
413 .tx_buf = buf,
414
415 };
416 struct spi_transfer xfer_buf = {
417 .len = len,
418 .tx_buf = data,
419 };
420
421 mutex_lock(&lp->bmux);
422 buf[0] = CMD_WRITE | CMD_FB;
423 buf[1] = len + 2; /* 2 bytes for CRC that isn't written */
424
425 dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
426 dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
427
428 spi_message_init(&msg);
429 spi_message_add_tail(&xfer_head, &msg);
430 spi_message_add_tail(&xfer_buf, &msg);
431
432 status = spi_sync(lp->spi, &msg);
433 dev_vdbg(&lp->spi->dev, "status = %d\n", status);
434 if (msg.status)
435 status = msg.status;
436
437 dev_vdbg(&lp->spi->dev, "status = %d\n", status);
438 dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
439 dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
440
441 mutex_unlock(&lp->bmux);
442 return status;
443}
444
445static int
446at86rf230_read_fbuf(struct at86rf230_local *lp, u8 *data, u8 *len, u8 *lqi)
447{
448 u8 *buf = lp->buf;
449 int status;
450 struct spi_message msg;
451 struct spi_transfer xfer_head = {
452 .len = 2,
453 .tx_buf = buf,
454 .rx_buf = buf,
455 };
456 struct spi_transfer xfer_head1 = {
457 .len = 2,
458 .tx_buf = buf,
459 .rx_buf = buf,
460 };
461 struct spi_transfer xfer_buf = {
462 .len = 0,
463 .rx_buf = data,
464 };
465
466 mutex_lock(&lp->bmux);
467
468 buf[0] = CMD_FB;
469 buf[1] = 0x00;
470
471 spi_message_init(&msg);
472 spi_message_add_tail(&xfer_head, &msg);
473
474 status = spi_sync(lp->spi, &msg);
475 dev_vdbg(&lp->spi->dev, "status = %d\n", status);
476
477 xfer_buf.len = *(buf + 1) + 1;
478 *len = buf[1];
479
480 buf[0] = CMD_FB;
481 buf[1] = 0x00;
482
483 spi_message_init(&msg);
484 spi_message_add_tail(&xfer_head1, &msg);
485 spi_message_add_tail(&xfer_buf, &msg);
486
487 status = spi_sync(lp->spi, &msg);
488
489 if (msg.status)
490 status = msg.status;
491
492 dev_vdbg(&lp->spi->dev, "status = %d\n", status);
493 dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
494 dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
495
496 if (status) {
497 if (lqi && (*len > lp->buf[1]))
498 *lqi = data[lp->buf[1]];
499 }
500 mutex_unlock(&lp->bmux);
501
502 return status;
503}
504
505static int
506at86rf230_ed(struct ieee802154_dev *dev, u8 *level)
507{
508 might_sleep();
509 BUG_ON(!level);
510 *level = 0xbe;
511 return 0;
512}
513
514static int
515at86rf230_state(struct ieee802154_dev *dev, int state)
516{
517 struct at86rf230_local *lp = dev->priv;
518 int rc;
519 u8 val;
520 u8 desired_status;
521
522 might_sleep();
523
524 if (state == STATE_FORCE_TX_ON)
525 desired_status = STATE_TX_ON;
526 else if (state == STATE_FORCE_TRX_OFF)
527 desired_status = STATE_TRX_OFF;
528 else
529 desired_status = state;
530
531 do {
532 rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val);
533 if (rc)
534 goto err;
535 } while (val == STATE_TRANSITION_IN_PROGRESS);
536
537 if (val == desired_status)
538 return 0;
539
540 /* state is equal to phy states */
541 rc = at86rf230_write_subreg(lp, SR_TRX_CMD, state);
542 if (rc)
543 goto err;
544
545 do {
546 rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val);
547 if (rc)
548 goto err;
549 } while (val == STATE_TRANSITION_IN_PROGRESS);
550
551
552 if (val == desired_status)
553 return 0;
554
555 pr_err("unexpected state change: %d, asked for %d\n", val, state);
556 return -EBUSY;
557
558err:
559 pr_err("error: %d\n", rc);
560 return rc;
561}
562
563static int
564at86rf230_start(struct ieee802154_dev *dev)
565{
566 struct at86rf230_local *lp = dev->priv;
567 u8 rc;
568
569 rc = at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1);
570 if (rc)
571 return rc;
572
5b520bbb 573 return at86rf230_state(dev, STATE_RX_AACK_ON);
7b8e19b6 574}
575
576static void
577at86rf230_stop(struct ieee802154_dev *dev)
578{
579 at86rf230_state(dev, STATE_FORCE_TRX_OFF);
580}
581
8fad346f
PB
582static int
583at86rf230_set_channel(struct at86rf230_local *lp, int page, int channel)
584{
6ca00197
PB
585 lp->rssi_base_val = -91;
586
8fad346f
PB
587 return at86rf230_write_subreg(lp, SR_CHANNEL, channel);
588}
589
590static int
591at86rf212_set_channel(struct at86rf230_local *lp, int page, int channel)
592{
593 int rc;
594
595 if (channel == 0)
596 rc = at86rf230_write_subreg(lp, SR_SUB_MODE, 0);
597 else
598 rc = at86rf230_write_subreg(lp, SR_SUB_MODE, 1);
599 if (rc < 0)
600 return rc;
601
6ca00197 602 if (page == 0) {
643e53c2 603 rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, 0);
6ca00197
PB
604 lp->rssi_base_val = -100;
605 } else {
643e53c2 606 rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, 1);
6ca00197
PB
607 lp->rssi_base_val = -98;
608 }
643e53c2
PB
609 if (rc < 0)
610 return rc;
611
8fad346f
PB
612 return at86rf230_write_subreg(lp, SR_CHANNEL, channel);
613}
614
7b8e19b6 615static int
616at86rf230_channel(struct ieee802154_dev *dev, int page, int channel)
617{
618 struct at86rf230_local *lp = dev->priv;
619 int rc;
620
621 might_sleep();
622
8fad346f
PB
623 if (page < 0 || page > 31 ||
624 !(lp->dev->phy->channels_supported[page] & BIT(channel))) {
7b8e19b6 625 WARN_ON(1);
626 return -EINVAL;
627 }
628
8fad346f
PB
629 if (is_rf212(lp))
630 rc = at86rf212_set_channel(lp, page, channel);
631 else
632 rc = at86rf230_set_channel(lp, page, channel);
633 if (rc < 0)
634 return rc;
635
7b8e19b6 636 msleep(1); /* Wait for PLL */
637 dev->phy->current_channel = channel;
643e53c2 638 dev->phy->current_page = page;
7b8e19b6 639
640 return 0;
641}
642
643static int
644at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
645{
646 struct at86rf230_local *lp = dev->priv;
647 int rc;
648 unsigned long flags;
649
5b00f2ee 650 spin_lock(&lp->lock);
057dad6f 651 if (lp->irq_busy) {
5b00f2ee 652 spin_unlock(&lp->lock);
653 return -EBUSY;
654 }
655 spin_unlock(&lp->lock);
656
7b8e19b6 657 might_sleep();
658
659 rc = at86rf230_state(dev, STATE_FORCE_TX_ON);
660 if (rc)
661 goto err;
662
663 spin_lock_irqsave(&lp->lock, flags);
664 lp->is_tx = 1;
16735d02 665 reinit_completion(&lp->tx_complete);
7b8e19b6 666 spin_unlock_irqrestore(&lp->lock, flags);
667
668 rc = at86rf230_write_fbuf(lp, skb->data, skb->len);
669 if (rc)
670 goto err_rx;
671
672 rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_BUSY_TX);
673 if (rc)
674 goto err_rx;
675
676 rc = wait_for_completion_interruptible(&lp->tx_complete);
677 if (rc < 0)
678 goto err_rx;
679
680 rc = at86rf230_start(dev);
681
682 return rc;
683
684err_rx:
685 at86rf230_start(dev);
686err:
687 pr_err("error: %d\n", rc);
688
689 spin_lock_irqsave(&lp->lock, flags);
690 lp->is_tx = 0;
691 spin_unlock_irqrestore(&lp->lock, flags);
692
693 return rc;
694}
695
696static int at86rf230_rx(struct at86rf230_local *lp)
697{
698 u8 len = 128, lqi = 0;
7b8e19b6 699 struct sk_buff *skb;
700
701 skb = alloc_skb(len, GFP_KERNEL);
702
703 if (!skb)
704 return -ENOMEM;
705
5b00f2ee 706 if (at86rf230_read_fbuf(lp, skb_put(skb, len), &len, &lqi))
7b8e19b6 707 goto err;
7b8e19b6 708
709 if (len < 2)
710 goto err;
711
712 skb_trim(skb, len - 2); /* We do not put CRC into the frame */
713
714 ieee802154_rx_irqsafe(lp->dev, skb, lqi);
715
23c34215 716 dev_dbg(&lp->spi->dev, "READ_FBUF: %d %x\n", len, lqi);
7b8e19b6 717
718 return 0;
719err:
720 pr_debug("received frame is too small\n");
721
722 kfree_skb(skb);
723 return -EINVAL;
724}
725
1486774d 726static int
727at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev,
728 struct ieee802154_hw_addr_filt *filt,
729 unsigned long changed)
730{
731 struct at86rf230_local *lp = dev->priv;
732
733 if (changed & IEEE802515_AFILT_SADDR_CHANGED) {
734 dev_vdbg(&lp->spi->dev,
735 "at86rf230_set_hw_addr_filt called for saddr\n");
736 __at86rf230_write(lp, RG_SHORT_ADDR_0, filt->short_addr);
737 __at86rf230_write(lp, RG_SHORT_ADDR_1, filt->short_addr >> 8);
738 }
739
740 if (changed & IEEE802515_AFILT_PANID_CHANGED) {
741 dev_vdbg(&lp->spi->dev,
742 "at86rf230_set_hw_addr_filt called for pan id\n");
743 __at86rf230_write(lp, RG_PAN_ID_0, filt->pan_id);
744 __at86rf230_write(lp, RG_PAN_ID_1, filt->pan_id >> 8);
745 }
746
747 if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) {
748 dev_vdbg(&lp->spi->dev,
749 "at86rf230_set_hw_addr_filt called for IEEE addr\n");
750 at86rf230_write_subreg(lp, SR_IEEE_ADDR_0, filt->ieee_addr[7]);
751 at86rf230_write_subreg(lp, SR_IEEE_ADDR_1, filt->ieee_addr[6]);
752 at86rf230_write_subreg(lp, SR_IEEE_ADDR_2, filt->ieee_addr[5]);
753 at86rf230_write_subreg(lp, SR_IEEE_ADDR_3, filt->ieee_addr[4]);
754 at86rf230_write_subreg(lp, SR_IEEE_ADDR_4, filt->ieee_addr[3]);
755 at86rf230_write_subreg(lp, SR_IEEE_ADDR_5, filt->ieee_addr[2]);
756 at86rf230_write_subreg(lp, SR_IEEE_ADDR_6, filt->ieee_addr[1]);
757 at86rf230_write_subreg(lp, SR_IEEE_ADDR_7, filt->ieee_addr[0]);
758 }
759
760 if (changed & IEEE802515_AFILT_PANC_CHANGED) {
761 dev_vdbg(&lp->spi->dev,
762 "at86rf230_set_hw_addr_filt called for panc change\n");
763 if (filt->pan_coord)
764 at86rf230_write_subreg(lp, SR_AACK_I_AM_COORD, 1);
765 else
766 at86rf230_write_subreg(lp, SR_AACK_I_AM_COORD, 0);
767 }
768
769 return 0;
770}
771
9b2777d6
PB
772static int
773at86rf212_set_txpower(struct ieee802154_dev *dev, int db)
774{
775 struct at86rf230_local *lp = dev->priv;
776 int rc;
777
778 /* typical maximum output is 5dBm with RG_PHY_TX_PWR 0x60, lower five
779 * bits decrease power in 1dB steps. 0x60 represents extra PA gain of
780 * 0dB.
781 * thus, supported values for db range from -26 to 5, for 31dB of
782 * reduction to 0dB of reduction.
783 */
784 if (db > 5 || db < -26)
785 return -EINVAL;
786
787 db = -(db - 5);
788
789 rc = __at86rf230_write(lp, RG_PHY_TX_PWR, 0x60 | db);
790 if (rc)
791 return rc;
792
793 return 0;
794}
795
84dda3c6
PB
796static int
797at86rf212_set_lbt(struct ieee802154_dev *dev, bool on)
798{
799 struct at86rf230_local *lp = dev->priv;
800
801 return at86rf230_write_subreg(lp, SR_CSMA_LBT_MODE, on);
802}
803
ba08fea5
PB
804static int
805at86rf212_set_cca_mode(struct ieee802154_dev *dev, u8 mode)
806{
807 struct at86rf230_local *lp = dev->priv;
808
809 return at86rf230_write_subreg(lp, SR_CCA_MODE, mode);
810}
811
6ca00197
PB
812static int
813at86rf212_set_cca_ed_level(struct ieee802154_dev *dev, s32 level)
814{
815 struct at86rf230_local *lp = dev->priv;
816 int desens_steps;
817
818 if (level < lp->rssi_base_val || level > 30)
819 return -EINVAL;
820
821 desens_steps = (level - lp->rssi_base_val) * 100 / 207;
822
823 return at86rf230_write_subreg(lp, SR_CCA_ED_THRES, desens_steps);
824}
825
7b8e19b6 826static struct ieee802154_ops at86rf230_ops = {
827 .owner = THIS_MODULE,
828 .xmit = at86rf230_xmit,
829 .ed = at86rf230_ed,
830 .set_channel = at86rf230_channel,
831 .start = at86rf230_start,
832 .stop = at86rf230_stop,
1486774d 833 .set_hw_addr_filt = at86rf230_set_hw_addr_filt,
7b8e19b6 834};
835
8fad346f
PB
836static struct ieee802154_ops at86rf212_ops = {
837 .owner = THIS_MODULE,
838 .xmit = at86rf230_xmit,
839 .ed = at86rf230_ed,
840 .set_channel = at86rf230_channel,
841 .start = at86rf230_start,
842 .stop = at86rf230_stop,
843 .set_hw_addr_filt = at86rf230_set_hw_addr_filt,
9b2777d6 844 .set_txpower = at86rf212_set_txpower,
84dda3c6 845 .set_lbt = at86rf212_set_lbt,
ba08fea5 846 .set_cca_mode = at86rf212_set_cca_mode,
6ca00197 847 .set_cca_ed_level = at86rf212_set_cca_ed_level,
8fad346f
PB
848};
849
7b8e19b6 850static void at86rf230_irqwork(struct work_struct *work)
851{
852 struct at86rf230_local *lp =
853 container_of(work, struct at86rf230_local, irqwork);
854 u8 status = 0, val;
855 int rc;
856 unsigned long flags;
857
7b8e19b6 858 rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &val);
859 status |= val;
860
861 status &= ~IRQ_PLL_LOCK; /* ignore */
862 status &= ~IRQ_RX_START; /* ignore */
863 status &= ~IRQ_AMI; /* ignore */
864 status &= ~IRQ_TRX_UR; /* FIXME: possibly handle ???*/
865
866 if (status & IRQ_TRX_END) {
5b00f2ee 867 spin_lock_irqsave(&lp->lock, flags);
7b8e19b6 868 status &= ~IRQ_TRX_END;
869 if (lp->is_tx) {
870 lp->is_tx = 0;
5b00f2ee 871 spin_unlock_irqrestore(&lp->lock, flags);
7b8e19b6 872 complete(&lp->tx_complete);
873 } else {
5b00f2ee 874 spin_unlock_irqrestore(&lp->lock, flags);
7b8e19b6 875 at86rf230_rx(lp);
876 }
877 }
878
5b00f2ee 879 spin_lock_irqsave(&lp->lock, flags);
057dad6f 880 lp->irq_busy = 0;
7b8e19b6 881 spin_unlock_irqrestore(&lp->lock, flags);
057dad6f
SH
882}
883
884static void at86rf230_irqwork_level(struct work_struct *work)
885{
886 struct at86rf230_local *lp =
887 container_of(work, struct at86rf230_local, irqwork);
888
889 at86rf230_irqwork(work);
5b00f2ee 890
891 enable_irq(lp->spi->irq);
7b8e19b6 892}
893
894static irqreturn_t at86rf230_isr(int irq, void *data)
895{
896 struct at86rf230_local *lp = data;
897
898 spin_lock(&lp->lock);
057dad6f 899 lp->irq_busy = 1;
7b8e19b6 900 spin_unlock(&lp->lock);
901
902 schedule_work(&lp->irqwork);
903
904 return IRQ_HANDLED;
905}
906
057dad6f
SH
907static irqreturn_t at86rf230_isr_level(int irq, void *data)
908{
909 disable_irq_nosync(irq);
910
911 return at86rf230_isr(irq, data);
912}
913
43b5abe0
SH
914static int at86rf230_irq_polarity(struct at86rf230_local *lp, int pol)
915{
916 return at86rf230_write_subreg(lp, SR_IRQ_POLARITY, pol);
917}
7b8e19b6 918
919static int at86rf230_hw_init(struct at86rf230_local *lp)
920{
43b5abe0
SH
921 struct at86rf230_platform_data *pdata = lp->spi->dev.platform_data;
922 int rc, irq_pol;
7b8e19b6 923 u8 status;
7b8e19b6 924
925 rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
926 if (rc)
927 return rc;
928
929 dev_info(&lp->spi->dev, "Status: %02x\n", status);
930 if (status == STATE_P_ON) {
8fad346f
PB
931 rc = at86rf230_write_subreg(lp, SR_TRX_CMD,
932 STATE_FORCE_TRX_OFF);
7b8e19b6 933 if (rc)
934 return rc;
935 msleep(1);
936 rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
937 if (rc)
938 return rc;
939 dev_info(&lp->spi->dev, "Status: %02x\n", status);
940 }
941
43b5abe0
SH
942 /* configure irq polarity, defaults to high active */
943 if (pdata->irq_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
944 irq_pol = IRQ_ACTIVE_LOW;
945 else
946 irq_pol = IRQ_ACTIVE_HIGH;
947
948 rc = at86rf230_irq_polarity(lp, irq_pol);
949 if (rc)
950 return rc;
951
057dad6f 952 rc = at86rf230_write_subreg(lp, SR_IRQ_MASK, IRQ_TRX_END);
7b8e19b6 953 if (rc)
954 return rc;
955
956 /* CLKM changes are applied immediately */
957 rc = at86rf230_write_subreg(lp, SR_CLKM_SHA_SEL, 0x00);
958 if (rc)
959 return rc;
960
961 /* Turn CLKM Off */
962 rc = at86rf230_write_subreg(lp, SR_CLKM_CTRL, 0x00);
963 if (rc)
964 return rc;
965 /* Wait the next SLEEP cycle */
966 msleep(100);
967
968 rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_TX_ON);
969 if (rc)
970 return rc;
971 msleep(1);
972
973 rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
974 if (rc)
975 return rc;
976 dev_info(&lp->spi->dev, "Status: %02x\n", status);
977
978 rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &status);
979 if (rc)
980 return rc;
981 if (!status) {
982 dev_err(&lp->spi->dev, "DVDD error\n");
983 return -EINVAL;
984 }
985
986 rc = at86rf230_read_subreg(lp, SR_AVDD_OK, &status);
987 if (rc)
988 return rc;
989 if (!status) {
990 dev_err(&lp->spi->dev, "AVDD error\n");
991 return -EINVAL;
992 }
993
994 return 0;
995}
996
bb1f4606 997static int at86rf230_probe(struct spi_device *spi)
7b8e19b6 998{
43b5abe0 999 struct at86rf230_platform_data *pdata;
7b8e19b6 1000 struct ieee802154_dev *dev;
1001 struct at86rf230_local *lp;
8fad346f
PB
1002 u16 man_id = 0;
1003 u8 part = 0, version = 0, status;
057dad6f
SH
1004 irq_handler_t irq_handler;
1005 work_func_t irq_worker;
8fad346f 1006 int rc;
7b8e19b6 1007 const char *chip;
8fad346f 1008 struct ieee802154_ops *ops = NULL;
7b8e19b6 1009
1010 if (!spi->irq) {
1011 dev_err(&spi->dev, "no IRQ specified\n");
1012 return -EINVAL;
1013 }
1014
43b5abe0
SH
1015 pdata = spi->dev.platform_data;
1016 if (!pdata) {
1017 dev_err(&spi->dev, "no platform_data\n");
1018 return -EINVAL;
1019 }
1020
8fad346f 1021 rc = gpio_request(pdata->rstn, "rstn");
7b8e19b6 1022 if (rc)
8fad346f 1023 return rc;
7b8e19b6 1024
8fad346f
PB
1025 if (gpio_is_valid(pdata->slp_tr)) {
1026 rc = gpio_request(pdata->slp_tr, "slp_tr");
7b8e19b6 1027 if (rc)
1028 goto err_slp_tr;
1029 }
1030
8fad346f 1031 rc = gpio_direction_output(pdata->rstn, 1);
7b8e19b6 1032 if (rc)
1033 goto err_gpio_dir;
1034
8fad346f
PB
1035 if (gpio_is_valid(pdata->slp_tr)) {
1036 rc = gpio_direction_output(pdata->slp_tr, 0);
7b8e19b6 1037 if (rc)
1038 goto err_gpio_dir;
1039 }
1040
1041 /* Reset */
1042 msleep(1);
8fad346f 1043 gpio_set_value(pdata->rstn, 0);
7b8e19b6 1044 msleep(1);
8fad346f 1045 gpio_set_value(pdata->rstn, 1);
7b8e19b6 1046 msleep(1);
1047
8fad346f
PB
1048 rc = __at86rf230_detect_device(spi, &man_id, &part, &version);
1049 if (rc < 0)
7b8e19b6 1050 goto err_gpio_dir;
1051
8fad346f 1052 if (man_id != 0x001f) {
7b8e19b6 1053 dev_err(&spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
8fad346f 1054 man_id >> 8, man_id & 0xFF);
7b8e19b6 1055 rc = -EINVAL;
1056 goto err_gpio_dir;
1057 }
1058
8fad346f 1059 switch (part) {
7b8e19b6 1060 case 2:
1061 chip = "at86rf230";
8fad346f 1062 /* FIXME: should be easy to support; */
7b8e19b6 1063 break;
1064 case 3:
1065 chip = "at86rf231";
8fad346f
PB
1066 ops = &at86rf230_ops;
1067 break;
1068 case 7:
1069 chip = "at86rf212";
1070 if (version == 1)
1071 ops = &at86rf212_ops;
7b8e19b6 1072 break;
1073 default:
1074 chip = "UNKNOWN";
1075 break;
1076 }
1077
8fad346f
PB
1078 dev_info(&spi->dev, "Detected %s chip version %d\n", chip, version);
1079 if (!ops) {
7b8e19b6 1080 rc = -ENOTSUPP;
1081 goto err_gpio_dir;
1082 }
1083
8fad346f
PB
1084 dev = ieee802154_alloc_device(sizeof(*lp), ops);
1085 if (!dev) {
1086 rc = -ENOMEM;
1087 goto err_gpio_dir;
1088 }
1089
1090 lp = dev->priv;
1091 lp->dev = dev;
1092 lp->part = part;
1093 lp->vers = version;
1094
1095 lp->spi = spi;
1096
1097 dev->parent = &spi->dev;
1098 dev->extra_tx_headroom = 0;
1099 dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK;
1100
1101 if (pdata->irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
1102 irq_worker = at86rf230_irqwork;
1103 irq_handler = at86rf230_isr;
1104 } else {
1105 irq_worker = at86rf230_irqwork_level;
1106 irq_handler = at86rf230_isr_level;
1107 }
1108
1109 mutex_init(&lp->bmux);
1110 INIT_WORK(&lp->irqwork, irq_worker);
1111 spin_lock_init(&lp->lock);
1112 init_completion(&lp->tx_complete);
1113
1114 spi_set_drvdata(spi, lp);
1115
643e53c2 1116 if (is_rf212(lp)) {
8fad346f 1117 dev->phy->channels_supported[0] = 0x00007FF;
643e53c2
PB
1118 dev->phy->channels_supported[2] = 0x00007FF;
1119 } else {
8fad346f 1120 dev->phy->channels_supported[0] = 0x7FFF800;
643e53c2 1121 }
8fad346f 1122
7b8e19b6 1123 rc = at86rf230_hw_init(lp);
1124 if (rc)
8fad346f 1125 goto err_hw_init;
7b8e19b6 1126
057dad6f 1127 rc = request_irq(spi->irq, irq_handler,
43b5abe0 1128 IRQF_SHARED | pdata->irq_type,
7b8e19b6 1129 dev_name(&spi->dev), lp);
1130 if (rc)
8fad346f 1131 goto err_hw_init;
7b8e19b6 1132
057dad6f
SH
1133 /* Read irq status register to reset irq line */
1134 rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &status);
1135 if (rc)
1136 goto err_irq;
1137
7b8e19b6 1138 rc = ieee802154_register_device(lp->dev);
1139 if (rc)
1140 goto err_irq;
1141
1142 return rc;
1143
7b8e19b6 1144err_irq:
1145 free_irq(spi->irq, lp);
8fad346f 1146err_hw_init:
7b8e19b6 1147 flush_work(&lp->irqwork);
8fad346f 1148 spi_set_drvdata(spi, NULL);
7b8e19b6 1149 mutex_destroy(&lp->bmux);
1150 ieee802154_free_device(lp->dev);
8fad346f
PB
1151
1152err_gpio_dir:
1153 if (gpio_is_valid(pdata->slp_tr))
1154 gpio_free(pdata->slp_tr);
1155err_slp_tr:
1156 gpio_free(pdata->rstn);
7b8e19b6 1157 return rc;
1158}
1159
bb1f4606 1160static int at86rf230_remove(struct spi_device *spi)
7b8e19b6 1161{
1162 struct at86rf230_local *lp = spi_get_drvdata(spi);
8fad346f 1163 struct at86rf230_platform_data *pdata = spi->dev.platform_data;
7b8e19b6 1164
1165 ieee802154_unregister_device(lp->dev);
1166
1167 free_irq(spi->irq, lp);
1168 flush_work(&lp->irqwork);
1169
8fad346f
PB
1170 if (gpio_is_valid(pdata->slp_tr))
1171 gpio_free(pdata->slp_tr);
1172 gpio_free(pdata->rstn);
7b8e19b6 1173
7b8e19b6 1174 mutex_destroy(&lp->bmux);
1175 ieee802154_free_device(lp->dev);
1176
1177 dev_dbg(&spi->dev, "unregistered at86rf230\n");
1178 return 0;
1179}
1180
1181static struct spi_driver at86rf230_driver = {
1182 .driver = {
1183 .name = "at86rf230",
1184 .owner = THIS_MODULE,
1185 },
1186 .probe = at86rf230_probe,
bb1f4606 1187 .remove = at86rf230_remove,
7b8e19b6 1188};
1189
395a5738 1190module_spi_driver(at86rf230_driver);
7b8e19b6 1191
1192MODULE_DESCRIPTION("AT86RF230 Transceiver Driver");
1193MODULE_LICENSE("GPL v2");
This page took 0.206525 seconds and 5 git commands to generate.