From: Szymon Janc <szymon.janc@tieto.com>
To: Amitkumar Karwar <akarwar@marvell.com>
Cc: linux-bluetooth@vger.kernel.org, marcel@holtmann.org
Subject: Re: [PATCH] Bluetooth: btmrvl: add manufacturing mode support
Date: Thu, 07 May 2015 18:33:40 +0200 [thread overview]
Message-ID: <9058872.bsh93WddjV@leonov> (raw)
In-Reply-To: <1431012963-2754-1-git-send-email-akarwar@marvell.com>
Hi Amitkumar,
On Thursday 07 of May 2015 08:36:03 Amitkumar Karwar wrote:
> Default firmware is chosen when driver is loaded. This patch
> adds provision to download manufacturing firmware which is
> used for RF tests in the factory through sysfs configuration.
>
> Procedure
> 1) Switch from normal mode to manufacturing mode.
> echo 1 > /sys/class/bluetooth/hci0/mfg_mode.
> echo "mrvl/sdio8897_mfg.bin" > /sys/class/bluetooth/hci0/mfg_firmware
> Trigger chip reset from wlan driver.
>
> 2) Switch from manufacturing mode to normal mode.
> echo 0 > /sys/class/bluetooth/hci0/mfg_mode
> Trigger chip reset from wlan driver.
>
> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
> ---
> drivers/bluetooth/Makefile | 1 +
> drivers/bluetooth/btmrvl_drv.h | 7 +++
> drivers/bluetooth/btmrvl_main.c | 3 ++
> drivers/bluetooth/btmrvl_sdio.c | 16 +++++-
> drivers/bluetooth/btmrvl_sysfs.c | 103
> +++++++++++++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+),
> 2 deletions(-)
> create mode 100644 drivers/bluetooth/btmrvl_sysfs.c
>
> diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
> index dd0d9c4..11042ac 100644
> --- a/drivers/bluetooth/Makefile
> +++ b/drivers/bluetooth/Makefile
> @@ -23,6 +23,7 @@ obj-$(CONFIG_BT_WILINK) += btwilink.o
> obj-$(CONFIG_BT_BCM) += btbcm.o
>
> btmrvl-y := btmrvl_main.o
> +btmrvl-y += btmrvl_sysfs.o
> btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o
>
> hci_uart-y := hci_ldisc.o
> diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
> index 086f0ec..71dc407 100644
> --- a/drivers/bluetooth/btmrvl_drv.h
> +++ b/drivers/bluetooth/btmrvl_drv.h
> @@ -89,6 +89,7 @@ struct btmrvl_adapter {
> wait_queue_head_t event_hs_wait_q;
> u8 cmd_complete;
> bool is_suspended;
> + bool mfg_mode;
> };
>
> struct btmrvl_private {
> @@ -155,6 +156,9 @@ struct btmrvl_event {
> u8 data[4];
> } __packed;
>
> +extern bool mfg_mode;
> +extern char mfg_firmware[32];
> +
> /* Prototype of global function */
>
> int btmrvl_register_hdev(struct btmrvl_private *priv);
> @@ -174,6 +178,9 @@ int btmrvl_prepare_command(struct btmrvl_private *priv);
> int btmrvl_enable_hs(struct btmrvl_private *priv);
> void btmrvl_firmware_dump(struct btmrvl_private *priv);
>
> +int btmrvl_sysfs_register(struct hci_dev *hdev);
> +void btmrvl_sysfs_unregister(struct hci_dev *hdev);
> +
> #ifdef CONFIG_DEBUG_FS
> void btmrvl_debugfs_init(struct hci_dev *hdev);
> void btmrvl_debugfs_remove(struct hci_dev *hdev);
> diff --git a/drivers/bluetooth/btmrvl_main.c
> b/drivers/bluetooth/btmrvl_main.c index de05deb..1a76bdd 100644
> --- a/drivers/bluetooth/btmrvl_main.c
> +++ b/drivers/bluetooth/btmrvl_main.c
> @@ -432,6 +432,7 @@ static void btmrvl_init_adapter(struct btmrvl_private
> *priv)
>
> init_waitqueue_head(&priv->adapter->cmd_wait_q);
> init_waitqueue_head(&priv->adapter->event_hs_wait_q);
> + priv->adapter->mfg_mode = mfg_mode;
> }
>
> static void btmrvl_free_adapter(struct btmrvl_private *priv)
> @@ -716,6 +717,7 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
> #ifdef CONFIG_DEBUG_FS
> btmrvl_debugfs_init(hdev);
> #endif
> + btmrvl_sysfs_register(hdev);
>
> return 0;
>
> @@ -791,6 +793,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv)
> #ifdef CONFIG_DEBUG_FS
> btmrvl_debugfs_remove(hdev);
> #endif
> + btmrvl_sysfs_unregister(hdev);
>
> hci_unregister_dev(hdev);
>
> diff --git a/drivers/bluetooth/btmrvl_sdio.c
> b/drivers/bluetooth/btmrvl_sdio.c index 01d6da5..82268717 100644
> --- a/drivers/bluetooth/btmrvl_sdio.c
> +++ b/drivers/bluetooth/btmrvl_sdio.c
> @@ -452,8 +452,20 @@ static int btmrvl_sdio_download_fw_w_helper(struct
> btmrvl_sdio_card *card) u16 len, blksz_dl = card->sd_blksz_fw_dl;
> int txlen = 0, tx_blocks = 0, count = 0;
>
> - ret = request_firmware(&fw_firmware, card->firmware,
> - &card->func->dev);
> + if (mfg_mode && !strlen(mfg_firmware)) {
> + mfg_mode = 0;
> + BT_ERR("mfg firmware missing. Ignoring manufacturing mode");
> + }
> +
> + /* override default firmware name with new one if provided by user */
> + if (mfg_mode) {
> + ret = request_firmware(&fw_firmware, mfg_firmware,
> + &card->func->dev);
> + } else {
> + ret = request_firmware(&fw_firmware, card->firmware,
> + &card->func->dev);
> + }
> +
> if ((ret < 0) || !fw_firmware) {
> BT_ERR("request_firmware(firmware) failed, error code = %d",
> ret);
> diff --git a/drivers/bluetooth/btmrvl_sysfs.c
> b/drivers/bluetooth/btmrvl_sysfs.c new file mode 100644
> index 0000000..b39938e
> --- /dev/null
> +++ b/drivers/bluetooth/btmrvl_sysfs.c
> @@ -0,0 +1,103 @@
> +/* Marvell Bluetooth driver: sysfs related functions
> + *
> + * Copyright (C) 2015, Marvell International Ltd.
> + *
> + * This software file (the "File") is distributed by Marvell International
> + * Ltd. under the terms of the GNU General Public License Version 2, June
> 1991 + * (the "License"). You may use, redistribute and/or modify this
> File in + * accordance with the terms and conditions of the License, a copy
> of which + * is available on the worldwide web at
> + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
> + *
> + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
> PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional
> details about + * this warranty disclaimer.
> + */
> +
> +#include <net/bluetooth/bluetooth.h>
> +#include <net/bluetooth/hci_core.h>
> +#include "btmrvl_drv.h"
> +
> +bool mfg_mode;
> +EXPORT_SYMBOL_GPL(mfg_mode);
> +char mfg_firmware[32];
> +EXPORT_SYMBOL_GPL(mfg_firmware);
> +
> +static ssize_t
> +btmrvl_sysfs_get_mfg_mode(struct device *dev, struct device_attribute
> *attr, + char *buf)
> +{
> + struct btmrvl_private *priv = hci_get_drvdata(to_hci_dev(dev));
> +
> + return snprintf(buf, PAGE_SIZE, "%d\n", priv->adapter->mfg_mode);
> +}
> +
> +static ssize_t
> +btmrvl_sysfs_set_mfg_mode(struct device *dev, struct device_attribute
> *attr, + const char *buf, size_t count)
> +{
> + bool res;
> +
> + if (strtobool(buf, &res))
> + return -EINVAL;
> +
> + mfg_mode = res;
> +
> + return count;
> +}
> +
> +static DEVICE_ATTR(mfg_mode, S_IRUGO | S_IWUSR,
> + btmrvl_sysfs_get_mfg_mode,
> + btmrvl_sysfs_set_mfg_mode);
> +
> +static ssize_t btmrvl_sysfs_show_mfg_firmware(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + return snprintf(buf, PAGE_SIZE, "%s\n", mfg_firmware);
> +}
> +
> +static ssize_t btmrvl_sysfs_store_mfg_firmware(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + int len;
> +
> + len = strlen(buf);
> + if (len > sizeof(mfg_firmware))
> + return -EINVAL;
> +
> + strcpy(mfg_firmware, buf);
if len == sizeof(mfg_firmware) you will write 1 byte after mfg_firmware
> + mfg_firmware[len - 1] = '\0';
if len == 0 you will write 1 byte before mfg_firmware
> +
> + return count;
> +}
> +static DEVICE_ATTR(mfg_firmware, S_IRUGO | S_IWUSR,
> + btmrvl_sysfs_show_mfg_firmware,
> + btmrvl_sysfs_store_mfg_firmware);
> +
> +int btmrvl_sysfs_register(struct hci_dev *hdev)
> +{
> + int ret;
> +
> + /* Create sysfs file to control manufacturing mode feature*/
> + ret = device_create_file(&hdev->dev, &dev_attr_mfg_mode);
> + if (ret)
> + BT_ERR("%s failed to create sysfs file mfg_mode", hdev->name);
> +
> + /* Create sysfs file to store manufacturing firmware name */
> + ret = device_create_file(&hdev->dev, &dev_attr_mfg_firmware);
> + if (ret)
> + BT_ERR("%s failed to create sysfs file mfg_firmware",
> + hdev->name);
> +
> + return ret;
> +}
> +
> +void btmrvl_sysfs_unregister(struct hci_dev *hdev)
> +{
> + device_remove_file(&hdev->dev, &dev_attr_mfg_mode);
> + device_remove_file(&hdev->dev, &dev_attr_mfg_firmware);
> +}
> +
--
BR
Szymon Janc
next prev parent reply other threads:[~2015-05-07 16:33 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-07 15:36 [PATCH] Bluetooth: btmrvl: add manufacturing mode support Amitkumar Karwar
2015-05-07 15:54 ` Marcel Holtmann
2015-05-08 13:57 ` Amitkumar Karwar
2015-05-07 16:33 ` Szymon Janc [this message]
2015-05-08 13:59 ` Amitkumar Karwar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9058872.bsh93WddjV@leonov \
--to=szymon.janc@tieto.com \
--cc=akarwar@marvell.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=marcel@holtmann.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.