On Thu, 26 Apr 2012 16:51:10 -0700 Steve Sakoman <sakoman@xxxxxxxxx> wrote: > On Mon, Dec 19, 2011 at 1:10 AM, Ohad Ben-Cohen <ohad@xxxxxxxxxx> wrote: > > > We're slowly progressing towards understanding the issues we have with > > the 8686 (it seems there are a few different hw revisions of it, some > > of which do require toggling the reset pin before sending another init > > sequence), but it might take some more time until a solution fully > > materializes. > > > > Since 3.2 is just around the corner, I suggest we should now proceed > > with the revert (see patch below), and later revisit this once we have > > a complete solution in hand. > > Has any progress been made on this issue? > > I too have been trying to power down/up the wifi module on the Overo. > I'm seeing the same issue described in this thread. > > Some additional data: > > I rebuilt my kernel (3.2) with a CD GPIO enabled for the mmc port the module > is connected to and in turn connected that GPIO to another one that I > can toggle from user space. > > Toggling the CD GPIO after powering back up the module does indeed > work properly -- the module is detected, the driver loaded, and proper function > restored. > > So basically the procedure I've used is: > > - decide wifi can be powered down > - unload the libertas modules > - put the wifi hw in reset with gpio16 > - wait till wifi is needed again > - take the chip out of reset > - toggle the CD gpio > - libertas modules are autoloaded, as is the firmware > - wifi is up and functioning > > So the next step is to get rid of the silly two GPIO external hardware > hack. Is it possible to trigger a card insertion/removal event via > some standard API? > > Or does the above information provide a clue as to why normal code > paths don't work? > > Any other ideas? I thought I had a nicely working solution, but I recently discovered that it doesn't work as well as I thought it did. I now think we need some help from the mmc layer to get it really working. My understanding of the underlying problem is that the wifi chip can get into a state where it really needs a hardware reset, but it isn't given one. Applying the reset at the right time is needed. When the mmc layer wants to power-up the device, it tells the configured regulator to turn on, then sends some standard command sequence. If the regulator was actually off, this works (I think - it is a while since I experimented). However if the regulator wasn't actually off, it doesn't work - the wifi chip gets confused by getting the init sequence when it is already inited, and fails to continue. So pulsing the resent line low after turning on the power is necessary and sufficient. In my case, the regulator is shared by the bluetooth and the wifi so if bluetooth is on while the wifi is off the regulator never gets turned off, and so bad things happen when we try to turn the wifi back on. I had worked around this by defining a separate 'fixed' regulator to power the wifi chip. It declared the real regulator as the 'supply' regulator so that when the mmc driver turns on this pseudo regulator, the real one gets turned on too. The 'fixed' regulator can drive a gpio and I configured it to drive the wifi reset line. So when the regulator was turned off, the wifi was held in reset. When the regulator was turned back on, the reset was release, the power was on, and it all worked beautifully. But there are two problems with this: 1/ the reset line is also shared with the bluetooth :-( so I cannot hold it down. It is safe to pulse it down, but the 'fixed' regulator won't do that (without a bit of hacking) 2/ When the voltage is set for the 'fixed' regulator, it is not propagated back to the real regulator, so the real regulator's voltage doesn't get set properly to make the requirements of the wifi chip. I can work around the first problem by hacking the 'fixed' regulator, but I wouldn't expect that hack to go upstream. I can work around the second by observing the hsmmc enables 2 regulators if they are defined: vmmc and vmmc_aux So I configure the real regulator as vmmc, which gets the voltage setting, and configure the pseudo regulator as vmmc_aux. This gets powered on after vmmc, so the reset happens at the right time. But I think all this is really just hacking around the problem. I think we need for omap_hsmmc.c to be able to accept a 'reset_gpio' config, and to toggle that after power-on. It is unfortunate to have to include functionality for one particular device in common code like this, but I really cannot see any other way. BTW I explicitly set MMC_CAP_POWER_OFF so I don't need any card detect enabled and there is no need to rmmod the device. A simple "ifconfig wlan0 down" will power off the wifi chip, and "ifconfig wlan0 up" will power it on again. NeilBrown
Attachment:
signature.asc
Description: PGP signature