Hello.

As the patch is already applied this review may came a bit late but I think its
worth mentioning anyway.

On Mon, 2010-04-12 at 13:16, Hennerich, Michael wrote:
> This patch adds support for the Analog Devices ADF7242 Low Power 2.4GHz 
> IEEE802.15.4 Transceiver IC.
> The ADF7242 features IEEE802.15.4 frame filtering, automatic ACK transmission 
> and CSMA-CA with frame retry using an add-on firmware blob.
> This approach allows future extensions to 802.15.4 Standard to be supported 
> by simply updating the firmware file.
> The driver was tested on a Blackfin Processor platform, but should work on 
> any embedded platform running Linux.
> More information as well as the firmware file can be found here:
> http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:adf7242

Please cut your commit messages after 72-80 characters. Makes it a lot more
readable.

> Resend -  since this mail got rejected due to size and failed to get list 
> moderator approval afterwards.
> 
> Signed-off-by: Michael Hennerich <[email protected]>
> 
>  drivers/ieee802154/Kconfig   |    5 +
>  drivers/ieee802154/Makefile  |    1 +
>  drivers/ieee802154/adf7242.c | 1033 
> ++++++++++++++++++++++++++++++++++++++++++
>  include/linux/spi/adf7242.h  |   53 +++
>  4 files changed, 1092 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig
> index 186d326..7fe6c2a 100644
> --- a/drivers/ieee802154/Kconfig
> +++ b/drivers/ieee802154/Kconfig
> @@ -44,3 +44,8 @@ config IEEE802154_CC2420
>         tristate "CC2420 driver"
>         depends on SPI
>         depends on  IEEE802154_DRIVERS
> +
> +config IEEE802154_ADF7242
> +       tristate "ADF7242 transceiver driver"
> +       depends on IEEE802154_DRIVERS && MAC802154
> +       depends on SPI
> diff --git a/drivers/ieee802154/Makefile b/drivers/ieee802154/Makefile
> index b54a097..cb33815 100644
> --- a/drivers/ieee802154/Makefile
> +++ b/drivers/ieee802154/Makefile
> @@ -3,5 +3,6 @@ obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
>  obj-$(CONFIG_IEEE802154_SERIAL) += serial.o
>  obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
>  obj-$(CONFIG_IEEE802154_CC2420) += cc2420.o
> +obj-$(CONFIG_IEEE802154_ADF7242) += adf7242.o
> 
>  EXTRA_CFLAGS += -DDEBUG -DCONFIG_FFD
> diff --git a/drivers/ieee802154/adf7242.c b/drivers/ieee802154/adf7242.c
> new file mode 100644
> index 0000000..b034d9e
> --- /dev/null
> +++ b/drivers/ieee802154/adf7242.c
> @@ -0,0 +1,1033 @@
> +/*
> + * Analog Devices ADF7242 Low-Power IEEE 802.15.4 Transceiver
> + *
> + * Copyright 2009-2010 Analog Devices Inc.
> + *
> + * Licensed under the GPL-2 or later.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/delay.h>
> +#include <linux/mutex.h>
> +#include <linux/workqueue.h>
> +#include <linux/spinlock.h>
> +#include <linux/firmware.h>
> +#include <linux/spi/spi.h>
> +#include <linux/spi/adf7242.h>
> +
> +#include <net/mac802154.h>
> +#include <net/wpan-phy.h>
> +
> +/*
> + * DEBUG LEVEL
> + *     0       OFF
> + *     1       INFO
> + *     2       INFO + TRACE
> + */
> +
> +#define ADF_DEBUG      0
> +#define DBG(n, args...) do { if (ADF_DEBUG >= (n)) pr_debug(args); } while 
> (0)

Why do you need an extra layer over the standard debug macros?

You debug is also very chatty. Do you really need a statement everytime you
enter a function? I normally have this for development, but it gets distracting
once the driver starts working.

> +#define FIRMWARE       "adf7242_firmware.bin"
> +#define MAX_POLL_LOOPS 10
> +
> +/* All Registers */
> +
> +#define REG_EXT_CTRL   0x100 /* RW External LNA/PA and internal PA control 
> configuration bits */
> +#define REG_TX_FSK_TEST 0x101 /* RW TX FSK test mode configuration */
> +#define REG_CCA1       0x105 /* RW RSSI threshold for CCA */
> +#define REG_CCA2       0x106 /* RW CCA mode configuration */
> +#define REG_BUFFERCFG  0x107 /* RW RX_BUFFER overwrite control */
> +#define REG_PKT_CFG    0x108 /* RW FCS evaluation configuration */
> +#define REG_DELAYCFG0  0x109 /* RW RC_RX command to SFD or sync word search 
> delay */
> +#define REG_DELAYCFG1  0x10A /* RW RC_TX command to TX state */
> +#define REG_DELAYCFG2  0x10B /* RW Mac delay extention */
> +#define REG_SYNC_WORD0 0x10C /* RW sync word bits [7:0] of [23:0]  */
> +#define REG_SYNC_WORD1 0x10D /* RW sync word bits [15:8] of [23:0]  */
> +#define REG_SYNC_WORD2 0x10E /* RW sync word bits [23:16] of [23:0]  */
> +#define REG_SYNC_CONFIG        0x10F /* RW sync word configuration */

Wrong indentation.

> +#define REG_RC_CFG     0x13E /* RW RX / TX packet configuration */
> +#define REG_RC_VAR44   0x13F /* RW RESERVED */
> +#define REG_CH_FREQ0   0x300 /* RW Channel Frequency Settings - Low Byte */
> +#define REG_CH_FREQ1   0x301 /* RW Channel Frequency Settings - Middle Byte 
> */
> +#define REG_CH_FREQ2   0x302 /* RW Channel Frequency Settings - 2 MSBs */
> +#define REG_TX_FD      0x304 /* RW TX Frequency Deviation Register */
> +#define REG_DM_CFG0    0x305 /* RW RX Discriminator BW Register */
> +#define REG_TX_M       0x306 /* RW TX Mode Register */
> +#define REG_RX_M       0x307 /* RW RX Mode Register */
> +#define REG_RRB                0x30C /* R RSSI Readback Register */
> +#define REG_LRB                0x30D /* R Link Quality Readback Register */
> +#define REG_DR0                0x30E /* RW bits [15:8] of [15:0] for data 
> rate setting */
> +#define REG_DR1                0x30F /* RW bits [7:0] of [15:0] for data 
> rate setting */

Also wrong indent.

> +#define REG_PRAMPG     0x313 /* RW RESERVED */
> +#define REG_TXPB       0x314 /* RW TX Packet Storage Base Address */
> +#define REG_RXPB       0x315 /* RW RX Packet Storage Base Address */
> +#define REG_TMR_CFG0   0x316 /* RW Wake up Timer Configuration Register - 
> High Byte */
> +#define REG_TMR_CFG1   0x317 /* RW Wake up Timer Configuration Register - 
> Low Byte */
> +#define REG_TMR_RLD0   0x318 /* RW Wake up Timer Value Register - High Byte 
> */
> +#define REG_TMR_RLD1   0x319 /* RW Wake up Timer Value Register - Low Byte */
> +#define REG_TMR_CTRL   0x31A /* RW Wake up Timer Timeout flag */
> +#define REG_PD_AUX     0x31E /* RW Battmon enable */
> +#define REG_GP_CFG     0x32C /* RW GPIO Configuration */
> +#define REG_GP_OUT     0x32D /* RW GPIO Configuration */
> +#define REG_GP_IN      0x32E /* R GPIO Configuration */
> +#define REG_SYNT       0x335 /* RW bandwidth calibration timers */
> +#define REG_CAL_CFG    0x33D /* RW Calibration Settings */
> +#define REG_SYNT_CAL   0x371 /* RW Oscillator and Doubler Configuration */
> +#define REG_IIRF_CFG   0x389 /* RW BB Filter Decimation Rate */
> +#define REG_CDR_CFG    0x38A /* RW CDR kVCO */
> +#define REG_DM_CFG1    0x38B /* RW Postdemodulator Filter */
> +#define REG_AGCSTAT    0x38E /* R RXBB Ref Osc Calibration Engine Readback */
> +#define REG_RXCAL0     0x395 /* RW RX BB filter tuning, LSB */
> +#define REG_RXCAL1     0x396 /* RW RX BB filter tuning, MSB */
> +#define REG_RXFE_CFG   0x39B /* RW RXBB Ref Osc & RXFE Calibration */
> +#define REG_PA_RR      0x3A7 /* RW Set PA ramp rate */
> +#define REG_PA_CFG     0x3A8 /* RW PA enable */
> +#define REG_EXTPA_CFG  0x3A9 /* RW External PA BIAS DAC */
> +#define REG_EXTPA_MSC  0x3AA /* RW PA Bias Mode */
> +#define REG_ADC_RBK    0x3AE /* R Readback temp */
> +#define REG_AGC_CFG1   0x3B2 /* RW GC Parameters */
> +#define REG_AGC_MAX    0x3B4 /* RW Slew rate  */
> +#define REG_AGC_CFG2   0x3B6 /* RW RSSI Parameters */
> +#define REG_AGC_CFG3   0x3B7 /* RW RSSI Parameters */
> +#define REG_AGC_CFG4   0x3B8 /* RW RSSI Parameters */
> +#define REG_AGC_CFG5   0x3B9 /* RW RSSI & NDEC Parameters */
> +#define REG_AGC_CFG6   0x3BA /* RW NDEC Parameters */
> +#define REG_OCL_CFG1   0x3C4 /* RW OCL System Parameters */
> +#define REG_IRQ1_EN0   0x3C7 /* RW Interrupt Mask set bits  [7:0] of [15:0] 
> for IRQ1 */
> +#define REG_IRQ1_EN1   0x3C8 /* RW Interrupt Mask set bits  [15:8] of [15:0] 
> for IRQ1 */
> +#define REG_IRQ2_EN0   0x3C9 /* RW Interrupt Mask set bits  [7:0] of [15:0] 
> for IRQ2 */
> +#define REG_IRQ2_EN1   0x3CA /* RW Interrupt Mask set bits  [15:8] of [15:0] 
> for IRQ2 */
> +#define REG_IRQ1_SRC0  0x3CB /* RW Interrupt Source  bits  [7:0] of [15:0] 
> for IRQ */
> +#define REG_IRQ1_SRC1  0x3CC /* RW Interrupt Source bits  [15:8] of [15:0] 
> for IRQ */
> +#define REG_OCL_BW0    0x3D2 /* RW OCL System Parameters */
> +#define REG_OCL_BW1    0x3D3 /* RW OCL System Parameters */
> +#define REG_OCL_BW2    0x3D4 /* RW OCL System Parameters */
> +#define REG_OCL_BW3    0x3D5 /* RW OCL System Parameters */
> +#define REG_OCL_BW4    0x3D6 /* RW OCL System Parameters */
> +#define REG_OCL_BWS    0x3D7 /* RW OCL System Parameters */
> +#define REG_OCL_CFG13  0x3E0 /* RW OCL System Parameters */
> +#define REG_GP_DRV     0x3E3 /* RW I/O pads Configuration and bg trim */
> +#define REG_BM_CFG     0x3E6 /* RW Battery Monitor Threshold Voltage setting 
> */
> +#define REG_SFD_15_4   0x3F4 /* RW Option to set non standard SFD */
> +#define REG_AFC_CFG    0x3F7 /* RW AFC mode and polarity */
> +#define REG_AFC_KI_KP  0x3F8 /* RW AFC ki and kp */
> +#define REG_AFC_RANGE  0x3F9 /* RW AFC range */
> +#define REG_AFC_READ   0x3FA /* RW Readback frequency error */
> +
> +#define REG_PAN_ID0            0x112
> +#define REG_PAN_ID1            0x113
> +#define REG_SHORT_ADDR_0       0x114
> +#define REG_SHORT_ADDR_1       0x115
> +#define REG_IEEE_ADDR_0                0x116
> +#define REG_IEEE_ADDR_1                0x117
> +#define REG_IEEE_ADDR_2                0x118
> +#define REG_IEEE_ADDR_3                0x119
> +#define REG_IEEE_ADDR_4                0x11A
> +#define REG_IEEE_ADDR_5                0x11B
> +#define REG_IEEE_ADDR_6                0x11C
> +#define REG_IEEE_ADDR_7                0x11D

indent

> +#define REG_FFILT_CFG          0x11E
> +#define REG_AUTO_CFG           0x11F
> +#define REG_AUTO_TX1           0x120
> +#define REG_AUTO_TX2           0x121
> +#define REG_AUTO_STATUS                0x122

indent

> +
> +/* REG_FFILT_CFG */
> +#define ACCEPT_BEACON_FRAMES   (1 << 0)
> +#define ACCEPT_DATA_FRAMES     (1 << 1)
> +#define ACCEPT_ACK_FRAMES      (1 << 2)
> +#define ACCEPT_MACCMD_FRAMES   (1 << 3)
> +#define ACCEPT_RESERVED_FRAMES (1 << 4)
> +#define ACCEPT_ALL_ADDRESS     (1 << 5)
> +
> +/* REG_AUTO_CFG */
> +#define AUTO_ACK_FRAMEPEND     (1 << 0)
> +#define IS_PANCOORD            (1 << 1)
> +#define RX_AUTO_ACK_EN         (1 << 3)
> +#define CSMA_CA_RX_TURNAROUND  (1 << 4)
> +
> +/* REG_AUTO_TX1 */
> +#define MAX_FRAME_RETRIES(x)   ((x) & 0xF)
> +#define MAX_CCA_RETRIES(x)     (((x) & 0x7) << 4)
> +
> +/* REG_AUTO_TX2 */
> +#define CSMA_MAX_BE(x)         ((x) & 0xF)
> +#define CSMA_MIN_BE(x)         (((x) & 0xF) << 4)
> +
> +#define CMD_SPI_NOP            0xFF /* No operation. Use for dummy writes */
> +#define CMD_SPI_PKT_WR         0x10 /* Write telegram to the Packet RAM 
> starting from the TX packet base address pointer tx_packet_base */
> +#define CMD_SPI_PKT_RD         0x30 /* Read telegram from the Packet RAM 
> starting from RX packet base address pointer rxpb.rx_packet_base */
> +#define CMD_SPI_MEM_WR(x)      (0x18 + (x >> 8)) /* Write data to MCR or 
> Packet RAM sequentially */
> +#define CMD_SPI_MEM_RD(x)      (0x38 + (x >> 8)) /* Read data from MCR or 
> Packet RAM sequentially */
> +#define CMD_SPI_MEMR_WR(x)     (0x08 + (x >> 8)) /* Write data to MCR or 
> Packet RAM as random block */
> +#define CMD_SPI_MEMR_RD(x)     (0x28 + (x >> 8)) /* Read data from MCR or 
> Packet RAM as random block */
> +#define CMD_SPI_PRAM_WR                0x1E /* Write data sequentially to 
> current PRAM page selected */

Even more below. Please check all your defines.

> +#define CMD_RC_SLEEP           0xB1 /* Invoke transition of radio controller 
> into SLEEP state */
> +#define CMD_RC_IDLE            0xB2 /* Invoke transition of radio controller 
> into IDLE state */
> +#define CMD_RC_PHY_RDY         0xB3 /* Invoke transition of radio controller 
> into PHY_RDY state */
> +#define CMD_RC_RX              0xB4 /* Invoke transition of radio controller 
> into RX state */
> +#define CMD_RC_TX              0xB5 /* Invoke transition of radio controller 
> into TX state */
> +#define CMD_RC_MEAS            0xB6 /* Invoke transition of radio controller 
> into MEAS state */
> +#define CMD_RC_CCA             0xB7 /* Invoke Clear channel assessment */
> +#define CMD_RC_CSMACA          0xC1 /* initiates CSMA-CA channel access 
> sequence and frame transmission */
> +
> +/* STATUS */
> +
> +#define STAT_SPI_READY         (1 << 7)
> +#define STAT_IRQ_STATUS                (1 << 6)
> +#define STAT_RC_READY          (1 << 5)
> +#define STAT_CCA_RESULT                (1 << 4)
> +#define RC_STATUS_IDLE         1
> +#define RC_STATUS_MEAS         2
> +#define RC_STATUS_PHY_RDY      3
> +#define RC_STATUS_RX           4
> +#define RC_STATUS_TX           5
> +#define RC_STATUS_MASK         0xF
> +
> +/* AUTO_STATUS */
> +
> +#define SUCCESS                        0
> +#define SUCCESS_DATPEND                1
> +#define FAILURE_CSMACA         2
> +#define FAILURE_NOACK          3
> +#define AUTO_STATUS_MASK       0x3
> +
> +#define PRAM_PAGESIZE          256
> +
> +/* IRQ1 */
> +
> +#define IRQ_CCA_COMPLETE       (1 << 0)
> +#define IRQ_SFD_RX             (1 << 1)
> +#define IRQ_SFD_TX             (1 << 2)
> +#define IRQ_RX_PKT_RCVD                (1 << 3)
> +#define IRQ_TX_PKT_SENT                (1 << 4)
> +#define IRQ_FRAME_VALID                (1 << 5)
> +#define IRQ_ADDRESS_VALID      (1 << 6)
> +#define IRQ_CSMA_CA            (1 << 7)
> +
> +#define AUTO_TX_TURNAROUND     (1 << 3)
> +#define ADDON_EN               (1 << 4)
> +
> +struct adf7242_local {
> +       struct spi_device *spi;
> +       struct adf7242_platform_data *pdata;
> +       struct work_struct irqwork;
> +       struct completion tx_complete;
> +       struct ieee802154_dev *dev;
> +       struct mutex bmux;
> +       spinlock_t lock;
> +       unsigned irq_disabled:1; /* P: lock */
> +       unsigned is_tx:1; /* P: lock */
> +       unsigned mode;
> +       unsigned tx_irq;
> +       int tx_stat;
> +       u8 buf[3];
> +};
> +
> +static int adf7242_status(struct adf7242_local *lp, u8 *stat)
> +{
> +       int status;
> +       struct spi_message msg;
> +       u8 buf_tx[1], buf_rx[1];
> +
> +       struct spi_transfer xfer = {
> +               .len    = 1,
> +               .tx_buf = buf_tx,
> +               .rx_buf = buf_rx,
> +       };
> +
> +       buf_tx[0] = CMD_SPI_NOP;
> +
> +       spi_message_init(&msg);
> +       spi_message_add_tail(&xfer, &msg);
> +
> +       mutex_lock(&lp->bmux);
> +       status = spi_sync(lp->spi, &msg);
> +       mutex_unlock(&lp->bmux);
> +
> +       *stat = buf_rx[0];
> +
> +       return status;
> +}
> +
> +static int adf7242_wait_ready(struct adf7242_local *lp)
> +{
> +       u8 stat;
> +       int cnt = 0;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +
> +       do {
> +               adf7242_status(lp, &stat);
> +               cnt++;
> +       } while (!(stat & STAT_RC_READY) && (cnt < MAX_POLL_LOOPS));
> +
> +       DBG(2, "%s :Exit loops=%d\n", __func__, cnt);
> +
> +       return 0;
> +}
> +
> +static int adf7242_wait_status(struct adf7242_local *lp, int status)
> +{
> +       u8 stat;
> +       int cnt = 0;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +
> +       do {
> +               adf7242_status(lp, &stat);
> +               stat &= RC_STATUS_MASK;
> +               cnt++;
> +       } while ((stat != status) && (cnt < MAX_POLL_LOOPS));
> +
> +       DBG(2, "%s :Exit loops=%d\n", __func__, cnt);
> +
> +       return 0;
> +}
> +
> +static int adf7242_write_fbuf(struct adf7242_local *lp, u8 *data, u8 len)
> +{
> +       u8 *buf = lp->buf;
> +       int status;
> +       struct spi_message msg;
> +       struct spi_transfer xfer_head = {
> +               .len    = 2,
> +               .tx_buf = buf,
> +
> +       };
> +       struct spi_transfer xfer_buf = {
> +               .len    = len,
> +               .tx_buf = data,
> +       };
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +       adf7242_wait_ready(lp);
> +
> +       buf[0] = CMD_SPI_PKT_WR;
> +       buf[1] = len + 2;
> +
> +       spi_message_init(&msg);
> +       spi_message_add_tail(&xfer_head, &msg);
> +       spi_message_add_tail(&xfer_buf, &msg);
> +
> +       mutex_lock(&lp->bmux);
> +       status = spi_sync(lp->spi, &msg);
> +       mutex_unlock(&lp->bmux);
> +
> +       DBG(2, "%s :Exit\n", __func__);
> +       return status;
> +}
> +
> +static int adf7242_read_fbuf(struct adf7242_local *lp,
> +                            u8 *data, u8 *len, u8 *lqi)
> +{
> +       u8 *buf = lp->buf;
> +       int status;
> +       struct spi_message msg;
> +       struct spi_transfer xfer_head = {
> +               .len    = 3,
> +               .tx_buf = buf,
> +               .rx_buf = buf,
> +
> +       };
> +       struct spi_transfer xfer_buf = {
> +               .len    = *len,
> +               .rx_buf = data,
> +       };
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +       adf7242_wait_ready(lp);
> +
> +       mutex_lock(&lp->bmux);

Move this mutex around spi_sync as in the other functions?

> +       buf[0] = CMD_SPI_PKT_RD;
> +       buf[1] = CMD_SPI_NOP;
> +       buf[2] = 0;             /* PHR */
> +
> +       spi_message_init(&msg);
> +       spi_message_add_tail(&xfer_head, &msg);
> +       spi_message_add_tail(&xfer_buf, &msg);
> +
> +       status = spi_sync(lp->spi, &msg);
> +
> +       if (!status) {
> +               *lqi = data[buf[2] - 1];
> +               *len = buf[2];  /* PHR */
> +       }
> +
> +       mutex_unlock(&lp->bmux);
> +       DBG(2, "%s :Exit\n", __func__);
> +       return status;
> +}
> +
> +static int adf7242_read_reg(struct adf7242_local *lp,
> +                           u16 addr, u8 *data)
> +{
> +       int status;
> +       struct spi_message msg;
> +       u8 buf_tx[4], buf_rx[4];
> +
> +       struct spi_transfer xfer = {
> +               .len    = 4,
> +               .tx_buf = buf_tx,
> +               .rx_buf = buf_rx,
> +       };
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +       adf7242_wait_ready(lp);
> +
> +       mutex_lock(&lp->bmux);

Same for this mutex.

> +       buf_tx[0] = CMD_SPI_MEM_RD(addr);
> +       buf_tx[1] = addr;
> +       buf_tx[2] = CMD_SPI_NOP;
> +       buf_tx[3] = CMD_SPI_NOP;
> +
> +       spi_message_init(&msg);
> +       spi_message_add_tail(&xfer, &msg);
> +
> +       status = spi_sync(lp->spi, &msg);
> +       if (msg.status)
> +               status = msg.status;
> +
> +       if (!status)
> +               *data = buf_rx[3];
> +
> +       mutex_unlock(&lp->bmux);
> +       DBG(2, "%s :Exit\n", __func__);
> +
> +       return status;
> +}
> +
> +static int adf7242_write_reg(struct adf7242_local *lp,
> +                            u16 addr, u8 data)
> +{
> +       int status;
> +       struct spi_message msg;
> +       u8 buf_tx[4];
> +
> +       struct spi_transfer xfer = {
> +               .len    = 3,
> +               .tx_buf = buf_tx,
> +       };
> +       DBG(2, "%s :Enter\n", __func__);
> +       adf7242_wait_ready(lp);
> +
> +       buf_tx[0] = CMD_SPI_MEM_WR(addr);
> +       buf_tx[1] = addr;
> +       buf_tx[2] = data;
> +
> +       spi_message_init(&msg);
> +       spi_message_add_tail(&xfer, &msg);
> +
> +       mutex_lock(&lp->bmux);
> +       status = spi_sync(lp->spi, &msg);
> +       mutex_unlock(&lp->bmux);
> +       DBG(2, "%s :Exit\n", __func__);
> +
> +       return status;
> +}
> +
> +static int adf7242_cmd(struct adf7242_local *lp, u8 cmd)
> +{
> +       int status;
> +       struct spi_message msg;
> +       u8 buf_tx[1];
> +
> +       struct spi_transfer xfer = {
> +               .len    = 1,
> +               .tx_buf = buf_tx,
> +       };
> +
> +       DBG(2, "%s :Enter CMD=0x%X\n", __func__, cmd);
> +       adf7242_wait_ready(lp);
> +
> +       buf_tx[0] = cmd;
> +       spi_message_init(&msg);
> +       spi_message_add_tail(&xfer, &msg);
> +
> +       mutex_lock(&lp->bmux);
> +       status = spi_sync(lp->spi, &msg);
> +       mutex_unlock(&lp->bmux);
> +       DBG(2, "%s :Exit\n", __func__);
> +
> +       return status;
> +}
> +
> +static int adf7242_upload_firmware(struct adf7242_local *lp,
> +                                  u8 *data, u16 len)
> +{
> +       int status, i, page = 0;
> +       struct spi_message msg;
> +       struct spi_transfer xfer_buf = {};
> +       u8 buf[2];
> +
> +       struct spi_transfer xfer_head = {
> +               .len    = 2,
> +               .tx_buf = buf,
> +       };
> +
> +       buf[0] = CMD_SPI_PRAM_WR;
> +       buf[1] = 0;
> +
> +       for (i = len; i >= 0 ; i -= PRAM_PAGESIZE) {
> +               adf7242_write_reg(lp, REG_PRAMPG, page);
> +
> +               xfer_buf.len = i >= PRAM_PAGESIZE ? PRAM_PAGESIZE : i,
> +               xfer_buf.tx_buf = &data[page * PRAM_PAGESIZE],
> +
> +               spi_message_init(&msg);
> +               spi_message_add_tail(&xfer_head, &msg);
> +               spi_message_add_tail(&xfer_buf, &msg);
> +
> +               mutex_lock(&lp->bmux);
> +               status = spi_sync(lp->spi, &msg);
> +               mutex_unlock(&lp->bmux);
> +               page++;
> +       }
> +
> +       return status;
> +}
> +
> +static int adf7242_ed(struct ieee802154_dev *dev, u8 *level)
> +{
> +       struct adf7242_local *lp = dev->priv;
> +       int ret;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +#if 0
> +       adf7242_cmd(lp, CMD_RC_PHY_RDY);
> +       adf7242_cmd(lp, CMD_RC_CCA);
> +       adf7242_wait_status(lp, RC_STATUS_PHY_RDY);
> +#else

Dead code.

> +       udelay(128);
> +#endif
> +       ret = adf7242_read_reg(lp, REG_RRB, level);
> +       adf7242_cmd(lp, CMD_RC_RX);
> +       DBG(2, "%s :Exit\n", __func__);
> +
> +       return ret;
> +}
> +
> +static int adf7242_start(struct ieee802154_dev *dev)
> +{
> +       struct adf7242_local *lp = dev->priv;
> +       int ret;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +       ret = adf7242_cmd(lp, CMD_RC_RX);
> +       DBG(2, "%s :Exit\n", __func__);
> +
> +       return ret;
> +}
> +
> +static void adf7242_stop(struct ieee802154_dev *dev)
> +{
> +       struct adf7242_local *lp = dev->priv;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +       adf7242_cmd(lp, CMD_RC_PHY_RDY);
> +       DBG(2, "%s :Exit\n", __func__);
> +}
> +
> +static int adf7242_channel(struct ieee802154_dev *dev, int channel)
> +{
> +       struct adf7242_local *lp = dev->priv;
> +       unsigned long freq;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +       DBG(1, "%s :Channel=%d\n", __func__, channel);
> +
> +       might_sleep();
> +
> +       BUG_ON(channel < 11);
> +       BUG_ON(channel > 26);
> +
> +       freq = (2405 + 5 * (channel - 11)) * 100;
> +
> +       adf7242_cmd(lp, CMD_RC_PHY_RDY);
> +
> +       adf7242_write_reg(lp, REG_CH_FREQ0, freq);
> +       adf7242_write_reg(lp, REG_CH_FREQ1, freq >> 8);
> +       adf7242_write_reg(lp, REG_CH_FREQ2, freq >> 16);
> +
> +       adf7242_cmd(lp, CMD_RC_RX);
> +
> +       dev->phy->current_channel = channel;
> +       DBG(2, "%s :Exit\n", __func__);
> +
> +       return 0;

Could be made a void return value as we never return anything useful.

> +}
> +
> +static int adf7242_set_hw_addr_filt(struct ieee802154_dev *dev,
> +                                   struct ieee802154_hw_addr_filt *filt,
> +                                   unsigned long changed)
> +{
> +       struct adf7242_local *lp = dev->priv;
> +       u8 reg;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +       DBG(1, "%s :Changed=0x%lX\n", __func__, changed);
> +
> +       might_sleep();
> +
> +       if (changed & IEEE802515_IEEEADDR_CHANGED) {
> +               adf7242_write_reg(lp, REG_IEEE_ADDR_0, filt->ieee_addr[7]);
> +               adf7242_write_reg(lp, REG_IEEE_ADDR_1, filt->ieee_addr[6]);
> +               adf7242_write_reg(lp, REG_IEEE_ADDR_2, filt->ieee_addr[5]);
> +               adf7242_write_reg(lp, REG_IEEE_ADDR_3, filt->ieee_addr[4]);
> +               adf7242_write_reg(lp, REG_IEEE_ADDR_4, filt->ieee_addr[3]);
> +               adf7242_write_reg(lp, REG_IEEE_ADDR_5, filt->ieee_addr[2]);
> +               adf7242_write_reg(lp, REG_IEEE_ADDR_6, filt->ieee_addr[1]);
> +               adf7242_write_reg(lp, REG_IEEE_ADDR_7, filt->ieee_addr[0]);
> +       }
> +
> +       if (changed & IEEE802515_SADDR_CHANGED) {
> +               adf7242_write_reg(lp, REG_SHORT_ADDR_0, filt->short_addr);
> +               adf7242_write_reg(lp, REG_SHORT_ADDR_1, filt->short_addr >> 
> 8);
> +       }
> +
> +       if (changed & IEEE802515_PANID_CHANGED) {
> +               adf7242_write_reg(lp, REG_PAN_ID0, filt->pan_id);
> +               adf7242_write_reg(lp, REG_PAN_ID1, filt->pan_id >> 8);
> +       }
> +
> +       if (changed & IEEE802515_PANC_CHANGED) {
> +               adf7242_read_reg(lp, REG_AUTO_CFG, &reg);
> +               if (filt->pan_coord)
> +                       reg |= IS_PANCOORD;
> +               else
> +                       reg &= ~IS_PANCOORD;
> +               adf7242_write_reg(lp, REG_AUTO_CFG, reg);
> +       }
> +
> +       DBG(2, "%s :Exit\n", __func__);
> +       return 0;

Again a candidate for void.

> +}
> +
> +static int adf7242_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
> +{
> +       struct adf7242_local *lp = dev->priv;
> +       int ret;
> +       unsigned long flags;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +
> +       spin_lock_irqsave(&lp->lock, flags);
> +       BUG_ON(lp->is_tx);
> +       lp->is_tx = 1;
> +       spin_unlock_irqrestore(&lp->lock, flags);
> +
> +       ret = adf7242_write_fbuf(lp, skb->data, skb->len);
> +       if (ret)
> +               goto err_rx;
> +
> +       if (lp->mode & ADF_IEEE802154_AUTO_CSMA_CA) {
> +               ret = adf7242_cmd(lp, CMD_RC_PHY_RDY);
> +               ret |= adf7242_cmd(lp, CMD_RC_CSMACA);
> +       } else {
> +               ret = adf7242_cmd(lp, CMD_RC_TX);
> +       }
> +
> +       if (ret)
> +               goto err_rx;
> +
> +       ret = wait_for_completion_interruptible(&lp->tx_complete);
> +
> +       if (ret < 0)
> +               goto err_rx;
> +
> +       DBG(2, "%s :Exit\n", __func__);
> +       return ret;
> +
> +err_rx:
> +       spin_lock_irqsave(&lp->lock, flags);
> +       lp->is_tx = 0;
> +       spin_unlock_irqrestore(&lp->lock, flags);
> +       return ret;
> +}
> +
> +static int adf7242_rx(struct adf7242_local *lp)
> +{
> +       u8 len = 128;
> +       u8 lqi = 0;
> +       int ret;
> +       struct sk_buff *skb;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +
> +       skb = alloc_skb(len, GFP_KERNEL);
> +       if (!skb)
> +               return -ENOMEM;
> +
> +       ret = adf7242_read_fbuf(lp, skb_put(skb, len), &len, &lqi);
> +
> +       adf7242_cmd(lp, CMD_RC_RX);
> +
> +       skb_trim(skb, len - 2); /* We do not put RSSI/LQI or CRC into the 
> frame */
> +
> +       if (len < 2) {
> +               kfree_skb(skb);
> +               return -EINVAL;
> +       }
> +
> +       ieee802154_rx_irqsafe(lp->dev, skb, lqi);
> +
> +       DBG(1, "%s: %d %d %x\n", __func__, ret, len, lqi);
> +       DBG(2, "%s :Exit\n", __func__);
> +
> +       return 0;
> +}
> +
> +static struct ieee802154_ops adf7242_ops = {
> +       .owner = THIS_MODULE,
> +       .xmit = adf7242_xmit,
> +       .ed = adf7242_ed,
> +       .set_channel = adf7242_channel,
> +       .set_hw_addr_filt = adf7242_set_hw_addr_filt,
> +       .start = adf7242_start,
> +       .stop = adf7242_stop,
> +};
> +
> +static void adf7242_irqwork(struct work_struct *work)
> +{
> +       struct adf7242_local *lp =
> +               container_of(work, struct adf7242_local, irqwork);
> +       u8 irq1, auto_stat = 0, stat = 0;
> +       int ret;
> +       unsigned long flags;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +
> +       ret = adf7242_read_reg(lp, REG_IRQ1_SRC1, &irq1);
> +
> +       DBG(1, "%s IRQ1 = %X:\n%s%s%s%s%s%s%s%s\n", __func__, irq1,
> +               irq1 & IRQ_CCA_COMPLETE ? "IRQ_CCA_COMPLETE\n" : "",
> +               irq1 & IRQ_SFD_RX ? "IRQ_SFD_RX\n" : "",
> +               irq1 & IRQ_SFD_TX ? "IRQ_SFD_TX\n" : "",
> +               irq1 & IRQ_RX_PKT_RCVD ? "IRQ_RX_PKT_RCVD\n" : "",
> +               irq1 & IRQ_TX_PKT_SENT ? "IRQ_TX_PKT_SENT\n" : "",
> +               irq1 & IRQ_CSMA_CA ? "IRQ_CSMA_CA\n" : "",
> +               irq1 & IRQ_FRAME_VALID ? "IRQ_FRAME_VALID\n" : "",
> +               irq1 & IRQ_ADDRESS_VALID ? "IRQ_ADDRESS_VALID\n" : "");
> +
> +       adf7242_status(lp, &stat);
> +
> +       DBG(1, "%s STATUS = %X:\n%s\n%s%s%s%s%s\n", __func__, stat,
> +               stat & STAT_RC_READY ? "RC_READY" : "RC_BUSY",
> +               (stat & 0xf) == RC_STATUS_IDLE ? "RC_STATUS_IDLE" : "",
> +               (stat & 0xf) == RC_STATUS_MEAS ? "RC_STATUS_MEAS" : "",
> +               (stat & 0xf) == RC_STATUS_PHY_RDY ? "RC_STATUS_PHY_RDY" : "",
> +               (stat & 0xf) == RC_STATUS_RX ? "RC_STATUS_RX" : "",
> +               (stat & 0xf) == RC_STATUS_TX ? "RC_STATUS_TX" : "");
> +
> +       adf7242_write_reg(lp, REG_IRQ1_SRC1, irq1);
> +
> +       if (irq1 & IRQ_RX_PKT_RCVD) {
> +
> +               /* Wait until ACK is processed */
> +               if ((lp->mode & ADF_IEEE802154_HW_AACK) &&
> +                       ((stat & RC_STATUS_MASK) != RC_STATUS_PHY_RDY))
> +                       adf7242_wait_status(lp, RC_STATUS_PHY_RDY);
> +
> +               adf7242_rx(lp);
> +       }
> +
> +       if (irq1 & lp->tx_irq) {
> +
> +               if (lp->mode & ADF_IEEE802154_AUTO_CSMA_CA) {
> +                       adf7242_read_reg(lp, REG_AUTO_STATUS, &auto_stat);
> +                       auto_stat &= AUTO_STATUS_MASK;
> +
> +                       DBG(1, "%s AUTO_STATUS = %X:\n%s%s%s%s\n",
> +                        __func__, auto_stat,
> +                       auto_stat == SUCCESS ? "SUCCESS" : "",
> +                       auto_stat == SUCCESS_DATPEND ? "SUCCESS_DATPEND" : "",
> +                       auto_stat == FAILURE_CSMACA ? "FAILURE_CSMACA" : "",
> +                       auto_stat == FAILURE_NOACK ? "FAILURE_NOACK" : "");
> +
> +                       /* save CSMA-CA completion status */
> +                       lp->tx_stat = auto_stat;
> +               }
> +               spin_lock_irqsave(&lp->lock, flags);
> +               if (lp->is_tx) {
> +                       lp->is_tx = 0;
> +                       complete(&lp->tx_complete);
> +               }
> +               spin_unlock_irqrestore(&lp->lock, flags);
> +
> +               /* in case we just received a frame we are already in PHY_RX 
> */
> +
> +               if (!(irq1 & IRQ_RX_PKT_RCVD))
> +                       adf7242_cmd(lp, CMD_RC_RX);
> +       }
> +
> +       spin_lock_irqsave(&lp->lock, flags);
> +       if (lp->irq_disabled) {
> +               lp->irq_disabled = 0;
> +               enable_irq(lp->spi->irq);
> +       }
> +       spin_unlock_irqrestore(&lp->lock, flags);
> +
> +       DBG(2, "%s :Exit\n", __func__);
> +}
> +
> +static irqreturn_t adf7242_isr(int irq, void *data)
> +{
> +       struct adf7242_local *lp = data;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +
> +       spin_lock(&lp->lock);
> +       if (!lp->irq_disabled) {
> +               disable_irq_nosync(irq);
> +               lp->irq_disabled = 1;
> +       }
> +       spin_unlock(&lp->lock);
> +
> +       schedule_work(&lp->irqwork);
> +
> +       DBG(2, "%s :Exit\n", __func__);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +
> +static int adf7242_hw_init(struct adf7242_local *lp)
> +{
> +       int ret;
> +       const struct firmware *fw;
> +
> +       DBG(2, "%s :Enter\n", __func__);
> +
> +       adf7242_cmd(lp, CMD_RC_IDLE);
> +
> +       if (lp->mode) {
> +               /* get ADF7242 addon firmware
> +                * build this driver as module
> +                * and place under /lib/firmware/adf7242_firmware.bin
> +                */
> +               ret = request_firmware(&fw, FIRMWARE, &lp->spi->dev);
> +               if (ret) {
> +                       dev_err(&lp->spi->dev,
> +                               "request_firmware() failed with %i\n", ret);
> +                       return ret;
> +               }
> +
> +               adf7242_upload_firmware(lp, (u8 *) fw->data, fw->size);
> +               release_firmware(fw);
> +
> +               adf7242_write_reg(lp, REG_FFILT_CFG,
> +                       ACCEPT_BEACON_FRAMES |
> +                       ACCEPT_DATA_FRAMES |
> +                       ACCEPT_ACK_FRAMES |
> +                       ACCEPT_MACCMD_FRAMES |
> +                       (lp->mode & ADF_IEEE802154_PROMISCUOUS_MODE ?
> +                       ACCEPT_ALL_ADDRESS : 0) |
> +                       ACCEPT_RESERVED_FRAMES);
> +
> +               adf7242_write_reg(lp, REG_AUTO_TX1,
> +                       MAX_FRAME_RETRIES(lp->pdata->max_frame_retries) |
> +                       MAX_CCA_RETRIES(lp->pdata->max_cca_retries));
> +
> +               adf7242_write_reg(lp, REG_AUTO_TX2,
> +                       CSMA_MAX_BE(lp->pdata->max_csma_be) |
> +                       CSMA_MIN_BE(lp->pdata->min_csma_be));
> +
> +               adf7242_write_reg(lp, REG_AUTO_CFG,
> +                       (lp->mode & ADF_IEEE802154_HW_AACK ?
> +                       RX_AUTO_ACK_EN : 0));
> +       }
> +
> +       adf7242_write_reg(lp, REG_PKT_CFG, lp->mode ? ADDON_EN : 0);
> +
> +       adf7242_write_reg(lp, REG_EXTPA_MSC, 0xF1);
> +       adf7242_write_reg(lp, REG_RXFE_CFG, 0x1D);
> +       adf7242_write_reg(lp, REG_IRQ1_EN0, 0);
> +
> +       adf7242_write_reg(lp, REG_IRQ1_EN1, IRQ_RX_PKT_RCVD | lp->tx_irq);
> +
> +       adf7242_write_reg(lp, REG_IRQ1_SRC1, 0xFF);
> +       adf7242_write_reg(lp, REG_IRQ1_SRC0, 0xFF);
> +
> +       adf7242_cmd(lp, CMD_RC_PHY_RDY);
> +
> +       DBG(2, "%s :Exit\n", __func__);
> +
> +       return 0;
> +}
> +
> +static int adf7242_suspend(struct spi_device *spi, pm_message_t message)
> +{
> +       return 0;
> +}
> +
> +static int adf7242_resume(struct spi_device *spi)
> +{
> +       return 0;
> +}

If you don't implement PM you could just leave it out. At least be prepared to
compile without CONFIG_PM set.

> +static ssize_t adf7242_show(struct device *dev,
> +                           struct device_attribute *devattr,
> +                           char *buf)
> +{
> +       struct adf7242_local *lp = dev_get_drvdata(dev);
> +       u8 stat;
> +
> +       adf7242_status(lp, &stat);
> +
> +       return sprintf(buf, "STATUS = %X:\n%s\n%s%s%s%s%s\n", stat,
> +               stat & STAT_RC_READY ? "RC_READY" : "RC_BUSY",
> +               (stat & 0xf) == RC_STATUS_IDLE ? "RC_STATUS_IDLE" : "",
> +               (stat & 0xf) == RC_STATUS_MEAS ? "RC_STATUS_MEAS" : "",
> +               (stat & 0xf) == RC_STATUS_PHY_RDY ? "RC_STATUS_PHY_RDY" : "",
> +               (stat & 0xf) == RC_STATUS_RX ? "RC_STATUS_RX" : "",
> +               (stat & 0xf) == RC_STATUS_TX ? "RC_STATUS_TX" : "");
> +
> +}
> +static DEVICE_ATTR(status, 0664, adf7242_show, NULL);

This needs to be dosumented as sysfs ABI. Hard to remove later. Are you sure
that you actually need it?

> +static struct attribute *adf7242_attributes[] = {
> +       &dev_attr_status.attr,
> +       NULL
> +};
> +
> +static const struct attribute_group adf7242_attr_group = {
> +       .attrs = adf7242_attributes,
> +};
> +
> +static int __devinit adf7242_probe(struct spi_device *spi)
> +{
> +       struct adf7242_platform_data *pdata = spi->dev.platform_data;
> +       struct ieee802154_dev *dev;
> +       struct adf7242_local *lp;
> +       int ret;
> +
> +       if (!spi->irq) {
> +               dev_err(&spi->dev, "no IRQ specified\n");
> +               return -EINVAL;
> +       }
> +
> +       if (!pdata) {
> +               dev_err(&spi->dev, "no platform data?\n");
> +               return -ENODEV;
> +       }
> +
> +       dev = ieee802154_alloc_device(sizeof(*lp), &adf7242_ops);
> +       if (!dev)
> +               return -ENOMEM;
> +
> +       lp = dev->priv;
> +       lp->dev = dev;
> +       lp->spi = spi;
> +       lp->pdata = pdata;
> +       lp->mode = pdata->mode;
> +
> +       dev->priv = lp;
> +       dev->parent = &spi->dev;
> +       dev->extra_tx_headroom = 0;
> +       /* We do support only 2.4 Ghz */
> +
> +       dev->phy->channels_supported[0] = 0x7FFF800;
> +
> +       if (!lp->mode) {
> +               adf7242_ops.set_hw_addr_filt = NULL;
> +               lp->tx_irq = IRQ_TX_PKT_SENT;
> +       } else {
> +               if ((lp->mode & ADF_IEEE802154_PROMISCUOUS_MODE) &&
> +                       (lp->mode & ADF_IEEE802154_HW_AACK))
> +                       lp->mode &= ~ADF_IEEE802154_HW_AACK;
> +
> +               if (lp->mode & ADF_IEEE802154_AUTO_CSMA_CA)
> +                       lp->tx_irq = IRQ_CSMA_CA;
> +               else
> +                       lp->tx_irq = IRQ_TX_PKT_SENT;
> +       }
> +
> +       dev->flags = IEEE802154_HW_OMIT_CKSUM |
> +                       (lp->mode & ADF_IEEE802154_HW_AACK ?
> +                       IEEE802154_HW_AACK : 0);
> +
> +       mutex_init(&lp->bmux);
> +       INIT_WORK(&lp->irqwork, adf7242_irqwork);
> +       spin_lock_init(&lp->lock);
> +       init_completion(&lp->tx_complete);
> +
> +       spi_set_drvdata(spi, lp);
> +
> +       ret = adf7242_hw_init(lp);
> +       if (ret)
> +               goto err_hw_init;
> +
> +       ret = request_irq(spi->irq, adf7242_isr, IRQF_TRIGGER_HIGH,
> +                       dev_name(&spi->dev), lp);
> +       if (ret)
> +               goto err_hw_init;
> +
> +       ret = ieee802154_register_device(lp->dev);
> +       if (ret)
> +               goto err_irq;
> +
> +       dev_set_drvdata(&spi->dev, lp);
> +
> +       ret = sysfs_create_group(&spi->dev.kobj, &adf7242_attr_group);
> +       if (ret)
> +               goto out;
> +
> +       dev_info(&spi->dev, "mac802154 IRQ-%d registered\n", spi->irq);
> +
> +       return ret;
> +
> +out:
> +       ieee802154_unregister_device(lp->dev);
> +err_irq:
> +       free_irq(spi->irq, lp);
> +       flush_work(&lp->irqwork);
> +err_hw_init:
> +       spi_set_drvdata(spi, NULL);
> +       mutex_destroy(&lp->bmux);
> +       ieee802154_free_device(lp->dev);
> +       return ret;
> +}
> +
> +static int __devexit adf7242_remove(struct spi_device *spi)
> +{
> +       struct adf7242_local *lp = spi_get_drvdata(spi);
> +
> +       ieee802154_unregister_device(lp->dev);
> +       free_irq(spi->irq, lp);
> +       flush_work(&lp->irqwork);
> +       spi_set_drvdata(spi, NULL);
> +       mutex_destroy(&lp->bmux);
> +       ieee802154_free_device(lp->dev);
> +
> +       return 0;
> +}
> +
> +static struct spi_driver adf7242_driver = {
> +       .driver = {
> +               .name   = "adf7242",
> +               .owner  = THIS_MODULE,
> +       },
> +       .probe      = adf7242_probe,
> +       .remove     = __devexit_p(adf7242_remove),
> +       .suspend    = adf7242_suspend,
> +       .resume     = adf7242_resume,
> +};
> +
> +static int __init adf7242_init(void)
> +{
> +       return spi_register_driver(&adf7242_driver);
> +}
> +module_init(adf7242_init);
> +
> +static void __exit adf7242_exit(void)
> +{
> +       spi_unregister_driver(&adf7242_driver);
> +}
> +module_exit(adf7242_exit);
> +
> +MODULE_AUTHOR("Michael Hennerich <[email protected]>");
> +MODULE_DESCRIPTION("ADF7242 Transceiver Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/spi/adf7242.h b/include/linux/spi/adf7242.h
> new file mode 100644
> index 0000000..f1bd5f5
> --- /dev/null
> +++ b/include/linux/spi/adf7242.h
> @@ -0,0 +1,53 @@
> +/*
> + * Analog Devices ADF7242 Low-Power IEEE 802.15.4 Transceiver
> + *
> + * Copyright 2009-2010 Analog Devices Inc.
> + *
> + * Licensed under the GPL-2 or later.
> + */
> +
> +#ifndef __LINUX_SPI_ADF7242_H
> +#define __LINUX_SPI_ADF7242_H
> +
> +struct adf7242_platform_data {
> +
> +#define ADF_IEEE802154_HW_AACK         (1 << 1)
> +#define ADF_IEEE802154_AUTO_CSMA_CA    (1 << 2)
> +#define ADF_IEEE802154_PROMISCUOUS_MODE        (1 << 3)        /* no address 
> filtering, turns off HW_AACK */
> +
> +       int mode;
> +
> +       /*
> +        * Specifies number of attempts to
> +        * retransmit unacknowledged
> +        * frames while in automatic CSMA-CA
> +        * Tx mode.
> +        */
> +       int max_frame_retries;
> +
> +       /*
> +        * Specifies number of attempts to
> +        * repeat CSMA-CA algorithm prior to
> +        * cancellation of RC_TX command.
> +        * Valid range is 0 to 5;
> +        * 7: CSMA-CA algorithm is off
> +        */
> +       int max_cca_retries;
> +
> +       /*
> +        * Specifies the maximum back-off
> +        * exponent used in the CSMA-CA
> +        * algorithm; valid range is 4 to 8
> +        *
> +        */
> +       int max_csma_be;
> +
> +       /*
> +        * Specifies the minimum back-off
> +        * exponent used in the CSMA-CA
> +        * algorithm; valid range is 0 to
> +        * csma_max_be
> +        */
> +       int min_csma_be;
> +};
> +#endif

regards
Stefan Schmidt

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Linux-zigbee-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to