Hi Chethan, On Mon, Nov 05, 2018 at 02:46:26PM +0530, chethan tn wrote: > 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. I am confused, why you model a generic chip reset functionality via RFKill subsystem. As far as I understand, the issue is that you want to be able to reset the chip when it gets confused and not actually disable the chip/stop it from emitting RF signals. I believe this functionality should be contained in the driver and you simply need to come with a way to tie the adapter instance with data in ACPI, probably based on physical USB connection. Thanks. > > 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 -- Dmitry