Re: [Patch v1] Bluetooth: Add Rfkill driver for Intel Bluetooth controller

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

We are planning to further implement the followings, kindly please
provide your suggestions.
1. To handle more than 1 Intel BT controller connected to platform,
will keep list of the objects in "static const struct acpi_device_id
intel_bt_rfkill_acpi_match[] ". And keep a list of "struct
intel_bt_rfkill_dev" for each of the acpi object.
2.  With this implementation from user space RF kill for the device
object is achieved, however need to map the rfkill object with the
corresponding "hdev" so that on error from the controller kernel can
do the reset through this RF Kill driver.

Best Regards
Chethan
On Tue, Oct 30, 2018 at 7:27 PM Chethan T N
<chethan.tumkur.narayan@xxxxxxxxx> wrote:
>
> From: Raghuram Hegde <raghuram.hegde@xxxxxxxxx>
>
> Register ACPI object INTL6205 as platform Bluetooth RfKill
> driver to attach/detach Intel Bluetooth controller from
> platform USB bus.
>
> Signed-off-by: Raghuram Hegde <raghuram.hegde@xxxxxxxxx>
> Signed-off-by: Chethan T N <chethan.tumkur.narayan@xxxxxxxxx>
> Signed-off-by: Sukumar Ghorai <sukumar.ghorai@xxxxxxxxx>
> ---
>  drivers/platform/x86/Kconfig           |   9 +++
>  drivers/platform/x86/Makefile          |   1 +
>  drivers/platform/x86/intel_bt_rfkill.c | 123 +++++++++++++++++++++++++++++++++
>  3 files changed, 133 insertions(+)
>  create mode 100644 drivers/platform/x86/intel_bt_rfkill.c
>
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index 0c1aa6c314f5..bf050ba644c6 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -1229,6 +1229,15 @@ config I2C_MULTI_INSTANTIATE
>           To compile this driver as a module, choose M here: the module
>           will be called i2c-multi-instantiate.
>
> +config INTEL_BT_RFKILL
> +       tristate "Intel bluetooth platform rfkill support"
> +       depends on ACPI
> +       depends on RFKILL || !RFKILL
> +       ---help---
> +         This option adds support for rfkill switch on Intel bluetooth
> +         controllers.
> +         If you have a PC with Intel Bluetooth controller, choose Y.
> +
>  endif # X86_PLATFORM_DEVICES
>
>  config PMC_ATOM
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index e6d1becf81ce..af9ac3cd6151 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -92,3 +92,4 @@ obj-$(CONFIG_MLX_PLATFORM)    += mlx-platform.o
>  obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
>  obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN)    += intel_chtdc_ti_pwrbtn.o
>  obj-$(CONFIG_I2C_MULTI_INSTANTIATE)    += i2c-multi-instantiate.o
> +obj-$(CONFIG_INTEL_BT_RFKILL)   += intel_bt_rfkill.o
> diff --git a/drivers/platform/x86/intel_bt_rfkill.c b/drivers/platform/x86/intel_bt_rfkill.c
> new file mode 100644
> index 000000000000..904440dadb64
> --- /dev/null
> +++ b/drivers/platform/x86/intel_bt_rfkill.c
> @@ -0,0 +1,123 @@
> +/*
> + *  Intel Bluetooth Rfkill Driver
> + */
> +
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/platform_device.h>
> +#include <linux/rfkill.h>
> +#include <linux/gpio/consumer.h>
> +
> +struct intel_bt_rfkill_dev {
> +       struct rfkill *rfkill;
> +       struct gpio_desc *reset_gpio_handler;
> +};
> +
> +static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
> +static const struct acpi_gpio_mapping acpi_intel_bt_rfkill_gpios[] = {
> +       { "reset-gpios", &reset_gpios, 1 },
> +       { },
> +};
> +
> +static int intel_bt_disable(struct gpio_desc *reset_gpio)
> +{
> +       if (!reset_gpio)
> +               return -EINVAL;
> +
> +       /* This will detach the Intel BT controller */
> +       gpiod_set_value(reset_gpio, 0);
> +       return 0;
> +}
> +
> +static int intel_bt_enable(struct gpio_desc *reset_gpio)
> +{
> +       if (!reset_gpio)
> +               return -EINVAL;
> +
> +       /* This will re-attach the Intel BT controller */
> +       gpiod_set_value(reset_gpio, 1);
> +       return 0;
> +}
> +
> +/* RFKill handlers */
> +static int intel_bt_rfkill_set_block(void *data, bool blocked)
> +{
> +       struct intel_bt_rfkill_dev *bt_dev = data;
> +       int ret;
> +
> +       if (blocked)
> +               ret = intel_bt_disable(bt_dev->reset_gpio_handler);
> +       else
> +               ret = intel_bt_enable(bt_dev->reset_gpio_handler);
> +
> +       return ret;
> +}
> +static const struct rfkill_ops rfk_ops = {
> +       .set_block = intel_bt_rfkill_set_block,
> +};
> +
> +/* ACPI object probe */
> +static int intel_bt_rfkill_probe(struct platform_device *pdev)
> +{
> +       struct intel_bt_rfkill_dev *bt_dev;
> +       int result;
> +
> +       bt_dev = devm_kzalloc(&pdev->dev, sizeof(*bt_dev), GFP_KERNEL);
> +       if (!bt_dev)
> +               return -ENOMEM;
> +
> +       dev_set_drvdata(&pdev->dev, bt_dev);
> +
> +       if (acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev),
> +                                    acpi_intel_bt_rfkill_gpios))
> +               return -EINVAL;
> +
> +       bt_dev->reset_gpio_handler = devm_gpiod_get_optional(&pdev->dev,
> +                                       "reset", GPIOD_OUT_HIGH);
> +       if (IS_ERR(bt_dev->reset_gpio_handler))
> +               return PTR_ERR(bt_dev->reset_gpio_handler);
> +
> +       bt_dev->rfkill = rfkill_alloc("intel_bluetooth",
> +                                  &pdev->dev,
> +                                  RFKILL_TYPE_BLUETOOTH,
> +                                  &rfk_ops,
> +                                  bt_dev);
> +       if (!bt_dev->rfkill)
> +               return -ENOMEM;
> +
> +       result = rfkill_register(bt_dev->rfkill);
> +       if (result)
> +               rfkill_destroy(bt_dev->rfkill);
> +
> +       return result;
> +}
> +
> +static int intel_bt_rfkill_remove(struct platform_device *pdev)
> +{
> +       struct intel_bt_rfkill_dev *bt_dev = dev_get_drvdata(&pdev->dev);
> +
> +       if (bt_dev->rfkill) {
> +               rfkill_unregister(bt_dev->rfkill);
> +               rfkill_destroy(bt_dev->rfkill);
> +       }
> +
> +       acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
> +
> +       return 0;
> +}
> +
> +static const struct acpi_device_id intel_bt_rfkill_acpi_match[] = {
> +       { "INTL6205", 0 },
> +       { },
> +};
> +MODULE_DEVICE_TABLE(acpi, intel_bt_rfkill_acpi_match);
> +
> +static struct platform_driver intel_bt_rfkill_driver = {
> +       .probe = intel_bt_rfkill_probe,
> +       .remove = intel_bt_rfkill_remove,
> +       .driver = {
> +               .name = "intel_bt_rfkill",
> +               .acpi_match_table = ACPI_PTR(intel_bt_rfkill_acpi_match),
> +       },
> +};
> +module_platform_driver(intel_bt_rfkill_driver);
> --
> 2.7.4



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux