diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2017-03-30 13:04:43 +0300 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-03-31 09:06:29 +0300 |
commit | d4d969909bef4c1e103eec0fc2c820773811fb72 (patch) | |
tree | 3e48a64c11a98e7015701be148b31238ce440c48 /arch/x86/platform/intel-mid | |
parent | 2f2a033fb5819c393d65da9b6233e095f3690f15 (diff) | |
download | linux-d4d969909bef4c1e103eec0fc2c820773811fb72.tar.xz |
x86/platform/intel-mid: Enable Bluetooth support on Intel Edison
Intel Edison has Wi-Fi + BT module attached and, since it's an SFI-enumerated
platform, needs platform data. Here we add bits to enable the Bluetooth device.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20170330100443.22701-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/platform/intel-mid')
-rw-r--r-- | arch/x86/platform/intel-mid/device_libs/Makefile | 3 | ||||
-rw-r--r-- | arch/x86/platform/intel-mid/device_libs/platform_bt.c | 108 |
2 files changed, 110 insertions, 1 deletions
diff --git a/arch/x86/platform/intel-mid/device_libs/Makefile b/arch/x86/platform/intel-mid/device_libs/Makefile index a7dbec4dce27..36f0fdf6079a 100644 --- a/arch/x86/platform/intel-mid/device_libs/Makefile +++ b/arch/x86/platform/intel-mid/device_libs/Makefile @@ -2,8 +2,9 @@ obj-$(subst m,y,$(CONFIG_PINCTRL_MERRIFIELD)) += platform_mrfld_pinctrl.o # SDHCI Devices obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += platform_mrfld_sd.o -# WiFi +# WiFi + BT obj-$(subst m,y,$(CONFIG_BRCMFMAC_SDIO)) += platform_bcm43xx.o +obj-$(subst m,y,$(CONFIG_BT_HCIUART_BCM)) += platform_bt.o # IPC Devices obj-$(subst m,y,$(CONFIG_MFD_INTEL_MSIC)) += platform_msic.o obj-$(subst m,y,$(CONFIG_SND_MFLD_MACHINE)) += platform_msic_audio.o diff --git a/arch/x86/platform/intel-mid/device_libs/platform_bt.c b/arch/x86/platform/intel-mid/device_libs/platform_bt.c new file mode 100644 index 000000000000..5a0483e7bf66 --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_bt.c @@ -0,0 +1,108 @@ +/* + * Bluetooth platform data initialization file + * + * (C) Copyright 2017 Intel Corporation + * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + * + * 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; version 2 + * of the License. + */ + +#include <linux/gpio/machine.h> +#include <linux/pci.h> +#include <linux/platform_device.h> + +#include <asm/cpu_device_id.h> +#include <asm/intel-family.h> +#include <asm/intel-mid.h> + +struct bt_sfi_data { + struct device *dev; + const char *name; + int (*setup)(struct bt_sfi_data *ddata); +}; + +static struct gpiod_lookup_table tng_bt_sfi_gpio_table = { + .dev_id = "hci_bcm", + .table = { + GPIO_LOOKUP("0000:00:0c.0", -1, "device-wakeup", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("0000:00:0c.0", -1, "shutdown", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("0000:00:0c.0", -1, "host-wakeup", GPIO_ACTIVE_HIGH), + { }, + }, +}; + +#define TNG_BT_SFI_GPIO_DEVICE_WAKEUP "bt_wakeup" +#define TNG_BT_SFI_GPIO_SHUTDOWN "BT-reset" +#define TNG_BT_SFI_GPIO_HOST_WAKEUP "bt_uart_enable" + +static int __init tng_bt_sfi_setup(struct bt_sfi_data *ddata) +{ + struct gpiod_lookup_table *table = &tng_bt_sfi_gpio_table; + struct gpiod_lookup *lookup = table->table; + struct pci_dev *pdev; + + /* Connected to /dev/ttyS0 */ + pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(4, 1)); + if (!pdev) + return -ENODEV; + + ddata->dev = &pdev->dev; + ddata->name = table->dev_id; + + lookup[0].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_DEVICE_WAKEUP); + lookup[1].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_SHUTDOWN); + lookup[2].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_HOST_WAKEUP); + + gpiod_add_lookup_table(table); + return 0; +} + +static struct bt_sfi_data tng_bt_sfi_data __initdata = { + .setup = tng_bt_sfi_setup, +}; + +#define ICPU(model, ddata) \ + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (kernel_ulong_t)&ddata } + +static const struct x86_cpu_id bt_sfi_cpu_ids[] = { + ICPU(INTEL_FAM6_ATOM_MERRIFIELD, tng_bt_sfi_data), + {} +}; + +static int __init bt_sfi_init(void) +{ + struct platform_device_info info; + struct platform_device *pdev; + const struct x86_cpu_id *id; + struct bt_sfi_data *ddata; + int ret; + + id = x86_match_cpu(bt_sfi_cpu_ids); + if (!id) + return -ENODEV; + + ddata = (struct bt_sfi_data *)id->driver_data; + if (!ddata) + return -ENODEV; + + ret = ddata->setup(ddata); + if (ret) + return ret; + + memset(&info, 0, sizeof(info)); + info.fwnode = ddata->dev->fwnode; + info.parent = ddata->dev; + info.name = ddata->name, + info.id = PLATFORM_DEVID_NONE, + + pdev = platform_device_register_full(&info); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + dev_info(ddata->dev, "Registered Bluetooth device: %s\n", ddata->name); + return 0; +} +device_initcall(bt_sfi_init); |