[SPAM:4.2] [spam] D.entists Listing for the USA

2008-07-09 Thread Kris Berger





Just Released: for the United States

++ 164,259 Dent ists 
++ 158,870 Mailing Addresses
++ 163,212 Office phone Numbers
++ 77,886 Faxes
++ 45,335 Emails

Up to Jul 11 the price has been reduced to $297, you save $200!

For details please send an email to [EMAIL PROTECTED] 




Forward email with 1751 in the sub to purge from our records

___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c


[i2c] [patch 0/2] S3C24XX Updates for post 2.6.26

2008-07-09 Thread Ben Dooks
I2C updates for merging once 2.6.26 is out.

-- 
Ben

___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c


[i2c] [patch 1/2] I2C: S3C2410: Pass the I2C bus number via drivers platform data

2008-07-09 Thread Ben Dooks
Allow the platform data to specify the bus bumber that the
new I2C bus will be given. This is to allow the use of the
board registration mechanism to specify the new style of
I2C device registration which allows boards to provide a
list of attached devices.

Note, as discussed on the mailing list, we have dropped
backwards compatibility of adding an dynamic bus number
as it should not affect most boards to have the bus pinned
to 0 if they have either not specified platform data for
driver. Any board supplying platform data will automatically
have the bus_num field set to 0, and anyone who needs the
driver on a different bus number can supply platform data
to set bus_num.

Signed-off-by: Ben Dooks <[EMAIL PROTECTED]>

Index: linux-2.6.26-rc4-quilt3/drivers/i2c/busses/i2c-s3c2410.c
===
--- linux-2.6.26-rc4-quilt3.orig/drivers/i2c/busses/i2c-s3c2410.c   
2008-06-02 22:55:20.0 +0100
+++ linux-2.6.26-rc4-quilt3/drivers/i2c/busses/i2c-s3c2410.c2008-06-02 
22:55:29.0 +0100
@@ -752,9 +752,12 @@ static int s3c24xx_i2c_init(struct s3c24
 static int s3c24xx_i2c_probe(struct platform_device *pdev)
 {
struct s3c24xx_i2c *i2c = &s3c24xx_i2c;
+   struct s3c2410_platform_i2c *pdata;
struct resource *res;
int ret;
 
+   pdata = s3c24xx_i2c_get_platformdata(&pdev->dev);
+
/* find the clock and enable it */
 
i2c->dev = &pdev->dev;
@@ -832,7 +835,15 @@ static int s3c24xx_i2c_probe(struct plat
dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res,
(unsigned long)res->start);
 
-   ret = i2c_add_adapter(&i2c->adap);
+   /* Note, previous versions of the driver used i2c_add_adapter()
+* to add an bus at any number. We now pass the bus number via
+* the platform data, so if unset it will now default to always
+* being bus 0.
+*/
+
+   i2c->adap.nr = pdata->bus_num;
+   ret = i2c_add_numbered_adapter(&i2c->adap);
+
if (ret < 0) {
dev_err(&pdev->dev, "failed to add bus to i2c core\n");
goto err_irq;
Index: linux-2.6.26-rc4-quilt3/include/asm-arm/plat-s3c/iic.h
===
--- linux-2.6.26-rc4-quilt3.orig/include/asm-arm/plat-s3c/iic.h 2008-06-02 
20:12:47.0 +0100
+++ linux-2.6.26-rc4-quilt3/include/asm-arm/plat-s3c/iic.h  2008-06-02 
22:55:29.0 +0100
@@ -21,6 +21,7 @@
 */
 
 struct s3c2410_platform_i2c {
+   int bus_num;/* bus number to use */
unsigned intflags;
unsigned intslave_addr; /* slave address for controller */
unsigned long   bus_freq;   /* standard bus frequency */

-- 

___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c


[i2c] [patch 2/2] I2C: S3C24XX I2C frequency scaling support.

2008-07-09 Thread Ben Dooks
Add support for CPU frequency scaling to the S3C24XX I2C driver.

Signed-off-by: Ben Dooks <[EMAIL PROTECTED]>

Index: linux-2.6.26-rc9/drivers/i2c/busses/i2c-s3c2410.c
===
--- linux-2.6.26-rc9.orig/drivers/i2c/busses/i2c-s3c2410.c  2008-07-09 
13:46:08.0 +0100
+++ linux-2.6.26-rc9/drivers/i2c/busses/i2c-s3c2410.c   2008-07-09 
13:48:46.0 +0100
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -64,6 +65,7 @@ struct s3c24xx_i2c {
unsigned inttx_setup;
 
enum s3c24xx_i2c_state  state;
+   unsigned long   clkrate;
 
void __iomem*regs;
struct clk  *clk;
@@ -71,6 +73,10 @@ struct s3c24xx_i2c {
struct resource *irq;
struct resource *ioarea;
struct i2c_adapter  adap;
+
+#ifdef CONFIG_CPU_FREQ
+   struct notifier_block   freq_transition;
+#endif
 };
 
 /* default platform data to use if not supplied in the platform_device
@@ -501,6 +507,9 @@ static int s3c24xx_i2c_doxfer(struct s3c
unsigned long timeout;
int ret;
 
+   if (!readl(i2c->regs + S3C2410_IICCON) & S3C2410_IICCON_IRQEN)
+   return -EIO;
+
ret = s3c24xx_i2c_set_master(i2c);
if (ret != 0) {
dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
@@ -636,27 +645,28 @@ static inline int freq_acceptable(unsign
return (diff >= -2 && diff <= 2);
 }
 
-/* s3c24xx_i2c_getdivisor
+/* s3c24xx_i2c_clockrate
  *
  * work out a divisor for the user requested frequency setting,
  * either by the requested frequency, or scanning the acceptable
  * range of frequencies until something is found
 */
 
-static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c,
- struct s3c2410_platform_i2c *pdata,
- unsigned long *iicon,
- unsigned int *got)
+static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
 {
+   struct s3c2410_platform_i2c *pdata;
unsigned long clkin = clk_get_rate(i2c->clk);
-   
unsigned int divs, div1;
+   u32 iiccon;
int freq;
int start, end;
 
+   i2c->clkrate = clkin;
+
+   pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent);
clkin /= 1000;  /* clkin now in KHz */
  
-   dev_dbg(i2c->dev,  "pdata %p, freq %lu %lu..%lu\n",
+   dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
 pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq);
 
if (pdata->bus_freq != 0) {
@@ -688,11 +698,79 @@ static int s3c24xx_i2c_getdivisor(struct
 
  found:
*got = freq;
-   *iicon |= (divs-1);
-   *iicon |= (div1 == 512) ? S3C2410_IICCON_TXDIV_512 : 0;
+
+   iiccon = readl(i2c->regs + S3C2410_IICCON);
+   iiccon &= ~(S3C2410_IICCON_SCALEMASK | S3C2410_IICCON_TXDIV_512);
+   iiccon |= (divs-1);
+
+   if (div1 == 512)
+   iiccon |= S3C2410_IICCON_TXDIV_512;
+
+   writel(iiccon, i2c->regs + S3C2410_IICCON);
+
+   return 0;
+}
+
+#ifdef CONFIG_CPU_FREQ
+
+#define freq_to_i2c(_n) container_of(_n, struct s3c24xx_i2c, freq_transition)
+
+static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+   struct s3c24xx_i2c *i2c = freq_to_i2c(nb);
+   unsigned long clkrate;
+   unsigned long flags;
+   unsigned int got;
+   int ret;
+
+   clkrate = clk_get_rate(i2c->clk);
+
+   /* if we're post-change and the input clock has slowed down
+* or at pre-change and the clock is about to speed up, then
+* adjust our clock rate.
+*/
+
+   if ((val == CPUFREQ_POSTCHANGE && clkrate < i2c->clkrate) ||
+   (val == CPUFREQ_PRECHANGE && clkrate > i2c->clkrate)) {
+   spin_lock_irqsave(&i2c->lock, flags);
+   ret = s3c24xx_i2c_clockrate(i2c, &got);
+   spin_unlock_irqrestore(&i2c->lock, flags);
+
+   if (ret < 0)
+   dev_err(i2c->dev, "cannot find frequency\n");
+   else
+   dev_info(i2c->dev, "setting freq %d\n", got);
+   }
+
return 0;
 }
 
+static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
+{
+   i2c->freq_transition.notifier_call = s3c24xx_i2c_cpufreq_transition;
+
+   return cpufreq_register_notifier(&i2c->freq_transition,
+CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void s3c24xx_i2c_deregister_cpufreq(struct s3c24xx_i2c *i2c)
+{
+   cpufreq_unregister_notifier(&i2c->freq_transition,
+   CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+#else
+static inline int s3c24xx_i2c_register_cpufreq(struct s3c24xx_i2c *i2c)
+{
+   return 0;
+}
+
+static inline v

Re: [i2c] [patch 1/2] I2C: S3C2410: Pass the I2C bus number via drivers platform data

2008-07-09 Thread Jean Delvare
Hi Ben,

On Wed, 09 Jul 2008 13:51:48 +0100, Ben Dooks wrote:
> Allow the platform data to specify the bus bumber that the
> new I2C bus will be given. This is to allow the use of the
> board registration mechanism to specify the new style of
> I2C device registration which allows boards to provide a
> list of attached devices.
> 
> Note, as discussed on the mailing list, we have dropped
> backwards compatibility of adding an dynamic bus number
> as it should not affect most boards to have the bus pinned
> to 0 if they have either not specified platform data for

either?

> driver. Any board supplying platform data will automatically
> have the bus_num field set to 0, and anyone who needs the
> driver on a different bus number can supply platform data
> to set bus_num.

Sounds OK to me.

> 
> Signed-off-by: Ben Dooks <[EMAIL PROTECTED]>
> 
> Index: linux-2.6.26-rc4-quilt3/drivers/i2c/busses/i2c-s3c2410.c
> ===
> --- linux-2.6.26-rc4-quilt3.orig/drivers/i2c/busses/i2c-s3c2410.c 
> 2008-06-02 22:55:20.0 +0100
> +++ linux-2.6.26-rc4-quilt3/drivers/i2c/busses/i2c-s3c2410.c  2008-06-02 
> 22:55:29.0 +0100
> @@ -752,9 +752,12 @@ static int s3c24xx_i2c_init(struct s3c24
>  static int s3c24xx_i2c_probe(struct platform_device *pdev)
>  {
>   struct s3c24xx_i2c *i2c = &s3c24xx_i2c;
> + struct s3c2410_platform_i2c *pdata;
>   struct resource *res;
>   int ret;
>  
> + pdata = s3c24xx_i2c_get_platformdata(&pdev->dev);
> +
>   /* find the clock and enable it */
>  
>   i2c->dev = &pdev->dev;
> @@ -832,7 +835,15 @@ static int s3c24xx_i2c_probe(struct plat
>   dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res,
>   (unsigned long)res->start);
>  
> - ret = i2c_add_adapter(&i2c->adap);
> + /* Note, previous versions of the driver used i2c_add_adapter()
> +  * to add an bus at any number. We now pass the bus number via

"an bus" doesn't look correct.

> +  * the platform data, so if unset it will now default to always
> +  * being bus 0.
> +  */
> +
> + i2c->adap.nr = pdata->bus_num;
> + ret = i2c_add_numbered_adapter(&i2c->adap);
> +
>   if (ret < 0) {

Best practice is to not have a blank line between a function call and
the test of its return value.

>   dev_err(&pdev->dev, "failed to add bus to i2c core\n");
>   goto err_irq;
> Index: linux-2.6.26-rc4-quilt3/include/asm-arm/plat-s3c/iic.h
> ===
> --- linux-2.6.26-rc4-quilt3.orig/include/asm-arm/plat-s3c/iic.h   
> 2008-06-02 20:12:47.0 +0100
> +++ linux-2.6.26-rc4-quilt3/include/asm-arm/plat-s3c/iic.h2008-06-02 
> 22:55:29.0 +0100
> @@ -21,6 +21,7 @@
>  */
>  
>  struct s3c2410_platform_i2c {
> + int bus_num;/* bus number to use */
>   unsigned intflags;
>   unsigned intslave_addr; /* slave address for controller */
>   unsigned long   bus_freq;   /* standard bus frequency */
> 

Other than these details, the patch looks OK to me.

-- 
Jean Delvare

___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c


Re: [i2c] [PATCH 1/1] I2C pxa fast mode (400khz) support

2008-07-09 Thread Jean Delvare
On Wed, 02 Jul 2008 16:26:40 +0100, Jonathan Cameron wrote:
> Add fast_mode option to i2c_pxa_platform_data and use it to set the ICR_FM bit
> appropriately when i2c_pxa_reset is called. Parameter called fast_mode rather
> than frequency as this driver is also used for the i2c_pxa_pwr bus which has
> different normal and fast frequencies.
> 
> Signed-off-by: Jonathan Cameron <[EMAIL PROTECTED]>
> ---
>  drivers/i2c/busses/i2c-pxa.c|4 +++-
>  include/asm-arm/arch-pxa/i2c.h  |1 +
>  include/asm-arm/arch-pxa/pxa-regs.h |1 +
>  3 files changed, 5 insertions(+), 1 deletion(-)
> 
> --- a/include/asm-arm/arch-pxa/pxa-regs.h 2008-06-30 20:06:02.0 
> +0100
> +++ b/include/asm-arm/arch-pxa/pxa-regs.h 2008-07-02 14:03:19.0 
> +0100
> @@ -448,6 +448,7 @@
>  #define ICR_ALDIE(1 << 12)  /* enable arbitration interrupt */
>  #define ICR_SADIE(1 << 13)  /* slave address detected int enable 
> */
>  #define ICR_UR   (1 << 14)  /* unit reset */
> +#define ICR_FM   (1 << 15)  /* fast mode */
>  
>  #define ISR_RWM  (1 << 0)   /* read/write mode */
>  #define ISR_ACKNAK   (1 << 1)   /* ack/nak status */
> --- a/include/asm-arm/arch-pxa/i2c.h  2008-06-30 20:04:02.0 +0100
> +++ b/include/asm-arm/arch-pxa/i2c.h  2008-07-02 13:59:59.0 +0100
> @@ -66,6 +66,7 @@ struct i2c_pxa_platform_data {
>   struct i2c_slave_client *slave;
>   unsigned intclass;
>   int use_pio;
> + int fast_mode;
>  };
>  
>  extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
> --- a/drivers/i2c/busses/i2c-pxa.c2008-06-30 20:05:51.0 +0100
> +++ b/drivers/i2c/busses/i2c-pxa.c2008-07-02 15:50:31.0 +0100
> @@ -67,6 +67,7 @@ struct pxa_i2c {
>  
>   int irq;
>   int use_pio;
> + int fast_mode;
>  };
>  
>  #define _IBMR(i2c)   ((i2c)->reg_base + 0)
> @@ -365,7 +366,7 @@ static void i2c_pxa_reset(struct pxa_i2c
>   writel(i2c->slave_addr, _ISAR(i2c));
>  
>   /* set control register values */
> - writel(I2C_ICR_INIT, _ICR(i2c));
> + writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
>  
>  #ifdef CONFIG_I2C_PXA_SLAVE
>   dev_info(&i2c->adap.dev, "Enabling slave mode\n");
> @@ -1041,6 +1042,7 @@ static int i2c_pxa_probe(struct platform
>   if (plat) {
>   i2c->adap.class = plat->class;
>   i2c->use_pio = plat->use_pio;
> + i2c->fast_mode = plat->fast_mode;
>   }
>  
>   if (i2c->use_pio) {

Patch looks OK to me. Ben, i2c-pxa is embedded so this is something for
you.

-- 
Jean Delvare

___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c


Re: [i2c] [PATCH 1/2] Convert i2c-mpc from a platform driver into a of_platform driver, V4

2008-07-09 Thread Grant Likely
On Mon, Jun 30, 2008 at 5:01 PM, Jon Smirl <[EMAIL PROTECTED]> wrote:
> Convert i2c-mpc to an of_platform driver. Utilize the code in 
> drivers/of-i2c.c to make i2c modules dynamically loadable by the device tree.

Timur, can you please test this one on an 83xx platform?  It works on
5200, but I want to make sure 83xx doesn't break before I pick it up.

Thanks,
g.

>
> Signed-off-by: Jon Smirl <[EMAIL PROTECTED]>
> ---
>
>  arch/powerpc/sysdev/fsl_soc.c |  122 
> -
>  drivers/i2c/busses/i2c-mpc.c  |  104 ---
>  2 files changed, 60 insertions(+), 166 deletions(-)
>
> diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
> index 3a7054e..ebcec73 100644
> --- a/arch/powerpc/sysdev/fsl_soc.c
> +++ b/arch/powerpc/sysdev/fsl_soc.c
> @@ -414,128 +414,6 @@ err:
>
>  arch_initcall(gfar_of_init);
>
> -#ifdef CONFIG_I2C_BOARDINFO
> -#include 
> -struct i2c_driver_device {
> -   char*of_device;
> -   char*i2c_type;
> -};
> -
> -static struct i2c_driver_device i2c_devices[] __initdata = {
> -   {"ricoh,rs5c372a", "rs5c372a"},
> -   {"ricoh,rs5c372b", "rs5c372b"},
> -   {"ricoh,rv5c386",  "rv5c386"},
> -   {"ricoh,rv5c387a", "rv5c387a"},
> -   {"dallas,ds1307",  "ds1307"},
> -   {"dallas,ds1337",  "ds1337"},
> -   {"dallas,ds1338",  "ds1338"},
> -   {"dallas,ds1339",  "ds1339"},
> -   {"dallas,ds1340",  "ds1340"},
> -   {"stm,m41t00", "m41t00"},
> -   {"dallas,ds1374",  "rtc-ds1374"},
> -};
> -
> -static int __init of_find_i2c_driver(struct device_node *node,
> -struct i2c_board_info *info)
> -{
> -   int i;
> -
> -   for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
> -   if (!of_device_is_compatible(node, i2c_devices[i].of_device))
> -   continue;
> -   if (strlcpy(info->type, i2c_devices[i].i2c_type,
> -   I2C_NAME_SIZE) >= I2C_NAME_SIZE)
> -   return -ENOMEM;
> -   return 0;
> -   }
> -   return -ENODEV;
> -}
> -
> -static void __init of_register_i2c_devices(struct device_node *adap_node,
> -  int bus_num)
> -{
> -   struct device_node *node = NULL;
> -
> -   while ((node = of_get_next_child(adap_node, node))) {
> -   struct i2c_board_info info = {};
> -   const u32 *addr;
> -   int len;
> -
> -   addr = of_get_property(node, "reg", &len);
> -   if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
> -   printk(KERN_WARNING "fsl_soc.c: invalid i2c device 
> entry\n");
> -   continue;
> -   }
> -
> -   info.irq = irq_of_parse_and_map(node, 0);
> -   if (info.irq == NO_IRQ)
> -   info.irq = -1;
> -
> -   if (of_find_i2c_driver(node, &info) < 0)
> -   continue;
> -
> -   info.addr = *addr;
> -
> -   i2c_register_board_info(bus_num, &info, 1);
> -   }
> -}
> -
> -static int __init fsl_i2c_of_init(void)
> -{
> -   struct device_node *np;
> -   unsigned int i = 0;
> -   struct platform_device *i2c_dev;
> -   int ret;
> -
> -   for_each_compatible_node(np, NULL, "fsl-i2c") {
> -   struct resource r[2];
> -   struct fsl_i2c_platform_data i2c_data;
> -   const unsigned char *flags = NULL;
> -
> -   memset(&r, 0, sizeof(r));
> -   memset(&i2c_data, 0, sizeof(i2c_data));
> -
> -   ret = of_address_to_resource(np, 0, &r[0]);
> -   if (ret)
> -   goto err;
> -
> -   of_irq_to_resource(np, 0, &r[1]);
> -
> -   i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
> -   if (IS_ERR(i2c_dev)) {
> -   ret = PTR_ERR(i2c_dev);
> -   goto err;
> -   }
> -
> -   i2c_data.device_flags = 0;
> -   flags = of_get_property(np, "dfsrr", NULL);
> -   if (flags)
> -   i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
> -
> -   flags = of_get_property(np, "fsl5200-clocking", NULL);
> -   if (flags)
> -   i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
> -
> -   ret =
> -   platform_device_add_data(i2c_dev, &i2c_data,
> -sizeof(struct
> -   fsl_i2c_platform_data));
> -   if (ret)
> -   goto unreg;
> -
> -   of_register_i2c_devices(np, i++);
> -   }
> -
> -   return 0;
> -
> -unreg:
> -   platform_device_unregister(i2c_dev);
> -err:
> -   return ret;
> -}
> -
> -arch_initcall(fsl_i2c_of_

[SPAM:4.6] BUSINESS PROPOSAL IF YOU ARE INTERESTED REPLY ME IMMEDIATELY

2008-07-09 Thread Diallo Salim
You are invited to "BUSINESS PROPOSAL IF YOU ARE INTERESTED REPLY ME 
IMMEDIATELY".


By your host Diallo Salim:

DEAR PARTNER,
I HAVE A BUSINESS TRANSACTION OPPORTUNITY FOR THE BETTERMENT OF THE BOTH 
FAMILIES.MY NAME IS MR DIALLO SALIM AUDITING MANAGER BOA BANK BURKINA FASO.I 
DISCOVERED AN ABANDONED SUM WORTH OF $20MILLION US DOLLARS.THE CLAIMS IS 100% 
RISK FREE .I NEED A HONEST FOREIGN PARTNER THAT CAN ASSIST ME TRANSFER THE 
MONEY TO HIS BANK ACCOUNT WITHIN SHORT PERIOD FROM NOW.FOR MORE CLEARIFICATION 
REPLY ME BACK AND IF ONLY YOU ARE INTERESTED .AND CAPABLE TO ASIST ME CALL 
22676460669

 Date:  Wednesday July 9, 2008

 Time:  8:00 pm - 9:00 pm (GMT +00:00)

Will you attend? RSVP to this invitation at:

 
http://calendar.yahoo.com/diallo_salim29?v=126&a1=0&iid=6x%403lsx%40D8%406aXyN-hiHUXd%408tMc%40LJOa%40Qclx%40%40&igid=uhBopglcWMMY%40Cm-PxQTYQd%40w%40BfaJ34Vp%40C9N7bVgv%40

Copyright © 2008 All Rights Reserved
 www.yahoo.com

Privacy Policy:
 http://privacy.yahoo.com/privacy/us

Terms of Service:
 http://docs.yahoo.com/info/terms/
___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c

[i2c] [PATCH] gpio: max732x: add support for MAX7319, MAX7320-7327 I2C Port Expanders

2008-07-09 Thread Eric Miao

Signed-off-by: Jack Ren <[EMAIL PROTECTED]>
Signed-off-by: Eric Miao <[EMAIL PROTECTED]>
---
 drivers/gpio/Kconfig|   22 +++
 drivers/gpio/Makefile   |1 +
 drivers/gpio/max732x.c  |  342 +++
 include/linux/i2c/max732x.h |   19 +++
 4 files changed, 384 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpio/max732x.c
 create mode 100644 include/linux/i2c/max732x.h

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index bbd2834..9f8d030 100644
--- 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"
+   depends on I2C
+   help
+ Say yes here to support the MAX7319, MAX7320-7327 series of I2C
+ Port Expanders. Each IO port on these chips has a fixed role of
+ Input (designated by 'I'), Push-Pull Output ('O'), or Open-Drain
+ Input and Output (designed by 'P'). The combinations are listed
+ below:
+
+   MAX7319 (8I), MAX7320 (8O), MAX7321 (8P), MAX7322 (4I4O),
+   MAX7323 (4P4O), MAX7324 (8I8O), MAX7325 (8P8O)
+   MAX7326 (4I12O), MAX7327 (4P12O)
+
+ The board code has to specify the model to use, and the start
+ number for these GPIOs. Model specific information is calculated
+ automatically. Due to the fixed role of each port, configuration
+ of the port direction will be ignored and a warning be issued if
+ the corresponding port isn't applicable. And gpio_get_value() to
+ those output only ports will return the configured output status
+ instead of a real input.
+
 comment "SPI GPIO expanders:"
 
 config GPIO_MCP23S08
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index fdde992..814698c 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o
 obj-$(CONFIG_GPIO_MCP23S08)+= mcp23s08.o
 obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
 obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
+obj-$(CONFIG_GPIO_MAX732X) += max732x.o
diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c
new file mode 100644
index 000..b1b9b62
--- /dev/null
+++ b/drivers/gpio/max732x.c
@@ -0,0 +1,342 @@
+/*
+ *  max732x.c - I2C Port Expander with 8/16 I/O
+ *
+ *  Copyright (C) 2007 Marvell International Ltd.
+ *  Copyright (C) 2008 Jack Ren <[EMAIL PROTECTED]>
+ *  Copyright (C) 2008 Eric Miao <[EMAIL PROTECTED]>
+ *
+ *  Derived from drivers/gpio/pca953x.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+/* Each port of MAX732x (including MAX7319) falls into one of the
+ * following three types:
+ *
+ *   - Push Pull Output
+ *   - Input
+ *   - Open Drain I/O
+ *
+ * designated by 'O', 'I' and 'P' individually according to MAXIM's
+ * datasheets.
+ *
+ * There are two groups of I/O ports, each group usually includes
+ * up to 8 I/O ports, and is accessed by different I2C address:
+ *
+ *   - Group A : by I2C address 0b'110
+ *   - Group B : by I2C address 0b'101
+ *
+ * where '' is decided by the connections of pin AD2/AD0.
+ *
+ * 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.
+ *
+ * GPIO numbers start from 'gpio_base + 0' to 'gpio_base + 8/16',
+ * and GPIOs from GROUP_A are numbered before those from GROUP_B
+ * (if there are two groups).
+ *
+ * NOTE: MAX7328/MAX7329, however, resembles much closer to PCF8574,
+ * they are not supported by this driver.
+ */
+
+#define PORT_NONE  0x0 /* '/' No Port */
+#define PORT_OUTPUT0x1 /* 'O' Push-Pull, Output Only */
+#define PORT_INPUT 0x2 /* 'I' Input Only */
+#define PORT_OPENDRAIN 0x3 /* 'P' Open-Drain, I/O */
+
+#define IO_4I4O0x5AA5  /* O7 O6 I5 I4 I3 I2 O1 O0 */
+#define IO_4P4O0x5FF5  /* O7 O6 P5 P4 P3 P2 O1 O0 */
+#define IO_8I  0x  /* I7 I6 I5 I4 I3 I2 I1 I0 */
+#define IO_8P  0x  /* P7 P6 P5 P4 P3 P2 P1 P0 */
+#define IO_8O  0x  /* O7 O6 O5 O4 O3 O2 O1 O0 */
+
+#define GROUP_A(x) ((x) & 0x)  /* I2C Addr: 0b'110 */
+#define GROUP_B(x) ((x) << 16) /* I2C Addr: 0b'101 */
+
+static const struct i2c_device_id max732x_id[] = {
+   { "max7319", GROUP_A(IO_8I) },
+   { "max7320", GROUP_B(IO_8O) },
+   { "max7321", GROUP_A(IO_8P) },
+   { "max7322", GROUP_A(IO_4I4O) },
+   { "max7323", GROUP_A(IO_4P4O) },
+   { "max7324", GROUP_A(IO_8I) | GROUP_B(IO_8O