public inbox for linux-i2c@vger.kernel.org
 help / color / mirror / Atom feed
From: David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
To: eric miao <eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: Jack Ren <jack.ren-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>,
	i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org,
	linux-arm-kernel
	<linux-arm-kernel-xIg/pKzrS19vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
Subject: Re: [PATCH] gpio: max732x: add support for MAX7319, MAX7320-7327 I2C Port Expanders
Date: Fri, 11 Jul 2008 14:25:00 -0700	[thread overview]
Message-ID: <200807111425.00961.david-b@pacbell.net> (raw)
In-Reply-To: <f17812d70807110248y7fab3328q59ea41084c491df-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Friday 11 July 2008, eric miao wrote:
> patch updated:
> 
> >From 18d910f69c5408340661326f1ad1bcbb2c5bc6f6 Mon Sep 17 00:00:00 2001
> From: Eric Miao <eric.miao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
> Date: Thu, 10 Jul 2008 13:37:59 +0800
> Subject: [PATCH] gpio: max732x: add support for MAX7319, MAX7320-7327
> I2C Port Expanders
> 
> Signed-off-by: Jack Ren <jack.ren-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Eric Miao <eric.miao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/gpio/Kconfig        |   22 +++
>  drivers/gpio/Makefile       |    1 +
>  drivers/gpio/max732x.c      |  361 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/i2c/max732x.h |   19 +++
>  4 files changed, 403 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/gpio/max732x.c
>  create mode 100644 include/linux/i2c/max732x.h
> 
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -61,6 +61,28 @@ config GPIO_PCF857X
>  	  This driver provides an in-kernel interface to those GPIOs using
>  	  platform-neutral GPIO calls.
> 
> +config GPIO_MAX732X
> +	tristate "MAX7319, MAX7320-7327 8/16-bit I2C Port Expanders"

"MAX" should still precede "PCF" in the Kconfig.
As it says:  put drivers in the right section,
and in alphabetical order.


> --- /dev/null
> +++ b/drivers/gpio/max732x.c
> @@ -0,0 +1,361 @@
> ...
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/slab.h>
> +#include <linux/i2c.h>
> +#include <linux/i2c/max732x.h>
> +
> +#include <asm/gpio.h>

For consistency, make that <linux/gpio.h> and put it up above.
I like to see blank lines delineating groups, like <linux/*>
and <linux/i2c/*>, too.


> + * Within each group of ports, there are five known combinations of
> + * I/O ports: 4I4O, 4P4O, 8I, 8P, 8O, see the definitions below for
> + * the detailed organization of these ports.

Quirky little buggers, they are!!


> + * NOTE: MAX7328/MAX7329, however, resembles much closer to PCF8574,
> + * they are not supported by this driver.

In fact the data sheet for those parts says they're second sources
for those PCF chips.  Feel free to submit a patch updating Kconfig
and the pcf857x driver accordingly ... :)


> +static int max732x_gpio_get_value(struct gpio_chip *gc, unsigned off)
> +{
> +	struct max732x_chip *chip;
> +	uint8_t reg_val;
> +	int ret;
> +
> +	chip = container_of(gc, struct max732x_chip, gpio_chip);
> +
> +	ret = max732x_read(chip, is_group_a(chip, off), &reg_val);
> +	if (ret < 0)
> +		return 0;
> +
> +	return (reg_val & (1u << (off & 0x7))) ? 1 : 0;

Simpler:  "reg_val & (the_mask)".  The values here are
zero/nonzero, not zero/one/undefined.


> +static void max732x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
> +{ 
> +       struct max732x_chip *chip;
> +       uint8_t reg_out, mask = 1u << (off & 0x7);
> +       int ret;
> +
> +       chip = container_of(gc, struct max732x_chip, gpio_chip);
> +
> +       reg_out = (off > 7) ? chip->reg_out[1] : chip->reg_out[0];
> +       reg_out = (val) ? reg_out | mask : reg_out & ~mask;

You should have some kind of locking to protect chip->reg_out[].
Hmm, I notice the pcf857x driver doesn't ... sigh.

I can't quite see a way around a mutex or rwlock.  The set_bit()
clear_bit() calls would atomic, but you need the assignment to be
atomic at the I2C chip, not just on the host side.


> +
> +       ret = max732x_write(chip, is_group_a(chip, off), reg_out);
> +       if (ret < 0)
> +               return;
> +
> +       /* update the shadow register then */
> +       if (off > 7)
> +               chip->reg_out[1] = reg_out;
> +       else
> +               chip->reg_out[0] = reg_out;
> +}

Notice how two tasks setting direction for different GPIOs will
both feel free to clobber the cached chip->reg_out[] value ...


> +
> +	if ((mask & chip->dir_input) == 0)
> +		pr_warning("%s: port %d is output only\n", __func__, off);

First problem:  if it's an output-only signal, you should return a
negative errno to anyone trying to use it as an input.  (Likewise
for the converse, trying to set an output-only pin as an input.)
EACCES would seem appropriate; it's what open(2) returns when you
try to write a read-only file, and these modes can't be written.

Seocnd:  you shouldn't use pr_*() calls when there's a relevant
driver model node.  Of course, in this case once you properly
return a fault code, this merits at most a dev_dbg() call, since
the caller can be expected to handle such errors somehow.


> +static int __devinit max732x_probe(struct i2c_client *client,
> +				   const struct i2c_device_id *id)
> +{
> +	struct max732x_platform_data *pdata;
> +	struct max732x_chip *chip;
> +	int ret;
> +
> +	pdata = client->dev.platform_data;
> +	if (pdata == NULL)
> +		return -ENODEV;
> +
> +	chip = kzalloc(sizeof(struct max732x_chip), GFP_KERNEL);
> +	if (chip == NULL)
> +		return -ENOMEM;
> +
> +	chip->client[0] = client;
> +
> +	switch (client->addr & 0x70) {
> +	case 0x60:
> +		chip->client[1] = i2c_new_dummy(client->adapter,
> +					(client->addr & 0x0f) | 0x50);
> +		chip->client_group_a = chip->client[0];
> +		chip->client_group_b = chip->client[1];
> +		break;
> +	case 0x50:
> +		chip->client[1] = i2c_new_dummy(client->adapter,
> +					(client->addr & 0x0f) | 0x60);
> +		chip->client_group_a = chip->client[1];
> +		chip->client_group_b = chip->client[0];
> +		break;

Why not just insist the 0x5x address be registered/probed?  This
extra stuff is needless and confusing.


_______________________________________________
i2c mailing list
i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org
http://lists.lm-sensors.org/mailman/listinfo/i2c

  parent reply	other threads:[~2008-07-11 21:25 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-10  6:13 [PATCH] gpio: max732x: add support for MAX7319, MAX7320-7327 I2C Port Expanders Eric Miao
     [not found] ` <4875A893.3090402-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2008-07-11  8:29   ` Jean Delvare
     [not found]     ` <20080711102952.31d2d943-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-07-11  8:57       ` eric miao
     [not found]         ` <f17812d70807110157p5e421222sc9ef420ceb80970c-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-07-11  9:31           ` Jean Delvare
     [not found]             ` <20080711113114.79d80212-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-07-11  9:39               ` eric miao
     [not found]                 ` <f17812d70807110239q6c175f5cn70db966681ae387d-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-07-11  9:48                   ` eric miao
     [not found]                     ` <f17812d70807110248y7fab3328q59ea41084c491df-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-07-11 11:15                       ` Jean Delvare
2008-07-11 21:25                       ` David Brownell [this message]
     [not found]                         ` <200807111425.00961.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-07-12  7:16                           ` Jean Delvare
     [not found]                             ` <20080712091610.4ec242c3-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-07-12  7:46                               ` David Brownell
     [not found]                                 ` <200807120046.29389.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-07-12  7:53                                   ` Jean Delvare
     [not found]                                     ` <20080712095300.1ba4b3a7-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-07-12 21:42                                       ` David Brownell
2008-07-13  6:55                                         ` Jean Delvare
2008-07-13  6:04                                   ` eric miao
     [not found]                                     ` <f17812d70807122304o533d8af9k1384db653b264912-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-07-13  7:20                                       ` Jean Delvare
     [not found]                                         ` <20080713092050.6dffd8d3-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-07-13  8:53                                           ` eric miao
     [not found]                                             ` <f17812d70807130153g290e17ecq10ab12529effc8d4-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-07-13  9:13                                               ` Jean Delvare
     [not found]                                                 ` <20080713111306.791bbc41-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-07-13 13:45                                                   ` eric miao
     [not found]                                                     ` <f17812d70807130645i755c1c62la30d5c515c2d2080-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-07-13 19:18                                                       ` David Brownell
     [not found]                                                         ` <200807131218.29575.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-07-14  1:35                                                           ` Eric Miao
2008-07-13  9:12                                           ` David Brownell
     [not found]                                             ` <20080713091236.015E920ABDD-ZcXrCSuhvln6VZ3dlLfH/g4gEjPzgfUyLrfjE7I9kuVHxeISYlDBzl6hYfS7NtTn@public.gmane.org>
2008-07-13  9:18                                               ` Jean Delvare
2008-07-13 14:37                                       ` Jean Delvare
2008-07-11  9:54                   ` Jean Delvare
     [not found]                     ` <20080711115436.22134ce7-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-07-11 10:04                       ` eric miao

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=200807111425.00961.david-b@pacbell.net \
    --to=david-b-ybekhbn/0ldr7s880joybq@public.gmane.org \
    --cc=eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org \
    --cc=jack.ren-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org \
    --cc=linux-arm-kernel-xIg/pKzrS19vn6HldHNs0ANdhmdF6hFW@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