Root/drivers/ieee802154/cc2420.c

1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2
4 * as published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License along
12 * with this program; if not, write to the Free Software Foundation, Inc.,
13 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14 *
15 * Author: Jonathan Cameron <jic23@cam.ac.uk>
16 *
17 * Modified 2010: xue liu <liuxuenetmail@gmail.com>
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/mutex.h>
23#include <linux/spinlock.h>
24#include <linux/gpio.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/workqueue.h>
28#include <linux/spi/spi.h>
29#include <linux/spi/cc2420.h>
30#include <linux/skbuff.h>
31#include <linux/irq.h>
32#include <net/mac802154.h>
33#include <net/wpan-phy.h>
34
35#define CC2420_WRITEREG(x) (x)
36#define CC2420_READREG(x) (0x40 | x)
37#define CC2420_RAMADDR(x) ((x & 0x7F) | 0x80)
38#define CC2420_RAMBANK(x) ((x >> 1) & 0xc0)
39#define CC2420_WRITERAM(x) (x)
40#define CC2420_READRAM(x) (0x20 | x)
41
42#define CC2420_FREQ_MASK 0x3FF
43#define CC2420_ADR_DECODE_MASK 0x0B00
44#define CC2420_FIFOP_THR_MASK 0x003F
45#define CC2420_CRC_MASK 0x80
46#define CC2420_RSSI_MASK 0x7F
47#define CC2420_FSMSTATE_MASK 0x2F
48
49#define CC2420_MANFIDLOW 0x233D
50#define CC2420_MANFIDHIGH 0x3000 /* my chip appears to version 3 - broaden this with testing */
51
52#define RSSI_OFFSET 45
53
54#define STATE_PDOWN 0
55#define STATE_IDLE 1
56#define STATE_RX_CALIBRATE 2
57#define STATE_RX_CALIBRATE2 40
58
59#define STATE_RX_SFD_SEARCH_MIN 3
60#define STATE_RX_SFD_SEARCH_MAX 6
61#define STATE_RX_FRAME 16
62#define STATE_RX_FRAME2 40
63#define STATE_RX_WAIT 14
64#define STATE_RX_OVERFLOW 17
65#define STATE_TX_ACK_CALIBRATE 48
66#define STATE_TX_ACK_PREAMBLE_MIN 49
67#define STATE_TX_ACK_PREAMBLE_MAX 51
68#define STATE_TX_ACK_MIN 52
69#define STATE_TX_ACK_MAX 54
70#define STATE_TX_CALIBRATE 32
71#define STATE_TX_PREAMBLE_MIN 34
72#define STATE_TX_PREAMBLE_MAX 36
73#define STATE_TX_FRAME_MIN 37
74#define STATE_TX_FRAME_MAX 39
75#define STATE_TX_UNDERFLOW 56
76
77struct cc2420_local {
78    struct cc2420_platform_data *pdata;
79    struct spi_device *spi;
80    struct ieee802154_dev *dev;
81    u8 *buf;
82    struct mutex bmux;
83    int fifop_irq;
84    int sfd_irq;
85    struct work_struct fifop_irqwork;
86    struct work_struct sfd_irqwork;
87    spinlock_t lock;
88    unsigned irq_disabled:1;/* P:lock */
89    unsigned is_tx:1; /* P:lock */
90
91    struct completion tx_complete;
92};
93static int cc2420_get_status(struct cc2420_local *lp, u8 *status)
94{
95    int ret;
96    struct spi_message msg;
97    struct spi_transfer xfer = {
98        .len = 1,
99        .tx_buf = lp->buf,
100        .rx_buf = lp->buf,
101    };
102    spi_message_init(&msg);
103    spi_message_add_tail(&xfer, &msg);
104    mutex_lock(&lp->bmux);
105    lp->buf[0] = CC2420_WRITEREG(CC2420_SNOP);
106    dev_vdbg(&lp->spi->dev, "get status command buf[0] = %02x\n", lp->buf[0]);
107    ret = spi_sync(lp->spi, &msg);
108    if (!ret)
109        *status = lp->buf[0];
110    dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", lp->buf[0]);
111    mutex_unlock(&lp->bmux);
112    return ret;
113
114}
115static int cc2420_cmd_strobe(struct cc2420_local *lp,
116                 u8 addr)
117{
118    int ret;
119    u8 status = 0xf;
120    struct spi_message msg;
121    struct spi_transfer xfer = {
122        .len = 1,
123        .tx_buf = lp->buf,
124        .rx_buf = lp->buf,
125    };
126    spi_message_init(&msg);
127    spi_message_add_tail(&xfer, &msg);
128    mutex_lock(&lp->bmux);
129    lp->buf[0] = CC2420_WRITEREG(addr);
130    dev_vdbg(&lp->spi->dev, "cmd strobe buf[0] = %02x\n", lp->buf[0]);
131    ret = spi_sync(lp->spi, &msg);
132    if (!ret)
133        status = lp->buf[0];
134    dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", lp->buf[0]);
135
136    mutex_unlock(&lp->bmux);
137
138    return ret;
139}
140
141static int cc2420_read_16_bit_reg(struct cc2420_local *lp,
142                  u8 addr, u16 *data)
143{
144    int ret;
145    struct spi_message msg;
146    struct spi_transfer xfer = {
147        .len = 3,
148        .tx_buf = lp->buf,
149        .rx_buf = lp->buf,
150    };
151
152    spi_message_init(&msg);
153    spi_message_add_tail(&xfer, &msg);
154    mutex_lock(&lp->bmux);
155    lp->buf[0] = CC2420_READREG(addr);
156    dev_vdbg(&lp->spi->dev, "readreg addr buf[0] = %02x\n", lp->buf[0]);
157    ret = spi_sync(lp->spi, &msg);
158    dev_dbg(&lp->spi->dev, "status = %d\n", ret);
159    mutex_unlock(&lp->bmux);
160    dev_dbg(&lp->spi->dev, "buf[0] = %02x\n", lp->buf[0]);
161    dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
162    dev_dbg(&lp->spi->dev, "buf[2] = %02x\n", lp->buf[2]);
163    if (!ret)
164        *data = ((u16) (lp->buf[1]) << 8) | lp->buf[2];
165    return ret;
166}
167
168static int cc2420_write_16_bit_reg_partial(struct cc2420_local *lp,
169                       u8 addr, u16 data, u16 mask)
170{
171    int ret;
172    struct spi_message msg;
173    struct spi_transfer xfer = {
174        .len = 3,
175        .tx_buf = lp->buf,
176        .rx_buf = lp->buf,
177    };
178    dev_dbg(&lp->spi->dev, "data = %x\n", data);
179    dev_dbg(&lp->spi->dev, "mask = %x\n", mask);
180    spi_message_init(&msg);
181    spi_message_add_tail(&xfer, &msg);
182    mutex_lock(&lp->bmux);
183    lp->buf[0] = CC2420_READREG(addr);
184    dev_vdbg(&lp->spi->dev, "read addr buf[0] = %02x\n", lp->buf[0]);
185    ret = spi_sync(lp->spi, &msg);
186    if (ret)
187        goto err_ret;
188    dev_dbg(&lp->spi->dev, "read buf[0] = %02x\n", lp->buf[0]);
189    dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
190    dev_dbg(&lp->spi->dev, "buf[2] = %02x\n", lp->buf[2]);
191
192    lp->buf[0] = CC2420_WRITEREG(addr);
193
194    lp->buf[1] &= ~(mask >> 8);
195    lp->buf[2] &= ~(mask & 0xFF);
196    lp->buf[1] |= (mask >> 8) & (data >> 8);
197    lp->buf[2] |= (mask & 0xFF) & (data & 0xFF);
198    dev_vdbg(&lp->spi->dev, "writereg addr buf[0] = %02x\n", lp->buf[0]);
199    dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
200    dev_dbg(&lp->spi->dev, "buf[2] = %02x\n", lp->buf[2]);
201    ret = spi_sync(lp->spi, &msg);
202    if (ret)
203        goto err_ret;
204    dev_dbg(&lp->spi->dev, "return status buf[0] = %02x\n", lp->buf[0]);
205    dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
206    dev_dbg(&lp->spi->dev, "buf[2] = %02x\n", lp->buf[2]);
207
208err_ret:
209    mutex_unlock(&lp->bmux);
210    return ret;
211}
212
213static int cc2420_channel(struct ieee802154_dev *dev, int page, int channel)
214{
215    struct cc2420_local *lp = dev->priv;
216    int ret;
217
218    might_sleep();
219    dev_dbg(&lp->spi->dev, "trying to set channel\n");
220
221    BUG_ON(page != 0);
222    BUG_ON(channel < CC2420_MIN_CHANNEL);
223    BUG_ON(channel > CC2420_MAX_CHANNEL);
224
225    ret = cc2420_write_16_bit_reg_partial(lp, CC2420_FSCTRL, 357 + 5*(channel - 11), CC2420_FREQ_MASK);
226
227    dev->phy->current_channel = channel;
228    return ret;
229}
230
231static int cc2420_write_ram(struct cc2420_local *lp, u16 addr, u8 len, u8 *data)
232{
233    int status;
234    struct spi_message msg;
235    struct spi_transfer xfer_head = {
236        .len = 2,
237        .tx_buf = lp->buf,
238        .rx_buf = lp->buf,
239    };
240    struct spi_transfer xfer_buf = {
241        .len = len,
242        .tx_buf = data,
243    };
244
245    mutex_lock(&lp->bmux);
246    lp->buf[0] = CC2420_RAMADDR(addr);
247    lp->buf[1] = CC2420_WRITERAM(CC2420_RAMBANK(addr));
248    dev_dbg(&lp->spi->dev, "write ram addr buf[0] = %02x\n", lp->buf[0]);
249    dev_dbg(&lp->spi->dev, "ram bank buf[1] = %02x\n", lp->buf[1]);
250
251    spi_message_init(&msg);
252    spi_message_add_tail(&xfer_head, &msg);
253    spi_message_add_tail(&xfer_buf, &msg);
254
255    status = spi_sync(lp->spi, &msg);
256    dev_dbg(&lp->spi->dev, "spi status = %d\n", status);
257    if (msg.status)
258        status = msg.status;
259    dev_dbg(&lp->spi->dev, "cc2420 status = %02x\n", lp->buf[0]);
260    dev_dbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
261
262    mutex_unlock(&lp->bmux);
263    return status;
264}
265
266static int cc2420_write_txfifo(struct cc2420_local *lp, u8 *data, u8 len)
267{
268    int status;
269    /* Length byte must include FCS even if calculated in hardware */
270    int len_byte = len + 2;
271    struct spi_message msg;
272    struct spi_transfer xfer_head = {
273        .len = 1,
274        .tx_buf = lp->buf,
275        .rx_buf = lp->buf,
276    };
277    struct spi_transfer xfer_len = {
278        .len = 1,
279        .tx_buf = &len_byte,
280    };
281    struct spi_transfer xfer_buf = {
282        .len = len,
283        .tx_buf = data,
284    };
285
286    mutex_lock(&lp->bmux);
287    lp->buf[0] = CC2420_WRITEREG(CC2420_TXFIFO);
288    dev_vdbg(&lp->spi->dev, "TX_FIFO addr buf[0] = %02x\n", lp->buf[0]);
289
290    spi_message_init(&msg);
291    spi_message_add_tail(&xfer_head, &msg);
292    spi_message_add_tail(&xfer_len, &msg);
293    spi_message_add_tail(&xfer_buf, &msg);
294
295    status = spi_sync(lp->spi, &msg);
296    dev_vdbg(&lp->spi->dev, "status = %d\n", status);
297    if (msg.status)
298        status = msg.status;
299    dev_vdbg(&lp->spi->dev, "status = %d\n", status);
300    dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", lp->buf[0]);
301
302    mutex_unlock(&lp->bmux);
303    return status;
304}
305
306static int
307cc2420_read_rxfifo(struct cc2420_local *lp, u8 *data, u8 *len, u8 *lqi)
308{
309    int status;
310    struct spi_message msg;
311    struct spi_transfer xfer_head = {
312        .len = 2,
313        .tx_buf = lp->buf,
314        .rx_buf = lp->buf,
315    };
316    struct spi_transfer xfer_buf = {
317        .len = *len,
318        .rx_buf = data,
319    };
320
321    mutex_lock(&lp->bmux);
322    lp->buf[0] = CC2420_READREG(CC2420_RXFIFO);
323    lp->buf[1] = 0x00;
324    dev_vdbg(&lp->spi->dev, "read rxfifo buf[0] = %02x\n", lp->buf[0]);
325    dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", lp->buf[1]);
326    spi_message_init(&msg);
327    spi_message_add_tail(&xfer_head, &msg);
328    spi_message_add_tail(&xfer_buf, &msg);
329
330    status = spi_sync(lp->spi, &msg);
331    dev_vdbg(&lp->spi->dev, "status = %d\n", status);
332    if (msg.status)
333        status = msg.status;
334    dev_vdbg(&lp->spi->dev, "status = %d\n", status);
335    dev_vdbg(&lp->spi->dev, "return status buf[0] = %02x\n", lp->buf[0]);
336    dev_vdbg(&lp->spi->dev, "length buf[1] = %02x\n", lp->buf[1]);
337
338    *lqi = data[lp->buf[1] - 1] & 0x7f;
339    *len = lp->buf[1]; /* it should be less than 130 */
340
341    mutex_unlock(&lp->bmux);
342
343    return status;
344}
345
346
347static int cc2420_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
348{
349    struct cc2420_local *lp = dev->priv;
350    int rc;
351    unsigned long flags;
352    u8 status = 0;
353
354    pr_debug("%s\n", __func__);
355
356    might_sleep();
357
358    rc = cc2420_cmd_strobe(lp, CC2420_SFLUSHTX);
359    if (rc)
360        goto err_rx;
361    rc = cc2420_write_txfifo(lp, skb->data, skb->len);
362    if (rc)
363        goto err_rx;
364
365    /* TODO: test CCA pin */
366
367    rc = cc2420_get_status(lp, &status);
368    if (rc)
369        goto err_rx;
370
371    if (status & CC2420_STATUS_TX_UNDERFLOW) {
372        dev_err(&lp->spi->dev, "cc2420 tx underflow!\n");
373        goto err_rx;
374    }
375
376    spin_lock_irqsave(&lp->lock, flags);
377    BUG_ON(lp->is_tx);
378    lp->is_tx = 1;
379    INIT_COMPLETION(lp->tx_complete);
380    spin_unlock_irqrestore(&lp->lock, flags);
381
382    rc = cc2420_cmd_strobe(lp, CC2420_STXONCCA);
383    if (rc)
384        goto err;
385
386    rc = wait_for_completion_interruptible(&lp->tx_complete);
387    if (rc < 0)
388        goto err;
389
390    cc2420_cmd_strobe(lp, CC2420_SFLUSHTX);
391    cc2420_cmd_strobe(lp, CC2420_SRXON);
392
393    return rc;
394
395err:
396    spin_lock_irqsave(&lp->lock, flags);
397    lp->is_tx = 0;
398    spin_unlock_irqrestore(&lp->lock, flags);
399err_rx:
400    cc2420_cmd_strobe(lp, CC2420_SFLUSHTX);
401    cc2420_cmd_strobe(lp, CC2420_SRXON);
402    return rc;
403}
404
405static int cc2420_rx(struct cc2420_local *lp)
406{
407    u8 len = 128;
408    u8 lqi = 0; /* link quality */
409    int rc;
410    struct sk_buff *skb;
411
412    skb = alloc_skb(len, GFP_KERNEL);
413    if (!skb)
414        return -ENOMEM;
415
416    rc = cc2420_read_rxfifo(lp, skb_put(skb, len), &len, &lqi);
417    if (len < 2) {
418        kfree_skb(skb);
419        return -EINVAL;
420    }
421
422    /* Clip last two bytes. When using hardware FCS they get replaced with
423     * correlation value, FCS flag and RSSI value */
424    skb_trim(skb, len-2);
425
426    ieee802154_rx_irqsafe(lp->dev, skb, lqi);
427
428    dev_dbg(&lp->spi->dev, "RXFIFO: %d %d %x\n", rc, len, lqi);
429
430    return 0;
431}
432
433static int
434cc2420_set_hw_addr_filt(struct ieee802154_dev *dev,
435                        struct ieee802154_hw_addr_filt *filt,
436                        unsigned long changed)
437{
438    struct cc2420_local *lp = dev->priv;
439    u16 reg;
440
441    might_sleep();
442
443    if (changed & IEEE802515_IEEEADDR_CHANGED)
444        cc2420_write_ram(lp, CC2420_RAM_IEEEADR,
445                         IEEE802154_ALEN,
446                         filt->ieee_addr);
447
448    if (changed & IEEE802515_SADDR_CHANGED) {
449        u8 short_addr[2];
450        short_addr[0] = filt->short_addr & 0xff;/* LSB */
451        short_addr[1] = filt->short_addr >> 8; /* MSB */
452        cc2420_write_ram(lp, CC2420_RAM_SHORTADR,
453                         sizeof(short_addr),
454                         short_addr);
455    }
456
457    if (changed & IEEE802515_PANID_CHANGED) {
458        u8 panid[2];
459        panid[0] = filt->pan_id & 0xff; /* LSB */
460        panid[1] = filt->pan_id >> 8; /* MSB */
461        cc2420_write_ram(lp, CC2420_RAM_PANID,
462                         sizeof(panid),
463                         panid);
464    }
465
466    if (changed & IEEE802515_PANC_CHANGED) {
467        cc2420_read_16_bit_reg(lp, CC2420_MDMCTRL0, &reg);
468        if (filt->pan_coord)
469            reg |= 1 << CC2420_MDMCTRL0_PANCRD;
470        else
471            reg &= ~(1 << CC2420_MDMCTRL0_PANCRD);
472        cc2420_write_16_bit_reg_partial(lp, CC2420_MDMCTRL0,
473                                        reg, 1 << CC2420_MDMCTRL0_PANCRD);
474    }
475
476    return 0;
477}
478
479static int cc2420_ed(struct ieee802154_dev *dev, u8 *level)
480{
481    struct cc2420_local *lp = dev->priv;
482    u16 rssi;
483    int ret;
484    dev_dbg(&lp->spi->dev, "ed called\n");
485
486    ret = cc2420_read_16_bit_reg(lp, CC2420_RSSI, &rssi);
487    if (ret)
488        return ret;
489
490    /* P = RSSI_VAL + RSSI_OFFSET[dBm] */
491    *level = (rssi & CC2420_RSSI_MASK) + RSSI_OFFSET;
492    return ret;
493}
494
495static int cc2420_start(struct ieee802154_dev *dev)
496{
497    return cc2420_cmd_strobe(dev->priv, CC2420_SRXON);
498}
499
500static void cc2420_stop(struct ieee802154_dev *dev)
501{
502    cc2420_cmd_strobe(dev->priv, CC2420_SRFOFF);
503}
504
505static struct ieee802154_ops cc2420_ops = {
506    .owner = THIS_MODULE,
507    .xmit = cc2420_tx,
508    .ed = cc2420_ed,
509    .start = cc2420_start,
510    .stop = cc2420_stop,
511    .set_channel = cc2420_channel,
512    .set_hw_addr_filt = cc2420_set_hw_addr_filt,
513};
514
515static int cc2420_register(struct cc2420_local *lp)
516{
517    int ret = -ENOMEM;
518    lp->dev = ieee802154_alloc_device(sizeof(*lp), &cc2420_ops);
519    if (!lp->dev)
520        goto err_ret;
521
522    lp->dev->priv = lp;
523    lp->dev->parent = &lp->spi->dev;
524    //look this up.
525    lp->dev->extra_tx_headroom = 0;
526    //and this
527    //lp->dev->channel_mask = 0x7ff;
528    //and more.
529
530    /* We do support only 2.4 Ghz */
531    lp->dev->phy->channels_supported[0] = 0x7FFF800;
532    lp->dev->flags = IEEE802154_HW_OMIT_CKSUM;
533
534    dev_dbg(&lp->spi->dev, "registered cc2420\n");
535    ret = ieee802154_register_device(lp->dev);
536    if (ret)
537        goto err_free_device;
538
539    return 0;
540err_free_device:
541    ieee802154_free_device(lp->dev);
542err_ret:
543    return ret;
544}
545
546static void cc2420_unregister(struct cc2420_local *lp)
547{
548    ieee802154_unregister_device(lp->dev);
549    //check this is needed
550    ieee802154_free_device(lp->dev);
551}
552
553static irqreturn_t cc2420_isr(int irq, void *data)
554{
555    struct cc2420_local *lp = data;
556
557    spin_lock(&lp->lock);
558    if (!lp->irq_disabled) {
559        disable_irq_nosync(irq);
560        lp->irq_disabled = 1;
561    }
562    spin_unlock(&lp->lock);
563
564    if (irq == lp->sfd_irq)
565        schedule_work(&lp->sfd_irqwork);
566
567    if (irq == lp->fifop_irq)
568        schedule_work(&lp->fifop_irqwork);
569
570    return IRQ_HANDLED;
571}
572
573static void cc2420_fifop_irqwork(struct work_struct *work)
574{
575    struct cc2420_local *lp
576        = container_of(work, struct cc2420_local, fifop_irqwork);
577    unsigned long flags;
578
579    dev_dbg(&lp->spi->dev, "fifop interrupt received\n");
580
581    if (gpio_get_value(lp->pdata->fifo))
582        cc2420_rx(lp);
583    else
584        dev_err(&lp->spi->dev, "rxfifo overflow\n");
585
586    cc2420_cmd_strobe(lp, CC2420_SFLUSHRX);
587    cc2420_cmd_strobe(lp, CC2420_SFLUSHRX);
588
589    spin_lock_irqsave(&lp->lock, flags);
590    if (lp->irq_disabled) {
591        lp->irq_disabled = 0;
592        enable_irq(lp->fifop_irq);
593    }
594    spin_unlock_irqrestore(&lp->lock, flags);
595}
596
597static void cc2420_sfd_irqwork(struct work_struct *work)
598{
599    struct cc2420_local *lp
600        = container_of(work, struct cc2420_local, sfd_irqwork);
601    unsigned long flags;
602
603    dev_dbg(&lp->spi->dev, "sfd interrupt received\n");
604
605    spin_lock_irqsave(&lp->lock, flags);
606    if (lp->is_tx) {
607        lp->is_tx = 0;
608        spin_unlock_irqrestore(&lp->lock, flags);
609        complete(&lp->tx_complete);
610    } else {
611        spin_unlock_irqrestore(&lp->lock, flags);
612    }
613
614    spin_lock_irqsave(&lp->lock, flags);
615    if (lp->irq_disabled) {
616        lp->irq_disabled = 0;
617        enable_irq(lp->sfd_irq);
618    }
619    spin_unlock_irqrestore(&lp->lock, flags);
620}
621
622static int cc2420_hw_init(struct cc2420_local *lp)
623{
624    int ret;
625    u16 state;
626    u8 status = 0xff;
627    int timeout = 500; /* 500us delay */
628    ret = cc2420_read_16_bit_reg(lp, CC2420_FSMSTATE, &state);
629    if (ret)
630        goto error_ret;
631    /* reset has occured prior to this, so there should be no other option */
632    if (state != STATE_PDOWN) {
633        ret = -EINVAL;
634        goto error_ret;
635    }
636    ret = cc2420_cmd_strobe(lp, CC2420_SXOSCON);
637    if (ret)
638        goto error_ret;
639
640    do {
641        ret = cc2420_get_status(lp, &status);
642        if (ret)
643            goto error_ret;
644        if (timeout-- <= 0) {
645            dev_err(&lp->spi->dev, "oscillator start failed!\n");
646            return ret;
647        }
648        udelay(1);
649    } while (!(status & CC2420_STATUS_XOSC16M_STABLE));
650
651    dev_info(&lp->spi->dev, "oscillator succesfully brought up\n");
652
653    return 0;
654error_ret:
655    return ret;
656}
657
658static int __devinit cc2420_probe(struct spi_device *spi)
659{
660    int ret;
661    u16 manidl, manidh;
662    struct cc2420_local *lp = kzalloc(sizeof *lp, GFP_KERNEL);
663    if (!lp) {
664        ret = -ENOMEM;
665        goto error_ret;
666    }
667
668    lp->pdata = spi->dev.platform_data;
669    if (!lp->pdata) {
670        dev_err(&spi->dev, "no platform data\n");
671        ret = -EINVAL;
672        goto err_free_local;
673    }
674    spi_set_drvdata(spi, lp);
675    mutex_init(&lp->bmux);
676    INIT_WORK(&lp->fifop_irqwork, cc2420_fifop_irqwork);
677    INIT_WORK(&lp->sfd_irqwork, cc2420_sfd_irqwork);
678    spin_lock_init(&lp->lock);
679    init_completion(&lp->tx_complete);
680
681    lp->spi = spi;
682    lp->buf = kmalloc(3*sizeof *lp->buf, GFP_KERNEL);
683    if (!lp->buf) {
684        ret = -ENOMEM;
685        goto err_free_local;
686    }
687
688    /* Request all the gpio's */
689    ret = gpio_request(lp->pdata->fifo, "fifo");
690    if (ret)
691        goto err_free_buf;
692    ret = gpio_request(lp->pdata->cca, "cca");
693    if (ret)
694        goto err_free_gpio_fifo;
695#if 0
696    /* This is causing problems as fifop is gpio 0 ? */
697    ret = gpio_request(lp->pdata->fifop, "fifop");
698    if (ret)
699        goto err_free_gpio_cca;
700#endif
701    ret = gpio_request(lp->pdata->sfd, "sfd");
702    if (ret)
703        goto err_free_gpio_fifop;
704    ret = gpio_request(lp->pdata->reset, "reset");
705    if (ret)
706        goto err_free_gpio_sfd;
707    ret = gpio_request(lp->pdata->vreg, "vreg");
708    if (ret)
709        goto err_free_gpio_reset;
710    /* Configure the gpios appropriately */
711
712    /* Enable the voltage regulator */
713    ret = gpio_direction_output(lp->pdata->vreg, 1);
714    if (ret)
715        goto err_free_gpio_reset;
716    udelay(600); /* Time for regulator to power up */
717    /* Toggle the reset */
718    ret = gpio_direction_output(lp->pdata->reset, 0);
719    if (ret)
720        goto err_disable_vreg;
721    udelay(10); /* no idea how long this should be? */
722    ret = gpio_direction_output(lp->pdata->reset, 1);
723    if (ret)
724        goto err_disable_vreg;
725    udelay(10);
726
727    ret = gpio_direction_input(lp->pdata->cca);
728    if (ret)
729        goto err_disable_vreg;
730    ret = gpio_direction_input(lp->pdata->fifo);
731    if (ret)
732        goto err_disable_vreg;
733    ret = gpio_direction_input(lp->pdata->fifop);
734    if (ret)
735        goto err_disable_vreg;
736    ret = gpio_direction_input(lp->pdata->sfd);
737    if (ret)
738        goto err_disable_vreg;
739
740
741    /* Check this is actually a cc2420 */
742    ret = cc2420_read_16_bit_reg(lp, CC2420_MANFIDL, &manidl);
743    if (ret)
744        goto err_free_gpio_vreg;
745    ret = cc2420_read_16_bit_reg(lp, CC2420_MANFIDH, &manidh);
746    if (ret)
747        goto err_free_gpio_vreg;
748    if (manidh != CC2420_MANFIDHIGH || manidl != CC2420_MANFIDLOW) {
749        dev_err(&spi->dev, "Incorrect manufacturer id %x%x\n", manidh, manidl);
750        ret = -ENODEV;
751        goto err_free_gpio_vreg;
752    }
753    /* TODO: make it more readable */
754    dev_info(&lp->spi->dev, "Found Chipcon CC2420\n");
755    dev_info(&lp->spi->dev, "Manufacturer ID:%x Version:%x Partnum:%x\n",
756           manidl & 0x0FFF, manidh >> 12, manidl >> 12);
757
758    ret = cc2420_hw_init(lp);
759    if (ret)
760        goto err_disable_vreg;
761
762    lp->fifop_irq = gpio_to_irq(lp->pdata->fifop);
763    lp->sfd_irq = gpio_to_irq(lp->pdata->sfd);
764
765    ret = request_irq(lp->fifop_irq,
766                      cc2420_isr,
767                      IRQF_TRIGGER_RISING | IRQF_SHARED,
768                      dev_name(&spi->dev),
769                      lp);
770    if (ret) {
771        dev_err(&spi->dev, "could not get fifop irq?\n");
772        goto err_free_fifop_irq;
773    }
774
775    ret = request_irq(lp->sfd_irq,
776                      cc2420_isr,
777                      IRQF_TRIGGER_FALLING,
778                      dev_name(&spi->dev),
779                      lp);
780    if (ret) {
781        dev_err(&spi->dev, "could not get sfd irq?\n");
782        goto err_free_sfd_irq;
783    }
784
785    dev_info(&lp->spi->dev, "Set fifo threshold to 127\n");
786    cc2420_write_16_bit_reg_partial(lp, CC2420_IOCFG0, 127, CC2420_FIFOP_THR_MASK);
787    ret = cc2420_register(lp);
788    if (ret)
789        goto err_free_sfd_irq;
790
791    return 0;
792err_free_sfd_irq:
793    free_irq(lp->sfd_irq, lp);
794err_free_fifop_irq:
795    free_irq(lp->fifop_irq, lp);
796err_disable_vreg:
797    gpio_set_value(lp->pdata->vreg, 0);
798err_free_gpio_vreg:
799    gpio_free(lp->pdata->vreg);
800err_free_gpio_reset:
801    gpio_free(lp->pdata->reset);
802err_free_gpio_sfd:
803    gpio_free(lp->pdata->sfd);
804err_free_gpio_fifop:
805    gpio_free(lp->pdata->fifop);
806//err_free_gpio_cca:
807// gpio_free(lp->pdata->cca);
808err_free_gpio_fifo:
809    gpio_free(lp->pdata->fifo);
810err_free_buf:
811    kfree(lp->buf);
812err_free_local:
813    kfree(lp);
814error_ret:
815    return ret;
816}
817
818static int __devexit cc2420_remove(struct spi_device *spi)
819{
820    struct cc2420_local *lp = spi_get_drvdata(spi);
821
822    cc2420_unregister(lp);
823    free_irq(lp->fifop_irq, lp);
824    free_irq(lp->sfd_irq, lp);
825    flush_work(&lp->fifop_irqwork);
826    flush_work(&lp->sfd_irqwork);
827    gpio_free(lp->pdata->vreg);
828    gpio_free(lp->pdata->reset);
829    gpio_free(lp->pdata->sfd);
830    gpio_free(lp->pdata->fifop);
831    gpio_free(lp->pdata->cca);
832    gpio_free(lp->pdata->fifo);
833    kfree(lp->buf);
834    kfree(lp);
835
836    return 0;
837}
838
839static struct spi_driver cc2420_driver = {
840    .driver = {
841        .name = "cc2420",
842        .owner = THIS_MODULE,
843    },
844    .probe = cc2420_probe,
845    .remove = __devexit_p(cc2420_remove),
846};
847
848static int __init cc2420_init(void)
849{
850    return spi_register_driver(&cc2420_driver);
851}
852module_init(cc2420_init);
853
854static void __exit cc2420_exit(void)
855{
856    spi_unregister_driver(&cc2420_driver);
857}
858module_exit(cc2420_exit);
859MODULE_LICENSE("GPL v2");
860

Archive Download this file



interactive