diff mbox

[09/11] brcmfmac: Fix OOB interrupt not working for BCM43362

Message ID 1401090486-4414-10-git-send-email-hdegoede@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Hans de Goede May 26, 2014, 7:48 a.m. UTC
It has taken me a long long time to get the OOB interrupt working on the
AP6210 sdio wifi/bt module found on various Allwinner A20 boards. In the
end I found these magic register pokes in the cubietruck kernel tree:
https://github.com/cubieboard2/linux-sunxi/commit/7f08ba395617d17e7a711507503d89a50406fe7a

I'm not entirely sure if this specific to the AP6210 module, or if this
should be done for all BCM43362 sdio devices.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Arend van Spriel May 26, 2014, 9:20 a.m. UTC | #1
On 05/26/14 09:48, Hans de Goede wrote:
> It has taken me a long long time to get the OOB interrupt working on the
> AP6210 sdio wifi/bt module found on various Allwinner A20 boards. In the
> end I found these magic register pokes in the cubietruck kernel tree:
> https://github.com/cubieboard2/linux-sunxi/commit/7f08ba395617d17e7a711507503d89a50406fe7a
>
> I'm not entirely sure if this specific to the AP6210 module, or if this
> should be done for all BCM43362 sdio devices.

This magic is not in our host drivers so my guess is that it is board 
specific. This means the nvram file provided to the firmware should have 
this specified. Can you send me yours?

Regards,
Arend

> Signed-off-by: Hans de Goede<hdegoede@redhat.com>
> ---
>   drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 18 ++++++++++++++++++
>   1 file changed, 18 insertions(+)
>
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> index 0fc707c..2369a0f 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> @@ -39,7 +39,9 @@
>   #include<brcm_hw_ids.h>
>   #include<brcmu_utils.h>
>   #include<brcmu_wifi.h>
> +#include<chipcommon.h>
>   #include<soc.h>
> +#include "chip.h"
>   #include "dhd_bus.h"
>   #include "dhd_dbg.h"
>   #include "sdio_host.h"
> @@ -119,6 +121,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
>   {
>   	int ret = 0;
>   	u8 data;
> +	u32 addr, gpiocontrol;
>   	unsigned long flags;
>
>   	if ((sdiodev->pdata)&&  (sdiodev->pdata->oob_irq_supported)) {
> @@ -148,6 +151,21 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
>
>   		sdio_claim_host(sdiodev->func[1]);
>
> +		if (sdiodev->bus_if->chip == BCM43362_CHIP_ID) {
> +			addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
> +			gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr,&ret);
> +			gpiocontrol |= 0x2;
> +			brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol,&ret);
> +
> +			/* SPROM_ADDR_HIGH ? perhaps the defines name is off */
> +			brcmf_sdiod_regwb(sdiodev, SBSDIO_SPROM_ADDR_HIGH, 0xf,
> +					&ret);
> +			brcmf_sdiod_regwb(sdiodev, SBSDIO_CHIP_CTRL_DATA, 0,
> +					&ret);
> +			brcmf_sdiod_regwb(sdiodev, SBSDIO_CHIP_CTRL_EN, 0x2,
> +					&ret);
> +		}
> +
>   		/* must configure SDIO_CCCR_IENx to enable irq */
>   		data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx,&ret);
>   		data |= 1<<  SDIO_FUNC_1 | 1<<  SDIO_FUNC_2 | 1;

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arend van Spriel May 27, 2014, 5:03 p.m. UTC | #2
On 05/26/14 09:48, Hans de Goede wrote:
> It has taken me a long long time to get the OOB interrupt working on the
> AP6210 sdio wifi/bt module found on various Allwinner A20 boards. In the
> end I found these magic register pokes in the cubietruck kernel tree:
> https://github.com/cubieboard2/linux-sunxi/commit/7f08ba395617d17e7a711507503d89a50406fe7a
>
> I'm not entirely sure if this specific to the AP6210 module, or if this
> should be done for all BCM43362 sdio devices.

Let keep it as this for now. I added some remarks below.

Regards,
Arend

> Signed-off-by: Hans de Goede<hdegoede@redhat.com>
> ---
>   drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 18 ++++++++++++++++++
>   1 file changed, 18 insertions(+)
>
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> index 0fc707c..2369a0f 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
> @@ -39,7 +39,9 @@
>   #include<brcm_hw_ids.h>
>   #include<brcmu_utils.h>
>   #include<brcmu_wifi.h>
> +#include<chipcommon.h>
>   #include<soc.h>
> +#include "chip.h"
>   #include "dhd_bus.h"
>   #include "dhd_dbg.h"
>   #include "sdio_host.h"
> @@ -119,6 +121,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
>   {
>   	int ret = 0;
>   	u8 data;
> +	u32 addr, gpiocontrol;
>   	unsigned long flags;
>
>   	if ((sdiodev->pdata)&&  (sdiodev->pdata->oob_irq_supported)) {
> @@ -148,6 +151,21 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
>
>   		sdio_claim_host(sdiodev->func[1]);
>
> +		if (sdiodev->bus_if->chip == BCM43362_CHIP_ID) {
+			/* assign GPIO to SDIO core */
> +			addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
> +			gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr,&ret);
> +			gpiocontrol |= 0x2;
> +			brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol,&ret);
> +
> +			/* SPROM_ADDR_HIGH ? perhaps the defines name is off */

These names are all off. These should be:
SBSDIO_SPROM_ADDR_HIGH = SBSDIO_GPIO_SELECT
SBSDIO_CHIP_CTRL_DATA = SBSDIO_GPIO_OUT
SBSDIO_CHIP_CTRL_EN = SBSDIO_GPIO_EN

> +			brcmf_sdiod_regwb(sdiodev, SBSDIO_SPROM_ADDR_HIGH, 0xf,
> +					&ret);
> +			brcmf_sdiod_regwb(sdiodev, SBSDIO_CHIP_CTRL_DATA, 0,
> +					&ret);
> +			brcmf_sdiod_regwb(sdiodev, SBSDIO_CHIP_CTRL_EN, 0x2,
> +					&ret);
> +		}
> +
>   		/* must configure SDIO_CCCR_IENx to enable irq */
>   		data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx,&ret);
>   		data |= 1<<  SDIO_FUNC_1 | 1<<  SDIO_FUNC_2 | 1;

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Hans de Goede May 27, 2014, 9:28 p.m. UTC | #3
Hi,

On 05/27/2014 07:03 PM, Arend van Spriel wrote:
> On 05/26/14 09:48, Hans de Goede wrote:
>> It has taken me a long long time to get the OOB interrupt working on the
>> AP6210 sdio wifi/bt module found on various Allwinner A20 boards. In the
>> end I found these magic register pokes in the cubietruck kernel tree:
>> https://github.com/cubieboard2/linux-sunxi/commit/7f08ba395617d17e7a711507503d89a50406fe7a
>>
>> I'm not entirely sure if this specific to the AP6210 module, or if this
>> should be done for all BCM43362 sdio devices.
>
> Let keep it as this for now. I added some remarks below.
>
> Regards,
> Arend
>
>> Signed-off-by: Hans de Goede<hdegoede@redhat.com>
>> ---
>>   drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 18 ++++++++++++++++++
>>   1 file changed, 18 insertions(+)
>>
>> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>> index 0fc707c..2369a0f 100644
>> --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>> +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>> @@ -39,7 +39,9 @@
>>   #include<brcm_hw_ids.h>
>>   #include<brcmu_utils.h>
>>   #include<brcmu_wifi.h>
>> +#include<chipcommon.h>
>>   #include<soc.h>
>> +#include "chip.h"
>>   #include "dhd_bus.h"
>>   #include "dhd_dbg.h"
>>   #include "sdio_host.h"
>> @@ -119,6 +121,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
>>   {
>>       int ret = 0;
>>       u8 data;
>> +    u32 addr, gpiocontrol;
>>       unsigned long flags;
>>
>>       if ((sdiodev->pdata)&&  (sdiodev->pdata->oob_irq_supported)) {
>> @@ -148,6 +151,21 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
>>
>>           sdio_claim_host(sdiodev->func[1]);
>>
>> +        if (sdiodev->bus_if->chip == BCM43362_CHIP_ID) {
> +            /* assign GPIO to SDIO core */
>> +            addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
>> +            gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr,&ret);
>> +            gpiocontrol |= 0x2;
>> +            brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol,&ret);
>> +
>> +            /* SPROM_ADDR_HIGH ? perhaps the defines name is off */
>
> These names are all off. These should be:
> SBSDIO_SPROM_ADDR_HIGH = SBSDIO_GPIO_SELECT
> SBSDIO_CHIP_CTRL_DATA = SBSDIO_GPIO_OUT
> SBSDIO_CHIP_CTRL_EN = SBSDIO_GPIO_EN

Ok, so I guess I should do a pre-patch adding defines for these, should
these replace the existing defines for these addresses in:
drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h

Or should the pre-patch add defines with the new names and keep the old
ones ?

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Arend van Spriel May 28, 2014, 9:07 a.m. UTC | #4
On 05/27/14 23:28, Hans de Goede wrote:
> Hi,
>
> On 05/27/2014 07:03 PM, Arend van Spriel wrote:
>> On 05/26/14 09:48, Hans de Goede wrote:
>>> It has taken me a long long time to get the OOB interrupt working on the
>>> AP6210 sdio wifi/bt module found on various Allwinner A20 boards. In the
>>> end I found these magic register pokes in the cubietruck kernel tree:
>>> https://github.com/cubieboard2/linux-sunxi/commit/7f08ba395617d17e7a711507503d89a50406fe7a
>>>
>>>
>>> I'm not entirely sure if this specific to the AP6210 module, or if this
>>> should be done for all BCM43362 sdio devices.
>>
>> Let keep it as this for now. I added some remarks below.
>>
>> Regards,
>> Arend
>>
>>> Signed-off-by: Hans de Goede<hdegoede@redhat.com>
>>> ---
>>> drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 18 ++++++++++++++++++
>>> 1 file changed, 18 insertions(+)
>>>
>>> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>>> b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>>> index 0fc707c..2369a0f 100644
>>> --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>>> +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>>> @@ -39,7 +39,9 @@
>>> #include<brcm_hw_ids.h>
>>> #include<brcmu_utils.h>
>>> #include<brcmu_wifi.h>
>>> +#include<chipcommon.h>
>>> #include<soc.h>
>>> +#include "chip.h"
>>> #include "dhd_bus.h"
>>> #include "dhd_dbg.h"
>>> #include "sdio_host.h"
>>> @@ -119,6 +121,7 @@ int brcmf_sdiod_intr_register(struct
>>> brcmf_sdio_dev *sdiodev)
>>> {
>>> int ret = 0;
>>> u8 data;
>>> + u32 addr, gpiocontrol;
>>> unsigned long flags;
>>>
>>> if ((sdiodev->pdata)&& (sdiodev->pdata->oob_irq_supported)) {
>>> @@ -148,6 +151,21 @@ int brcmf_sdiod_intr_register(struct
>>> brcmf_sdio_dev *sdiodev)
>>>
>>> sdio_claim_host(sdiodev->func[1]);
>>>
>>> + if (sdiodev->bus_if->chip == BCM43362_CHIP_ID) {
>> + /* assign GPIO to SDIO core */
>>> + addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
>>> + gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr,&ret);
>>> + gpiocontrol |= 0x2;
>>> + brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol,&ret);
>>> +
>>> + /* SPROM_ADDR_HIGH ? perhaps the defines name is off */
>>
>> These names are all off. These should be:
>> SBSDIO_SPROM_ADDR_HIGH = SBSDIO_GPIO_SELECT
>> SBSDIO_CHIP_CTRL_DATA = SBSDIO_GPIO_OUT
>> SBSDIO_CHIP_CTRL_EN = SBSDIO_GPIO_EN
>
> Ok, so I guess I should do a pre-patch adding defines for these, should
> these replace the existing defines for these addresses in:
> drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
>
> Or should the pre-patch add defines with the new names and keep the old
> ones ?

These defines are not used in the code so go ahead and replace them. It 
needs some more cleanup, but I can do a subsequent patch for that.

Gr. AvS
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 0fc707c..2369a0f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -39,7 +39,9 @@ 
 #include <brcm_hw_ids.h>
 #include <brcmu_utils.h>
 #include <brcmu_wifi.h>
+#include <chipcommon.h>
 #include <soc.h>
+#include "chip.h"
 #include "dhd_bus.h"
 #include "dhd_dbg.h"
 #include "sdio_host.h"
@@ -119,6 +121,7 @@  int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
 {
 	int ret = 0;
 	u8 data;
+	u32 addr, gpiocontrol;
 	unsigned long flags;
 
 	if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
@@ -148,6 +151,21 @@  int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
 
 		sdio_claim_host(sdiodev->func[1]);
 
+		if (sdiodev->bus_if->chip == BCM43362_CHIP_ID) {
+			addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
+			gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr, &ret);
+			gpiocontrol |= 0x2;
+			brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret);
+
+			/* SPROM_ADDR_HIGH ? perhaps the defines name is off */
+			brcmf_sdiod_regwb(sdiodev, SBSDIO_SPROM_ADDR_HIGH, 0xf,
+					  &ret);
+			brcmf_sdiod_regwb(sdiodev, SBSDIO_CHIP_CTRL_DATA, 0,
+					  &ret);
+			brcmf_sdiod_regwb(sdiodev, SBSDIO_CHIP_CTRL_EN, 0x2,
+					  &ret);
+		}
+
 		/* must configure SDIO_CCCR_IENx to enable irq */
 		data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
 		data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;