Linux 4.18.10
[linux/fpc-iii.git] / arch / x86 / platform / intel-mid / device_libs / platform_bt.c
blob5a0483e7bf662cb27044b7684567b644dfe49b81
1 /*
2 * Bluetooth platform data initialization file
4 * (C) Copyright 2017 Intel Corporation
5 * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
13 #include <linux/gpio/machine.h>
14 #include <linux/pci.h>
15 #include <linux/platform_device.h>
17 #include <asm/cpu_device_id.h>
18 #include <asm/intel-family.h>
19 #include <asm/intel-mid.h>
21 struct bt_sfi_data {
22 struct device *dev;
23 const char *name;
24 int (*setup)(struct bt_sfi_data *ddata);
27 static struct gpiod_lookup_table tng_bt_sfi_gpio_table = {
28 .dev_id = "hci_bcm",
29 .table = {
30 GPIO_LOOKUP("0000:00:0c.0", -1, "device-wakeup", GPIO_ACTIVE_HIGH),
31 GPIO_LOOKUP("0000:00:0c.0", -1, "shutdown", GPIO_ACTIVE_HIGH),
32 GPIO_LOOKUP("0000:00:0c.0", -1, "host-wakeup", GPIO_ACTIVE_HIGH),
33 { },
37 #define TNG_BT_SFI_GPIO_DEVICE_WAKEUP "bt_wakeup"
38 #define TNG_BT_SFI_GPIO_SHUTDOWN "BT-reset"
39 #define TNG_BT_SFI_GPIO_HOST_WAKEUP "bt_uart_enable"
41 static int __init tng_bt_sfi_setup(struct bt_sfi_data *ddata)
43 struct gpiod_lookup_table *table = &tng_bt_sfi_gpio_table;
44 struct gpiod_lookup *lookup = table->table;
45 struct pci_dev *pdev;
47 /* Connected to /dev/ttyS0 */
48 pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(4, 1));
49 if (!pdev)
50 return -ENODEV;
52 ddata->dev = &pdev->dev;
53 ddata->name = table->dev_id;
55 lookup[0].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_DEVICE_WAKEUP);
56 lookup[1].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_SHUTDOWN);
57 lookup[2].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_HOST_WAKEUP);
59 gpiod_add_lookup_table(table);
60 return 0;
63 static struct bt_sfi_data tng_bt_sfi_data __initdata = {
64 .setup = tng_bt_sfi_setup,
67 #define ICPU(model, ddata) \
68 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (kernel_ulong_t)&ddata }
70 static const struct x86_cpu_id bt_sfi_cpu_ids[] = {
71 ICPU(INTEL_FAM6_ATOM_MERRIFIELD, tng_bt_sfi_data),
75 static int __init bt_sfi_init(void)
77 struct platform_device_info info;
78 struct platform_device *pdev;
79 const struct x86_cpu_id *id;
80 struct bt_sfi_data *ddata;
81 int ret;
83 id = x86_match_cpu(bt_sfi_cpu_ids);
84 if (!id)
85 return -ENODEV;
87 ddata = (struct bt_sfi_data *)id->driver_data;
88 if (!ddata)
89 return -ENODEV;
91 ret = ddata->setup(ddata);
92 if (ret)
93 return ret;
95 memset(&info, 0, sizeof(info));
96 info.fwnode = ddata->dev->fwnode;
97 info.parent = ddata->dev;
98 info.name = ddata->name,
99 info.id = PLATFORM_DEVID_NONE,
101 pdev = platform_device_register_full(&info);
102 if (IS_ERR(pdev))
103 return PTR_ERR(pdev);
105 dev_info(ddata->dev, "Registered Bluetooth device: %s\n", ddata->name);
106 return 0;
108 device_initcall(bt_sfi_init);