From: David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
To: eric miao <eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
Guennadi Liakhovetski
<g.liakhovetski-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Cc: video4linux-list-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
Subject: Re: [RFC PATCH 3/8] Add PCA9536 4 bit I2C GPIO extender support to the pca9539 GPIO driver
Date: Wed, 30 Jan 2008 20:52:03 -0800 [thread overview]
Message-ID: <200801302052.04336.david-b@pacbell.net> (raw)
In-Reply-To: <f17812d70801301731n62597f12kc151d01c320e3dec-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wednesday 30 January 2008, eric miao wrote:
> I like this patch, overall looks ok. See my comments below.
I basically like it, but I'd still like to see some changes. :)
I'd split this patch into two parts (feature addition, and renaming),
and use simpler chip type handling. Re that latter, in 2.6.26 there
will be an i2c_device_id struct:
struct i2c_device_id {
char name[I2C_NAME_SIZE];
kernel_ulong_t driver_data; /* Data private to the driver */
};
A little planning done now will make it easy to use that scheme.
First, don't add a type field to the platform_data; that's what
the i2c_client.name is for. Then just map those strings to the
number of GPIOs (eventually just use driver_data), and everything
else follows from there.
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -27,15 +27,15 @@ config DEBUG_GPIO
> >
> > comment "I2C GPIO expanders:"
> >
> > -config GPIO_PCA9539
> > - tristate "PCA9539 16-bit I/O port"
> > +config GPIO_PCA953X
> > + tristate "PCA953X I/O port"
"Ports"
> > depends on I2C
> > help
> > - Say yes here to support the PCA9539 16-bit I/O port. These
> > - parts are made by NXP and TI.
> > + Say yes here to support PCA9539 16-bit and PCA9536 4-bit I/O ports.
This should IMO list the '38 (8-bit) and '37 (4-bit) parts too.
Same register layout as the '36 (4-bit). Otherwise the "x" seems
misleading...
> > diff --git a/drivers/gpio/pca9539.c b/drivers/gpio/pca953x.c
> > similarity index 67%
> > rename from drivers/gpio/pca9539.c
> > rename to drivers/gpio/pca953x.c
I'd prefer to see the new feature and the renaming be separate patches.
> > -#define NR_PCA9539_GPIOS 16
> > +struct pca953x_desc {
> > + unsigned int gpios;
> > + unsigned int input;
> > + unsigned int output;
> > + unsigned int invert;
> > + unsigned int direction;
> > +};
>
> I guess the register address can be inferred either from the number
> of GPIOs or a single member field of "shift" may be sufficient.
Yes, inferring that would be simpler. The number of GPIOs is a
function of the particular chip, and register offsets are 0/1/2/3
except for the 16-GPIO part where they're twice that.
What I'd do is save those four offsets directly in pca953x_chip,
initialized near when gpio_chip.ngpio is set up and with no need
for a separate "desc" type or table. Eventually there'd be:
struct i2c_device_id chips [] = {
{ "pca9536", 4, },
{ "pca9537", 4, },
{ "pca9538", 8, },
{ "pca9539", 16, },
};
MODULE_DEVICE_TABLE(i2c, chips);
Meanwhile, the equivalent of that table can come from a few strcmp()
tests in the probe() logic -- like what you already have, except
not using a "desc" type.
> > -static int pca9539_init_gpio(struct pca9539_chip *chip)
> > +static int pca953x_init_gpio(struct pca953x_chip *chip)
> > {
> > struct gpio_chip *gc;
> >
> > gc = &chip->gpio_chip;
> >
> > - gc->direction_input = pca9539_gpio_direction_input;
> > - gc->direction_output = pca9539_gpio_direction_output;
> > - gc->get = pca9539_gpio_get_value;
> > - gc->set = pca9539_gpio_set_value;
> > + gc->direction_input = pca953x_gpio_direction_input;
> > + gc->direction_output = pca953x_gpio_direction_output;
> > + gc->get = pca953x_gpio_get_value;
> > + gc->set = pca953x_gpio_set_value;
> >
> > gc->base = chip->gpio_start;
> > - gc->ngpio = NR_PCA9539_GPIOS;
> > - gc->label = "pca9539";
> > + gc->ngpio = chip->desc->gpios;
I'd expect "desc" to vanish, and ngpio to be an input to this function
(see below). Then ngpio could be used to choose the values to stuff
into chip->{input,output,invert,direction} register offsets.
> > + gc->label = "pca953x";
Why not just set gc->label to be chip->client->name?
Might as well have /sys/kernel/debug/gpio output be
that little bit more useful. And save the space that
would otherwise be wasted by that string. :)
> >
> > return gpiochip_add(gc);
> > }
> >
> > -static int __devinit pca9539_probe(struct i2c_client *client)
> > +static int __devinit pca953x_probe(struct i2c_client *client)
> > {
> > - struct pca9539_platform_data *pdata;
> > - struct pca9539_chip *chip;
> > + struct pca953x_platform_data *pdata;
> > + struct pca953x_chip *chip;
> > int ret;
> > + int variant;
> >
> > pdata = client->dev.platform_data;
> > if (pdata == NULL)
> > return -ENODEV;
> >
> > - chip = kzalloc(sizeof(struct pca9539_chip), GFP_KERNEL);
> > + if (!strcmp("pca9539", pdata->name))
Use client->name instead; there's no need to change pdata.
> > + variant = PCA9539;
> > + else if (!strcmp("pca9536", pdata->name))
> > + variant = PCA9536;
> > + else
> > + return -ENODEV;
> > +
>
> I prefer integer here more than string, for simplicity and efficiency.
Actually I'd use strings right now, and not change pdata at all. But
compare client->name, using that to figure out how many GPIOs.
When, later, an i2c_device_id is passed in, the driver can get the
number of GPIOs handed to it directly ... and won't need to worry
about that ENODEV case.
> > --- a/include/asm-generic/gpio.h
> > +++ b/include/asm-generic/gpio.h
> > @@ -16,6 +16,10 @@
> > #define ARCH_NR_GPIOS 256
> > #endif
> >
> > +#ifndef NO_GPIO
> > +#define NO_GPIO ((unsigned int)-1)
> > +#endif
> > +
>
> I don't understand this.
Me either; *ANY* negative number is invalid as a GPIO number,
not just "-1"...
> > --- a/include/linux/i2c/pca9539.h
> > +++ b/include/linux/i2c/pca953x.h
> > @@ -1,9 +1,12 @@
> > -/* platform data for the PCA9539 16-bit I/O expander driver */
> > +/* platform data for the PCA953x I/O expander driver */
> >
> > -struct pca9539_platform_data {
> > +struct pca953x_platform_data {
> > /* number of the first GPIO */
> > unsigned gpio_base;
> >
> > + /* chip variant. Currently supported "pca9536" and "pca9539" */
> > + const char *name;
> > +
That's not needed; i2c_client.name should identify the chip.
> > /* initial polarity inversion setting */
> > uint16_t invert;
> >
> >
_______________________________________________
i2c mailing list
i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
http://lists.lm-sensors.org/mailman/listinfo/i2c
next prev parent reply other threads:[~2008-01-31 4:52 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <Pine.LNX.4.64.0801231646090.4932@axis700.grange>
2008-01-23 17:41 ` [RFC PATCH 3/8] Philips PCA9536 4 bit I2C GPIO extender driver Guennadi Liakhovetski
[not found] ` <Pine.LNX.4.64.0801231820060.4932-0199iw4Nj15frtckUFj5Ag@public.gmane.org>
2008-01-27 21:45 ` Jean Delvare
2008-01-27 22:27 ` [i2c] " Guennadi Liakhovetski
[not found] ` <20080127224559.4eed7cea-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-01-28 6:18 ` David Brownell
2008-01-30 16:48 ` [i2c] [RFC PATCH 3/8] Add PCA9536 4 bit I2C GPIO extender support to the pca9539 GPIO driver Guennadi Liakhovetski
2008-01-31 1:31 ` eric miao
[not found] ` <f17812d70801301731n62597f12kc151d01c320e3dec-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-01-31 4:52 ` David Brownell [this message]
2008-01-31 10:13 ` Guennadi Liakhovetski
[not found] ` <Pine.LNX.4.64.0801311025210.6494-0199iw4Nj15frtckUFj5Ag@public.gmane.org>
2008-01-31 10:48 ` David Brownell
2008-01-31 11:30 ` [i2c] " Guennadi Liakhovetski
[not found] ` <Pine.LNX.4.64.0801311204280.6494-0199iw4Nj15frtckUFj5Ag@public.gmane.org>
2008-01-31 11:46 ` David Brownell
2008-01-31 11:49 ` David Brownell
2008-01-31 13:30 ` [i2c] " Guennadi Liakhovetski
[not found] ` <Pine.LNX.4.64.0801311425300.6494-0199iw4Nj15frtckUFj5Ag@public.gmane.org>
2008-01-31 23:56 ` David Brownell
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=200801302052.04336.david-b@pacbell.net \
--to=david-b-ybekhbn/0ldr7s880joybq@public.gmane.org \
--cc=eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=g.liakhovetski-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org \
--cc=i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org \
--cc=video4linux-list-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox