linux-i2c.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Power up/down of an I2C client?
@ 2010-11-16  4:44 Bill Gatliff
       [not found] ` <AANLkTinjBBxiq4K6wn8raOgooKtBhF3sW-k2FUSWNDzY-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 2+ messages in thread
From: Bill Gatliff @ 2010-11-16  4:44 UTC (permalink / raw)
  To: linux-i2c-u79uwXL29TY76Z2rM5mHXA

Guys:


I have several boards that can control the power supply to their i2c
chips, and I need to power down/up those chips when the boards go
through suspend/resume.  The problem is, I'm using the same chip on
all of the boards but the mechanism for controlling the power supply
to each one is different on each board.

For platform devices, I deal with the above problem by declaring a
board-specific, "parent" device that gets the suspend/resume events
after/before the actual chip driver does.  I fiddle with the power
supplies in those parent suspend/resume methods.  Something like this:

static int parent_probe(struct platform_device *this)
{
       platform_device_register_data(&this->dev, "child", -1, NULL, 0);
       return 0;
}

static int parent_suspend(struct device *this)
{
     /* power down the child device--- it has already been suspended */
     gpio_direction_output(..., 0);
     return 0;
}

static int parent_resume(struct device *this)
{
     /* power up the child device--- it will get resumed after we return */
     gpio_direction_output(..., 1);
     return 0;
}

static struct dev_pm_ops parent_pm_ops = {
       .suspend = parent_suspend,
       .resume = parent_resume,
};

static struct platform_driver parent_driver = {
       .probe = parent_probe,
       .driver = {
               .name = "parent",
               .pm = &parent_pm_ops,
               .owner = THIS_MODULE,
       },
};

...

     platform_device_register_simple("parent", -1, NULL, 0);


The above code may seem complicated, but it lets me completely
separate the power mechanism from the rest of the driver.  As such, it
gives me the freedom to completely change how power is managed to the
chip on a given board, without having to edit--- or even recompile---
chip driver code itself.  I write the chip driver code once, and it
stays written forever!

Trouble is, I can't come up with an equivalent approach for i2c
devices.  The i2c system uses both parents and buses itself, leaving
me without a convenient hook for catching events.  Is there no way to
"wrap" i2c devices the way you can for platform devices?

Reparenting the i2c adapter itself seems like the only alternative
here, and I might be able to live with that--- but it becomes a bit of
a nightmare when each chip on the bus is configurable as to whether it
will be a wakeup source (and therefore shouldn't be powered down), or
not.  That means I have to find and walk the device list to see who
needs to stay powered up, and who gets put to sleep...

I can't help but think that I'm missing something that would let me
have i2c chip-specific power controllers like I have for my platform
devices.  Any suggestions here would be greatly appreciated.

Thanks!


b.g.
-- 
Bill Gatliff
bgat-uPd5UNENI//N9NzbbXoYwQ@public.gmane.org

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Power up/down of an I2C client?
       [not found] ` <AANLkTinjBBxiq4K6wn8raOgooKtBhF3sW-k2FUSWNDzY-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2010-11-16 12:51   ` Mark Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2010-11-16 12:51 UTC (permalink / raw)
  To: Bill Gatliff; +Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Igor Grinberg

On Mon, Nov 15, 2010 at 08:44:10PM -0800, Bill Gatliff wrote:

> I have several boards that can control the power supply to their i2c
> chips, and I need to power down/up those chips when the boards go
> through suspend/resume.  The problem is, I'm using the same chip on
> all of the boards but the mechanism for controlling the power supply
> to each one is different on each board.

The current way of doing this is to abstract away via the regulator API,
though that doesn't cover reset GPIOs.

> Trouble is, I can't come up with an equivalent approach for i2c
> devices.  The i2c system uses both parents and buses itself, leaving
> me without a convenient hook for catching events.  Is there no way to
> "wrap" i2c devices the way you can for platform devices?

I'm working on an approach to this based on using notifiers.  Currently
we have notifiers from the driver model for driver probe, and we have
system-wide notifiers for PM events (but no per device stuff so runtime
PM can't be supported yet).  Not sure when I'll have something to show
but the idea is that you enable the device on BUS_NOTIFY_BIND_DRIVER,
disable it on BUS_NOTIFY_UNBOUND_DRIVER and do similar things on some
future notifiers for per-device suspend and resume.

This should work for all buses without any per-bus or per-device
modifications.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-11-16 12:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-16  4:44 Power up/down of an I2C client? Bill Gatliff
     [not found] ` <AANLkTinjBBxiq4K6wn8raOgooKtBhF3sW-k2FUSWNDzY-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-11-16 12:51   ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).