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>
This commit is contained in:
Родитель
2f2a033fb5
Коммит
d4d969909b
|
@ -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
|
||||
|
|
|
@ -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);
|
Загрузка…
Ссылка в новой задаче