-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Andy Shevchenko
authored and
Ingo Molnar
committed
Mar 31, 2017
1 parent
2f2a033
commit d4d9699
Showing
2 changed files
with
110 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); |