From a6ca2e10f795111a90a4efabb07717258669e03d Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 26 Jan 2013 21:38:35 +0100 Subject: ssb: add gpio_to_irq The old bcm47xx gpio code had support for gpio_to_irq, but the new code did not provide this function, but returned -ENXIO all the time. This patch adds the missing function. arch/mips/bcm47xx/wgt634u.c calls gpio_to_irq() and got the correct irq number with the old gpio handling code. With this patch the code in wgt634u.c should work again. I do not have a wgt634u to test this. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- include/linux/ssb/ssb_driver_mips.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ssb/ssb_driver_mips.h b/include/linux/ssb/ssb_driver_mips.h index 07a9c7a2e088..afe79d40a99e 100644 --- a/include/linux/ssb/ssb_driver_mips.h +++ b/include/linux/ssb/ssb_driver_mips.h @@ -45,6 +45,11 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) { } +static inline unsigned int ssb_mips_irq(struct ssb_device *dev) +{ + return 0; +} + #endif /* CONFIG_SSB_DRIVER_MIPS */ #endif /* LINUX_SSB_MIPSCORE_H_ */ -- cgit v1.2.3-71-gd317 From 8f1ca2683225afa21b827ff620a6225c390771a9 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 26 Jan 2013 21:39:44 +0100 Subject: bcma: add gpio_to_irq The old bcm47xx gpio code had support for gpio_to_irq, but the new code did not provide this function, but returned -ENXIO all the time. This patch adds the missing function. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/driver_gpio.c | 11 +++++++++++ include/linux/bcma/bcma_driver_mips.h | 9 +++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 9a6f585da2d9..0b5df538dfd9 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c @@ -73,6 +73,16 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio) bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); } +static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +{ + struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); + + if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) + return bcma_core_irq(cc->core); + else + return -EINVAL; +} + int bcma_gpio_init(struct bcma_drv_cc *cc) { struct gpio_chip *chip = &cc->gpio; @@ -85,6 +95,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) chip->set = bcma_gpio_set_value; chip->direction_input = bcma_gpio_direction_input; chip->direction_output = bcma_gpio_direction_output; + chip->to_irq = bcma_gpio_to_irq; chip->ngpio = 16; /* There is just one SoC in one device and its GPIO addresses should be * deterministic to address them more easily. The other buses could get diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h index 0d1ea297851a..fb61f3fb4ddb 100644 --- a/include/linux/bcma/bcma_driver_mips.h +++ b/include/linux/bcma/bcma_driver_mips.h @@ -42,13 +42,18 @@ struct bcma_drv_mips { #ifdef CONFIG_BCMA_DRIVER_MIPS extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); + +extern unsigned int bcma_core_irq(struct bcma_device *core); #else static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { } + +static inline unsigned int bcma_core_irq(struct bcma_device *core) +{ + return 0; +} #endif extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore); -extern unsigned int bcma_core_irq(struct bcma_device *core); - #endif /* LINUX_BCMA_DRIVER_MIPS_H_ */ -- cgit v1.2.3-71-gd317 From 97cc019ee56d52005ea4544af17bef268c464862 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Fri, 1 Feb 2013 08:46:56 +0100 Subject: bcma: cc: fix (and rename) define of NAND flash type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- include/linux/bcma/bcma_driver_chipcommon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 9a0e3fa3ca95..6a299f416288 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -27,7 +27,7 @@ #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */ #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */ #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */ -#define BCMA_CC_FLASHT_NFLASH 0x00000200 /* NAND flash */ +#define BCMA_CC_FLASHT_NAND 0x00000300 /* NAND flash */ #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */ #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */ #define BCMA_PLLTYPE_NONE 0x00000000 -- cgit v1.2.3-71-gd317 From cfad1ba87150e198be9ea32367a24e500e59de2c Mon Sep 17 00:00:00 2001 From: Eric Lapuyade Date: Tue, 18 Dec 2012 14:53:53 +0100 Subject: NFC: Initial support for Inside Secure microread Inside Secure microread is an HCI based NFC chipset. This initial support includes reader and p2p (Target and initiator) modes. Signed-off-by: Eric Lapuyade Signed-off-by: Samuel Ortiz --- drivers/nfc/Kconfig | 1 + drivers/nfc/Makefile | 1 + drivers/nfc/microread/Kconfig | 13 + drivers/nfc/microread/Makefile | 5 + drivers/nfc/microread/microread.c | 728 ++++++++++++++++++++++++++++++++ drivers/nfc/microread/microread.h | 33 ++ include/linux/platform_data/microread.h | 35 ++ 7 files changed, 816 insertions(+) create mode 100644 drivers/nfc/microread/Kconfig create mode 100644 drivers/nfc/microread/Makefile create mode 100644 drivers/nfc/microread/microread.c create mode 100644 drivers/nfc/microread/microread.h create mode 100644 include/linux/platform_data/microread.h (limited to 'include/linux') diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index 80c728b28828..e57034971ccc 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig @@ -27,5 +27,6 @@ config NFC_WILINK into the kernel or say M to compile it as module. source "drivers/nfc/pn544/Kconfig" +source "drivers/nfc/microread/Kconfig" endmenu diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile index 574bbc04d97a..a189ada0926a 100644 --- a/drivers/nfc/Makefile +++ b/drivers/nfc/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_NFC_PN544) += pn544/ +obj-$(CONFIG_NFC_MICROREAD) += microread/ obj-$(CONFIG_NFC_PN533) += pn533.o obj-$(CONFIG_NFC_WILINK) += nfcwilink.o diff --git a/drivers/nfc/microread/Kconfig b/drivers/nfc/microread/Kconfig new file mode 100644 index 000000000000..5b89d011d098 --- /dev/null +++ b/drivers/nfc/microread/Kconfig @@ -0,0 +1,13 @@ +config NFC_MICROREAD + tristate "Inside Secure microread NFC driver" + depends on NFC_HCI + select CRC_CCITT + default n + ---help--- + This module contains the main code for Inside Secure microread + NFC chipsets. It implements the chipset HCI logic and hooks into + the NFC kernel APIs. Physical layers will register against it. + + To compile this driver as a module, choose m here. The module will + be called microread. + Say N if unsure. diff --git a/drivers/nfc/microread/Makefile b/drivers/nfc/microread/Makefile new file mode 100644 index 000000000000..9ce2c53f49a7 --- /dev/null +++ b/drivers/nfc/microread/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Microread HCI based NFC driver +# + +obj-$(CONFIG_NFC_MICROREAD) += microread.o diff --git a/drivers/nfc/microread/microread.c b/drivers/nfc/microread/microread.c new file mode 100644 index 000000000000..3420d833db17 --- /dev/null +++ b/drivers/nfc/microread/microread.c @@ -0,0 +1,728 @@ +/* + * HCI based Driver for Inside Secure microread NFC Chip + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "microread.h" + +/* Proprietary gates, events, commands and registers */ +/* Admin */ +#define MICROREAD_GATE_ID_ADM NFC_HCI_ADMIN_GATE +#define MICROREAD_GATE_ID_MGT 0x01 +#define MICROREAD_GATE_ID_OS 0x02 +#define MICROREAD_GATE_ID_TESTRF 0x03 +#define MICROREAD_GATE_ID_LOOPBACK NFC_HCI_LOOPBACK_GATE +#define MICROREAD_GATE_ID_IDT NFC_HCI_ID_MGMT_GATE +#define MICROREAD_GATE_ID_LMS NFC_HCI_LINK_MGMT_GATE + +/* Reader */ +#define MICROREAD_GATE_ID_MREAD_GEN 0x10 +#define MICROREAD_GATE_ID_MREAD_ISO_B NFC_HCI_RF_READER_B_GATE +#define MICROREAD_GATE_ID_MREAD_NFC_T1 0x12 +#define MICROREAD_GATE_ID_MREAD_ISO_A NFC_HCI_RF_READER_A_GATE +#define MICROREAD_GATE_ID_MREAD_NFC_T3 0x14 +#define MICROREAD_GATE_ID_MREAD_ISO_15_3 0x15 +#define MICROREAD_GATE_ID_MREAD_ISO_15_2 0x16 +#define MICROREAD_GATE_ID_MREAD_ISO_B_3 0x17 +#define MICROREAD_GATE_ID_MREAD_BPRIME 0x18 +#define MICROREAD_GATE_ID_MREAD_ISO_A_3 0x19 + +/* Card */ +#define MICROREAD_GATE_ID_MCARD_GEN 0x20 +#define MICROREAD_GATE_ID_MCARD_ISO_B 0x21 +#define MICROREAD_GATE_ID_MCARD_BPRIME 0x22 +#define MICROREAD_GATE_ID_MCARD_ISO_A 0x23 +#define MICROREAD_GATE_ID_MCARD_NFC_T3 0x24 +#define MICROREAD_GATE_ID_MCARD_ISO_15_3 0x25 +#define MICROREAD_GATE_ID_MCARD_ISO_15_2 0x26 +#define MICROREAD_GATE_ID_MCARD_ISO_B_2 0x27 +#define MICROREAD_GATE_ID_MCARD_ISO_CUSTOM 0x28 +#define MICROREAD_GATE_ID_SECURE_ELEMENT 0x2F + +/* P2P */ +#define MICROREAD_GATE_ID_P2P_GEN 0x30 +#define MICROREAD_GATE_ID_P2P_TARGET 0x31 +#define MICROREAD_PAR_P2P_TARGET_MODE 0x01 +#define MICROREAD_PAR_P2P_TARGET_GT 0x04 +#define MICROREAD_GATE_ID_P2P_INITIATOR 0x32 +#define MICROREAD_PAR_P2P_INITIATOR_GI 0x01 +#define MICROREAD_PAR_P2P_INITIATOR_GT 0x03 + +/* Those pipes are created/opened by default in the chip */ +#define MICROREAD_PIPE_ID_LMS 0x00 +#define MICROREAD_PIPE_ID_ADMIN 0x01 +#define MICROREAD_PIPE_ID_MGT 0x02 +#define MICROREAD_PIPE_ID_OS 0x03 +#define MICROREAD_PIPE_ID_HDS_LOOPBACK 0x04 +#define MICROREAD_PIPE_ID_HDS_IDT 0x05 +#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_B 0x08 +#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_BPRIME 0x09 +#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_A 0x0A +#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_15_3 0x0B +#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_15_2 0x0C +#define MICROREAD_PIPE_ID_HDS_MCARD_NFC_T3 0x0D +#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_B_2 0x0E +#define MICROREAD_PIPE_ID_HDS_MCARD_CUSTOM 0x0F +#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_B 0x10 +#define MICROREAD_PIPE_ID_HDS_MREAD_NFC_T1 0x11 +#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_A 0x12 +#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_15_3 0x13 +#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_15_2 0x14 +#define MICROREAD_PIPE_ID_HDS_MREAD_NFC_T3 0x15 +#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_B_3 0x16 +#define MICROREAD_PIPE_ID_HDS_MREAD_BPRIME 0x17 +#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_A_3 0x18 +#define MICROREAD_PIPE_ID_HDS_MREAD_GEN 0x1B +#define MICROREAD_PIPE_ID_HDS_STACKED_ELEMENT 0x1C +#define MICROREAD_PIPE_ID_HDS_INSTANCES 0x1D +#define MICROREAD_PIPE_ID_HDS_TESTRF 0x1E +#define MICROREAD_PIPE_ID_HDS_P2P_TARGET 0x1F +#define MICROREAD_PIPE_ID_HDS_P2P_INITIATOR 0x20 + +/* Events */ +#define MICROREAD_EVT_MREAD_DISCOVERY_OCCURED NFC_HCI_EVT_TARGET_DISCOVERED +#define MICROREAD_EVT_MREAD_CARD_FOUND 0x3D +#define MICROREAD_EMCF_A_ATQA 0 +#define MICROREAD_EMCF_A_SAK 2 +#define MICROREAD_EMCF_A_LEN 3 +#define MICROREAD_EMCF_A_UID 4 +#define MICROREAD_EMCF_A3_ATQA 0 +#define MICROREAD_EMCF_A3_SAK 2 +#define MICROREAD_EMCF_A3_LEN 3 +#define MICROREAD_EMCF_A3_UID 4 +#define MICROREAD_EMCF_B_UID 0 +#define MICROREAD_EMCF_T1_ATQA 0 +#define MICROREAD_EMCF_T1_UID 4 +#define MICROREAD_EMCF_T3_UID 0 +#define MICROREAD_EVT_MREAD_DISCOVERY_START NFC_HCI_EVT_READER_REQUESTED +#define MICROREAD_EVT_MREAD_DISCOVERY_START_SOME 0x3E +#define MICROREAD_EVT_MREAD_DISCOVERY_STOP NFC_HCI_EVT_END_OPERATION +#define MICROREAD_EVT_MREAD_SIM_REQUESTS 0x3F +#define MICROREAD_EVT_MCARD_EXCHANGE NFC_HCI_EVT_TARGET_DISCOVERED +#define MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF 0x20 +#define MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_FROM_RF 0x21 +#define MICROREAD_EVT_MCARD_FIELD_ON 0x11 +#define MICROREAD_EVT_P2P_TARGET_ACTIVATED 0x13 +#define MICROREAD_EVT_P2P_TARGET_DEACTIVATED 0x12 +#define MICROREAD_EVT_MCARD_FIELD_OFF 0x14 + +/* Commands */ +#define MICROREAD_CMD_MREAD_EXCHANGE 0x10 +#define MICROREAD_CMD_MREAD_SUBSCRIBE 0x3F + +/* Hosts IDs */ +#define MICROREAD_ELT_ID_HDS NFC_HCI_TERMINAL_HOST_ID +#define MICROREAD_ELT_ID_SIM NFC_HCI_UICC_HOST_ID +#define MICROREAD_ELT_ID_SE1 0x03 +#define MICROREAD_ELT_ID_SE2 0x04 +#define MICROREAD_ELT_ID_SE3 0x05 + +static struct nfc_hci_gate microread_gates[] = { + {MICROREAD_GATE_ID_ADM, MICROREAD_PIPE_ID_ADMIN}, + {MICROREAD_GATE_ID_LOOPBACK, MICROREAD_PIPE_ID_HDS_LOOPBACK}, + {MICROREAD_GATE_ID_IDT, MICROREAD_PIPE_ID_HDS_IDT}, + {MICROREAD_GATE_ID_LMS, MICROREAD_PIPE_ID_LMS}, + {MICROREAD_GATE_ID_MREAD_ISO_B, MICROREAD_PIPE_ID_HDS_MREAD_ISO_B}, + {MICROREAD_GATE_ID_MREAD_ISO_A, MICROREAD_PIPE_ID_HDS_MREAD_ISO_A}, + {MICROREAD_GATE_ID_MREAD_ISO_A_3, MICROREAD_PIPE_ID_HDS_MREAD_ISO_A_3}, + {MICROREAD_GATE_ID_MGT, MICROREAD_PIPE_ID_MGT}, + {MICROREAD_GATE_ID_OS, MICROREAD_PIPE_ID_OS}, + {MICROREAD_GATE_ID_MREAD_NFC_T1, MICROREAD_PIPE_ID_HDS_MREAD_NFC_T1}, + {MICROREAD_GATE_ID_MREAD_NFC_T3, MICROREAD_PIPE_ID_HDS_MREAD_NFC_T3}, + {MICROREAD_GATE_ID_P2P_TARGET, MICROREAD_PIPE_ID_HDS_P2P_TARGET}, + {MICROREAD_GATE_ID_P2P_INITIATOR, MICROREAD_PIPE_ID_HDS_P2P_INITIATOR} +}; + +/* Largest headroom needed for outgoing custom commands */ +#define MICROREAD_CMDS_HEADROOM 2 +#define MICROREAD_CMD_TAILROOM 2 + +struct microread_info { + struct nfc_phy_ops *phy_ops; + void *phy_id; + + struct nfc_hci_dev *hdev; + + int async_cb_type; + data_exchange_cb_t async_cb; + void *async_cb_context; +}; + +static int microread_open(struct nfc_hci_dev *hdev) +{ + struct microread_info *info = nfc_hci_get_clientdata(hdev); + + return info->phy_ops->enable(info->phy_id); +} + +static void microread_close(struct nfc_hci_dev *hdev) +{ + struct microread_info *info = nfc_hci_get_clientdata(hdev); + + info->phy_ops->disable(info->phy_id); +} + +static int microread_hci_ready(struct nfc_hci_dev *hdev) +{ + int r; + u8 param[4]; + + param[0] = 0x03; + r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_A, + MICROREAD_CMD_MREAD_SUBSCRIBE, param, 1, NULL); + if (r) + return r; + + r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_A_3, + MICROREAD_CMD_MREAD_SUBSCRIBE, NULL, 0, NULL); + if (r) + return r; + + param[0] = 0x00; + param[1] = 0x03; + param[2] = 0x00; + r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_B, + MICROREAD_CMD_MREAD_SUBSCRIBE, param, 3, NULL); + if (r) + return r; + + r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_NFC_T1, + MICROREAD_CMD_MREAD_SUBSCRIBE, NULL, 0, NULL); + if (r) + return r; + + param[0] = 0xFF; + param[1] = 0xFF; + param[2] = 0x00; + param[3] = 0x00; + r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_NFC_T3, + MICROREAD_CMD_MREAD_SUBSCRIBE, param, 4, NULL); + + return r; +} + +static int microread_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) +{ + struct microread_info *info = nfc_hci_get_clientdata(hdev); + + return info->phy_ops->write(info->phy_id, skb); +} + +static int microread_start_poll(struct nfc_hci_dev *hdev, + u32 im_protocols, u32 tm_protocols) +{ + int r; + + u8 param[2]; + u8 mode; + + param[0] = 0x00; + param[1] = 0x00; + + if (im_protocols & NFC_PROTO_ISO14443_MASK) + param[0] |= (1 << 2); + + if (im_protocols & NFC_PROTO_ISO14443_B_MASK) + param[0] |= 1; + + if (im_protocols & NFC_PROTO_MIFARE_MASK) + param[1] |= 1; + + if (im_protocols & NFC_PROTO_JEWEL_MASK) + param[0] |= (1 << 1); + + if (im_protocols & NFC_PROTO_FELICA_MASK) + param[0] |= (1 << 5); + + if (im_protocols & NFC_PROTO_NFC_DEP_MASK) + param[1] |= (1 << 1); + + if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) { + hdev->gb = nfc_get_local_general_bytes(hdev->ndev, + &hdev->gb_len); + if (hdev->gb == NULL || hdev->gb_len == 0) { + im_protocols &= ~NFC_PROTO_NFC_DEP_MASK; + tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK; + } + } + + r = nfc_hci_send_event(hdev, MICROREAD_GATE_ID_MREAD_ISO_A, + MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, 0); + if (r) + return r; + + mode = 0xff; + r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET, + MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1); + if (r) + return r; + + if (im_protocols & NFC_PROTO_NFC_DEP_MASK) { + r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_INITIATOR, + MICROREAD_PAR_P2P_INITIATOR_GI, + hdev->gb, hdev->gb_len); + if (r) + return r; + } + + if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { + r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET, + MICROREAD_PAR_P2P_TARGET_GT, + hdev->gb, hdev->gb_len); + if (r) + return r; + + mode = 0x02; + r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET, + MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1); + if (r) + return r; + } + + return nfc_hci_send_event(hdev, MICROREAD_GATE_ID_MREAD_ISO_A, + MICROREAD_EVT_MREAD_DISCOVERY_START_SOME, + param, 2); +} + +static int microread_dep_link_up(struct nfc_hci_dev *hdev, + struct nfc_target *target, u8 comm_mode, + u8 *gb, size_t gb_len) +{ + struct sk_buff *rgb_skb = NULL; + int r; + + r = nfc_hci_get_param(hdev, target->hci_reader_gate, + MICROREAD_PAR_P2P_INITIATOR_GT, &rgb_skb); + if (r < 0) + return r; + + if (rgb_skb->len == 0 || rgb_skb->len > NFC_GB_MAXSIZE) { + r = -EPROTO; + goto exit; + } + + r = nfc_set_remote_general_bytes(hdev->ndev, rgb_skb->data, + rgb_skb->len); + if (r == 0) + r = nfc_dep_link_is_up(hdev->ndev, target->idx, comm_mode, + NFC_RF_INITIATOR); +exit: + kfree_skb(rgb_skb); + + return r; +} + +static int microread_dep_link_down(struct nfc_hci_dev *hdev) +{ + return nfc_hci_send_event(hdev, MICROREAD_GATE_ID_P2P_INITIATOR, + MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, 0); +} + +static int microread_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, + struct nfc_target *target) +{ + switch (gate) { + case MICROREAD_GATE_ID_P2P_INITIATOR: + target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; + break; + default: + return -EPROTO; + } + + return 0; +} + +static int microread_complete_target_discovered(struct nfc_hci_dev *hdev, + u8 gate, + struct nfc_target *target) +{ + return 0; +} + +#define MICROREAD_CB_TYPE_READER_ALL 1 + +static void microread_im_transceive_cb(void *context, struct sk_buff *skb, + int err) +{ + struct microread_info *info = context; + + switch (info->async_cb_type) { + case MICROREAD_CB_TYPE_READER_ALL: + if (err == 0) { + if (skb->len == 0) { + err = -EPROTO; + kfree_skb(skb); + info->async_cb(info->async_cb_context, NULL, + -EPROTO); + return; + } + + if (skb->data[skb->len - 1] != 0) { + err = nfc_hci_result_to_errno( + skb->data[skb->len - 1]); + kfree_skb(skb); + info->async_cb(info->async_cb_context, NULL, + err); + return; + } + + skb_trim(skb, skb->len - 1); /* RF Error ind. */ + } + info->async_cb(info->async_cb_context, skb, err); + break; + default: + if (err == 0) + kfree_skb(skb); + break; + } +} + +/* + * Returns: + * <= 0: driver handled the data exchange + * 1: driver doesn't especially handle, please do standard processing + */ +static int microread_im_transceive(struct nfc_hci_dev *hdev, + struct nfc_target *target, + struct sk_buff *skb, data_exchange_cb_t cb, + void *cb_context) +{ + struct microread_info *info = nfc_hci_get_clientdata(hdev); + u8 control_bits; + u16 crc; + + pr_info("data exchange to gate 0x%x\n", target->hci_reader_gate); + + if (target->hci_reader_gate == MICROREAD_GATE_ID_P2P_INITIATOR) { + *skb_push(skb, 1) = 0; + + return nfc_hci_send_event(hdev, target->hci_reader_gate, + MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF, + skb->data, skb->len); + } + + switch (target->hci_reader_gate) { + case MICROREAD_GATE_ID_MREAD_ISO_A: + control_bits = 0xCB; + break; + case MICROREAD_GATE_ID_MREAD_ISO_A_3: + control_bits = 0xCB; + break; + case MICROREAD_GATE_ID_MREAD_ISO_B: + control_bits = 0xCB; + break; + case MICROREAD_GATE_ID_MREAD_NFC_T1: + control_bits = 0x1B; + + crc = crc_ccitt(0xffff, skb->data, skb->len); + crc = ~crc; + *skb_put(skb, 1) = crc & 0xff; + *skb_put(skb, 1) = crc >> 8; + break; + case MICROREAD_GATE_ID_MREAD_NFC_T3: + control_bits = 0xDB; + break; + default: + pr_info("Abort im_transceive to invalid gate 0x%x\n", + target->hci_reader_gate); + return 1; + } + + *skb_push(skb, 1) = control_bits; + + info->async_cb_type = MICROREAD_CB_TYPE_READER_ALL; + info->async_cb = cb; + info->async_cb_context = cb_context; + + return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, + MICROREAD_CMD_MREAD_EXCHANGE, + skb->data, skb->len, + microread_im_transceive_cb, info); +} + +static int microread_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb) +{ + int r; + + r = nfc_hci_send_event(hdev, MICROREAD_GATE_ID_P2P_TARGET, + MICROREAD_EVT_MCARD_EXCHANGE, + skb->data, skb->len); + + kfree_skb(skb); + + return r; +} + +static void microread_target_discovered(struct nfc_hci_dev *hdev, u8 gate, + struct sk_buff *skb) +{ + struct nfc_target *targets; + int r = 0; + + pr_info("target discovered to gate 0x%x\n", gate); + + targets = kzalloc(sizeof(struct nfc_target), GFP_KERNEL); + if (targets == NULL) { + r = -ENOMEM; + goto exit; + } + + targets->hci_reader_gate = gate; + + switch (gate) { + case MICROREAD_GATE_ID_MREAD_ISO_A: + targets->supported_protocols = + nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A_SAK]); + targets->sens_res = + be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A_ATQA]); + targets->sel_res = skb->data[MICROREAD_EMCF_A_SAK]; + memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A_UID], + skb->data[MICROREAD_EMCF_A_LEN]); + targets->nfcid1_len = skb->data[MICROREAD_EMCF_A_LEN]; + break; + case MICROREAD_GATE_ID_MREAD_ISO_A_3: + targets->supported_protocols = + nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A3_SAK]); + targets->sens_res = + be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A3_ATQA]); + targets->sel_res = skb->data[MICROREAD_EMCF_A3_SAK]; + memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A3_UID], + skb->data[MICROREAD_EMCF_A3_LEN]); + targets->nfcid1_len = skb->data[MICROREAD_EMCF_A3_LEN]; + break; + case MICROREAD_GATE_ID_MREAD_ISO_B: + targets->supported_protocols = NFC_PROTO_ISO14443_B_MASK; + memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_B_UID], 4); + targets->nfcid1_len = 4; + break; + case MICROREAD_GATE_ID_MREAD_NFC_T1: + targets->supported_protocols = NFC_PROTO_JEWEL_MASK; + targets->sens_res = + le16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_T1_ATQA]); + memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T1_UID], 4); + targets->nfcid1_len = 4; + break; + case MICROREAD_GATE_ID_MREAD_NFC_T3: + targets->supported_protocols = NFC_PROTO_FELICA_MASK; + memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T3_UID], 8); + targets->nfcid1_len = 8; + break; + default: + pr_info("discard target discovered to gate 0x%x\n", gate); + goto exit_free; + } + + r = nfc_targets_found(hdev->ndev, targets, 1); + +exit_free: + kfree(targets); + +exit: + kfree_skb(skb); + + if (r) + pr_err("Failed to handle discovered target err=%d", r); +} + +static int microread_event_received(struct nfc_hci_dev *hdev, u8 gate, + u8 event, struct sk_buff *skb) +{ + int r; + u8 mode; + + pr_info("Microread received event 0x%x to gate 0x%x\n", event, gate); + + switch (event) { + case MICROREAD_EVT_MREAD_CARD_FOUND: + microread_target_discovered(hdev, gate, skb); + return 0; + + case MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_FROM_RF: + if (skb->len < 1) { + kfree_skb(skb); + return -EPROTO; + } + + if (skb->data[skb->len - 1]) { + kfree_skb(skb); + return -EIO; + } + + skb_trim(skb, skb->len - 1); + + r = nfc_tm_data_received(hdev->ndev, skb); + break; + + case MICROREAD_EVT_MCARD_FIELD_ON: + case MICROREAD_EVT_MCARD_FIELD_OFF: + kfree_skb(skb); + return 0; + + case MICROREAD_EVT_P2P_TARGET_ACTIVATED: + r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK, + NFC_COMM_PASSIVE, skb->data, + skb->len); + + kfree_skb(skb); + break; + + case MICROREAD_EVT_MCARD_EXCHANGE: + if (skb->len < 1) { + kfree_skb(skb); + return -EPROTO; + } + + if (skb->data[skb->len-1]) { + kfree_skb(skb); + return -EIO; + } + + skb_trim(skb, skb->len - 1); + + r = nfc_tm_data_received(hdev->ndev, skb); + break; + + case MICROREAD_EVT_P2P_TARGET_DEACTIVATED: + kfree_skb(skb); + + mode = 0xff; + r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET, + MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1); + if (r) + break; + + r = nfc_hci_send_event(hdev, gate, + MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, + 0); + break; + + default: + return 1; + } + + return r; +} + +static struct nfc_hci_ops microread_hci_ops = { + .open = microread_open, + .close = microread_close, + .hci_ready = microread_hci_ready, + .xmit = microread_xmit, + .start_poll = microread_start_poll, + .dep_link_up = microread_dep_link_up, + .dep_link_down = microread_dep_link_down, + .target_from_gate = microread_target_from_gate, + .complete_target_discovered = microread_complete_target_discovered, + .im_transceive = microread_im_transceive, + .tm_send = microread_tm_send, + .check_presence = NULL, + .event_received = microread_event_received, +}; + +int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, + int phy_headroom, int phy_tailroom, int phy_payload, + struct nfc_hci_dev **hdev) +{ + struct microread_info *info; + unsigned long quirks = 0; + u32 protocols, se; + struct nfc_hci_init_data init_data; + int r; + + info = kzalloc(sizeof(struct microread_info), GFP_KERNEL); + if (!info) { + pr_err("Cannot allocate memory for microread_info.\n"); + r = -ENOMEM; + goto err_info_alloc; + } + + info->phy_ops = phy_ops; + info->phy_id = phy_id; + + init_data.gate_count = ARRAY_SIZE(microread_gates); + memcpy(init_data.gates, microread_gates, sizeof(microread_gates)); + + strcpy(init_data.session_id, "MICROREA"); + + set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks); + + protocols = NFC_PROTO_JEWEL_MASK | + NFC_PROTO_MIFARE_MASK | + NFC_PROTO_FELICA_MASK | + NFC_PROTO_ISO14443_MASK | + NFC_PROTO_ISO14443_B_MASK | + NFC_PROTO_NFC_DEP_MASK; + + se = NFC_SE_UICC | NFC_SE_EMBEDDED; + + info->hdev = nfc_hci_allocate_device(µread_hci_ops, &init_data, + quirks, protocols, se, llc_name, + phy_headroom + + MICROREAD_CMDS_HEADROOM, + phy_tailroom + + MICROREAD_CMD_TAILROOM, + phy_payload); + if (!info->hdev) { + pr_err("Cannot allocate nfc hdev.\n"); + r = -ENOMEM; + goto err_alloc_hdev; + } + + nfc_hci_set_clientdata(info->hdev, info); + + r = nfc_hci_register_device(info->hdev); + if (r) + goto err_regdev; + + *hdev = info->hdev; + + return 0; + +err_regdev: + nfc_hci_free_device(info->hdev); + +err_alloc_hdev: + kfree(info); + +err_info_alloc: + return r; +} +EXPORT_SYMBOL(microread_probe); + +void microread_remove(struct nfc_hci_dev *hdev) +{ + struct microread_info *info = nfc_hci_get_clientdata(hdev); + + nfc_hci_unregister_device(hdev); + nfc_hci_free_device(hdev); + kfree(info); +} +EXPORT_SYMBOL(microread_remove); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/nfc/microread/microread.h b/drivers/nfc/microread/microread.h new file mode 100644 index 000000000000..64b447a1c5bf --- /dev/null +++ b/drivers/nfc/microread/microread.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2011 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __LOCAL_MICROREAD_H_ +#define __LOCAL_MICROREAD_H_ + +#include + +#define DRIVER_DESC "NFC driver for microread" + +int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, + int phy_headroom, int phy_tailroom, int phy_payload, + struct nfc_hci_dev **hdev); + +void microread_remove(struct nfc_hci_dev *hdev); + +#endif /* __LOCAL_MICROREAD_H_ */ diff --git a/include/linux/platform_data/microread.h b/include/linux/platform_data/microread.h new file mode 100644 index 000000000000..cfda59b226ee --- /dev/null +++ b/include/linux/platform_data/microread.h @@ -0,0 +1,35 @@ +/* + * Driver include for the PN544 NFC chip. + * + * Copyright (C) 2011 Tieto Poland + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _MICROREAD_H +#define _MICROREAD_H + +#include + +#define MICROREAD_DRIVER_NAME "microread" + +/* board config platform data for microread */ +struct microread_nfc_platform_data { + unsigned int rst_gpio; + unsigned int irq_gpio; + unsigned int ioh_gpio; +}; + +#endif /* _MICROREAD_H */ -- cgit v1.2.3-71-gd317 From afb43e6d88e587441c960a5d214d2c698d076c9c Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 25 Jan 2013 11:57:48 +0200 Subject: wlcore: remove if_ops from platform_data We can't pass pointers from the platform data to the modules, because with DT it cannot be done. Those pointers are not set by the board files anyway. It's the bus modules that set them, so they can be safely removed from the platform data without changing any board files. Create a new structure that the bus modules pass to wlcore. This structure contains the if_ops pointers and a pointer to the actual platform data. Signed-off-by: Luciano Coelho Reviewed-by: Felipe Balbi --- drivers/net/wireless/ti/wl12xx/main.c | 3 ++- drivers/net/wireless/ti/wlcore/main.c | 5 +++-- drivers/net/wireless/ti/wlcore/sdio.c | 22 +++++++++++++++++----- drivers/net/wireless/ti/wlcore/spi.c | 20 +++++++++++++++++--- drivers/net/wireless/ti/wlcore/wlcore_i.h | 5 +++++ include/linux/wl12xx.h | 2 -- 6 files changed, 44 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 3254bfc81a2a..09694e39bb14 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1703,7 +1703,8 @@ static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { static int wl12xx_setup(struct wl1271 *wl) { struct wl12xx_priv *priv = wl->priv; - struct wl12xx_platform_data *pdata = wl->pdev->dev.platform_data; + struct wlcore_platdev_data *pdev_data = wl->pdev->dev.platform_data; + struct wl12xx_platform_data *pdata = pdev_data->pdata; wl->rtable = wl12xx_rtable; wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS; diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 9a66acf1205f..cd70335cd5e8 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -5966,7 +5966,8 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context) { struct wl1271 *wl = context; struct platform_device *pdev = wl->pdev; - struct wl12xx_platform_data *pdata = pdev->dev.platform_data; + struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data; + struct wl12xx_platform_data *pdata = pdev_data->pdata; unsigned long irqflags; int ret; @@ -5995,7 +5996,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context) wl->irq = platform_get_irq(pdev, 0); wl->platform_quirks = pdata->platform_quirks; - wl->if_ops = pdata->ops; + wl->if_ops = pdev_data->if_ops; if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) irqflags = IRQF_TRIGGER_RISING; diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index d4f184e2efed..1f6f6e30daca 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -218,6 +218,7 @@ static int wl1271_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct wl12xx_platform_data *wlan_data; + struct wlcore_platdev_data *pdev_data; struct wl12xx_sdio_glue *glue; struct resource res[1]; mmc_pm_flag_t mmcflags; @@ -228,10 +229,18 @@ static int wl1271_probe(struct sdio_func *func, if (func->num != 0x02) return -ENODEV; + pdev_data = kzalloc(sizeof(*pdev_data), GFP_KERNEL); + if (!pdev_data) { + dev_err(&func->dev, "can't allocate platdev_data\n"); + goto out; + } + + pdev_data->if_ops = &sdio_ops; + glue = kzalloc(sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(&func->dev, "can't allocate glue\n"); - goto out; + goto out_free_pdev_data; } glue->dev = &func->dev; @@ -256,8 +265,6 @@ static int wl1271_probe(struct sdio_func *func, if (mmcflags & MMC_PM_KEEP_POWER) wlan_data->pwr_in_suspend = true; - wlan_data->ops = &sdio_ops; - sdio_set_drvdata(func, glue); /* Tell PM core that we don't need the card to be powered now */ @@ -295,8 +302,10 @@ static int wl1271_probe(struct sdio_func *func, goto out_dev_put; } - ret = platform_device_add_data(glue->core, wlan_data, - sizeof(*wlan_data)); + pdev_data->pdata = wlan_data; + + ret = platform_device_add_data(glue->core, pdev_data, + sizeof(*pdev_data)); if (ret) { dev_err(glue->dev, "can't add platform data\n"); goto out_dev_put; @@ -315,6 +324,9 @@ out_dev_put: out_free_glue: kfree(glue); +out_free_pdev_data: + kfree(pdev_data); + out: return ret; } diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c index 2d700b7ae14c..d437f4d28bd0 100644 --- a/drivers/net/wireless/ti/wlcore/spi.c +++ b/drivers/net/wireless/ti/wlcore/spi.c @@ -328,6 +328,7 @@ static int wl1271_probe(struct spi_device *spi) { struct wl12xx_spi_glue *glue; struct wl12xx_platform_data *pdata; + struct wlcore_platdev_data *pdev_data; struct resource res[1]; int ret = -ENOMEM; @@ -337,12 +338,18 @@ static int wl1271_probe(struct spi_device *spi) return -ENODEV; } - pdata->ops = &spi_ops; + pdev_data = kzalloc(sizeof(*pdev_data), GFP_KERNEL); + if (!pdev_data) { + dev_err(&spi->dev, "can't allocate platdev_data\n"); + goto out; + } + + pdev_data->if_ops = &spi_ops; glue = kzalloc(sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(&spi->dev, "can't allocate glue\n"); - goto out; + goto out_free_pdev_data; } glue->dev = &spi->dev; @@ -380,7 +387,10 @@ static int wl1271_probe(struct spi_device *spi) goto out_dev_put; } - ret = platform_device_add_data(glue->core, pdata, sizeof(*pdata)); + pdev_data->pdata = pdata; + + ret = platform_device_add_data(glue->core, pdev_data, + sizeof(*pdev_data)); if (ret) { dev_err(glue->dev, "can't add platform data\n"); goto out_dev_put; @@ -399,6 +409,10 @@ out_dev_put: out_free_glue: kfree(glue); + +out_free_pdev_data: + kfree(pdev_data); + out: return ret; } diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 20316ac328a2..c845b0ef7f4b 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -206,6 +206,11 @@ struct wl1271_if_operations { void (*set_block_size) (struct device *child, unsigned int blksz); }; +struct wlcore_platdev_data { + struct wl12xx_platform_data *pdata; + struct wl1271_if_operations *if_ops; +}; + #define MAX_NUM_KEYS 14 #define MAX_KEY_SIZE 32 diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index 0d6373195d32..360c9bce665c 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -55,8 +55,6 @@ struct wl12xx_platform_data { int board_tcxo_clock; unsigned long platform_quirks; bool pwr_in_suspend; - - struct wl1271_if_operations *ops; }; /* Platform does not support level trigger interrupts */ -- cgit v1.2.3-71-gd317 From 6cc9efed707c575a9e5880ea68f8b9d36b235f1f Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 25 Jan 2013 12:05:34 +0200 Subject: wlcore: move wl12xx_platform_data up and make it truly optional The platform data is used not only by wlcore-based drivers, but also by wl1251. Move it up in the directory hierarchy to reflect this. Additionally, make it truly optional. At the moment, disabling platform data while wl1251_sdio or wlcore_sdio are enabled doesn't work, but it will be necessary when device tree support is implemented. Signed-off-by: Luciano Coelho Reviewed-by: Felipe Balbi --- arch/arm/mach-omap2/board-omap3evm.c | 10 ++--- drivers/net/wireless/ti/Kconfig | 9 ++++ drivers/net/wireless/ti/Makefile | 4 +- drivers/net/wireless/ti/wilink_platform_data.c | 49 ++++++++++++++++++++++ drivers/net/wireless/ti/wlcore/Kconfig | 5 --- drivers/net/wireless/ti/wlcore/Makefile | 3 -- .../net/wireless/ti/wlcore/wl12xx_platform_data.c | 49 ---------------------- include/linux/wl12xx.h | 14 +++++-- 8 files changed, 77 insertions(+), 66 deletions(-) create mode 100644 drivers/net/wireless/ti/wilink_platform_data.c delete mode 100644 drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c (limited to 'include/linux') diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 3985f35aee06..a4ca63ba7faa 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -309,7 +309,7 @@ static struct omap2_hsmmc_info mmc[] = { .gpio_wp = 63, .deferred = true, }, -#ifdef CONFIG_WL12XX_PLATFORM_DATA +#ifdef CONFIG_WILINK_PLATFORM_DATA { .name = "wl1271", .mmc = 2, @@ -450,7 +450,7 @@ static struct regulator_init_data omap3evm_vio = { .consumer_supplies = omap3evm_vio_supply, }; -#ifdef CONFIG_WL12XX_PLATFORM_DATA +#ifdef CONFIG_WILINK_PLATFORM_DATA #define OMAP3EVM_WLAN_PMENA_GPIO (150) #define OMAP3EVM_WLAN_IRQ_GPIO (149) @@ -563,7 +563,7 @@ static struct omap_board_mux omap35x_board_mux[] __initdata = { OMAP_PIN_OFF_NONE), OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_NONE), -#ifdef CONFIG_WL12XX_PLATFORM_DATA +#ifdef CONFIG_WILINK_PLATFORM_DATA /* WLAN IRQ - GPIO 149 */ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), @@ -601,7 +601,7 @@ static struct omap_board_mux omap36x_board_mux[] __initdata = { OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -#ifdef CONFIG_WL12XX_PLATFORM_DATA +#ifdef CONFIG_WILINK_PLATFORM_DATA /* WLAN IRQ - GPIO 149 */ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), @@ -637,7 +637,7 @@ static struct gpio omap3_evm_ehci_gpios[] __initdata = { static void __init omap3_evm_wl12xx_init(void) { -#ifdef CONFIG_WL12XX_PLATFORM_DATA +#ifdef CONFIG_WILINK_PLATFORM_DATA int ret; /* WL12xx WLAN Init */ diff --git a/drivers/net/wireless/ti/Kconfig b/drivers/net/wireless/ti/Kconfig index be800119d0a3..cbe1e7fef61b 100644 --- a/drivers/net/wireless/ti/Kconfig +++ b/drivers/net/wireless/ti/Kconfig @@ -12,4 +12,13 @@ source "drivers/net/wireless/ti/wl18xx/Kconfig" # keep last for automatic dependencies source "drivers/net/wireless/ti/wlcore/Kconfig" + +config WILINK_PLATFORM_DATA + bool "TI WiLink platform data" + depends on WLCORE_SDIO || WL1251_SDIO + default y + ---help--- + Small platform data bit needed to pass data to the sdio modules. + + endif # WL_TI diff --git a/drivers/net/wireless/ti/Makefile b/drivers/net/wireless/ti/Makefile index 4d6823983c04..af14231aeede 100644 --- a/drivers/net/wireless/ti/Makefile +++ b/drivers/net/wireless/ti/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_WLCORE) += wlcore/ obj-$(CONFIG_WL12XX) += wl12xx/ -obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wlcore/ obj-$(CONFIG_WL1251) += wl1251/ obj-$(CONFIG_WL18XX) += wl18xx/ + +# small builtin driver bit +obj-$(CONFIG_WILINK_PLATFORM_DATA) += wilink_platform_data.o diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c new file mode 100644 index 000000000000..998e95895f9d --- /dev/null +++ b/drivers/net/wireless/ti/wilink_platform_data.c @@ -0,0 +1,49 @@ +/* + * This file is part of wl12xx + * + * Copyright (C) 2010-2011 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include + +static struct wl12xx_platform_data *platform_data; + +int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data) +{ + if (platform_data) + return -EBUSY; + if (!data) + return -EINVAL; + + platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); + if (!platform_data) + return -ENOMEM; + + return 0; +} + +struct wl12xx_platform_data *wl12xx_get_platform_data(void) +{ + if (!platform_data) + return ERR_PTR(-ENODEV); + + return platform_data; +} +EXPORT_SYMBOL(wl12xx_get_platform_data); diff --git a/drivers/net/wireless/ti/wlcore/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig index d7b907e67170..2b832825c3d4 100644 --- a/drivers/net/wireless/ti/wlcore/Kconfig +++ b/drivers/net/wireless/ti/wlcore/Kconfig @@ -33,8 +33,3 @@ config WLCORE_SDIO If you choose to build a module, it'll be called wlcore_sdio. Say N if unsure. - -config WL12XX_PLATFORM_DATA - bool - depends on WLCORE_SDIO != n || WL1251_SDIO != n - default y diff --git a/drivers/net/wireless/ti/wlcore/Makefile b/drivers/net/wireless/ti/wlcore/Makefile index d9fba9e32130..b21398f6c3ec 100644 --- a/drivers/net/wireless/ti/wlcore/Makefile +++ b/drivers/net/wireless/ti/wlcore/Makefile @@ -9,7 +9,4 @@ obj-$(CONFIG_WLCORE) += wlcore.o obj-$(CONFIG_WLCORE_SPI) += wlcore_spi.o obj-$(CONFIG_WLCORE_SDIO) += wlcore_sdio.o -# small builtin driver bit -obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o - ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c b/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c deleted file mode 100644 index 998e95895f9d..000000000000 --- a/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of wl12xx - * - * Copyright (C) 2010-2011 Texas Instruments, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include -#include - -static struct wl12xx_platform_data *platform_data; - -int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data) -{ - if (platform_data) - return -EBUSY; - if (!data) - return -EINVAL; - - platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); - if (!platform_data) - return -ENOMEM; - - return 0; -} - -struct wl12xx_platform_data *wl12xx_get_platform_data(void) -{ - if (!platform_data) - return ERR_PTR(-ENODEV); - - return platform_data; -} -EXPORT_SYMBOL(wl12xx_get_platform_data); diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h index 360c9bce665c..a54fe82e704b 100644 --- a/include/linux/wl12xx.h +++ b/include/linux/wl12xx.h @@ -24,6 +24,8 @@ #ifndef _LINUX_WL12XX_H #define _LINUX_WL12XX_H +#include + /* Reference clock values */ enum { WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */ @@ -60,10 +62,12 @@ struct wl12xx_platform_data { /* Platform does not support level trigger interrupts */ #define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0) -#ifdef CONFIG_WL12XX_PLATFORM_DATA +#ifdef CONFIG_WILINK_PLATFORM_DATA int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); +struct wl12xx_platform_data *wl12xx_get_platform_data(void); + #else static inline @@ -72,8 +76,12 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data) return -ENOSYS; } -#endif +static inline +struct wl12xx_platform_data *wl12xx_get_platform_data(void) +{ + return ERR_PTR(-ENODATA); +} -struct wl12xx_platform_data *wl12xx_get_platform_data(void); +#endif #endif -- cgit v1.2.3-71-gd317