All of lore.kernel.org
 help / color / mirror / Atom feed
From: obi@saftware.de (Andreas Oberritter)
To: LM Sensors <sensors@stimpy.netroedge.com>,
	LKML <linux-kernel@vger.kernel.org>
Cc: Greg KH <greg@kroah.com>
Subject: [PATCH] possible bug in i2c-algo-bit's inb function
Date: Thu, 19 May 2005 06:25:40 +0000	[thread overview]
Message-ID: <1109528034.4564.16.camel@localhost.localdomain> (raw)
In-Reply-To: <20050227103538.218fa1b0.khali@linux-fr.org>

Hi Jean,

On Sun, 2005-02-27 at 10:35 +0100, Jean Delvare wrote:
> > while writing a driver for a cardbus card which is supposed to use the
> > bit-banging algorithm I noticed that communication with the I2C slave
> > (Philips TDA10046) would fail without this patch. It forces SDA to
> > high for every bit in i2c_inb() instead of once per byte. Can this
> > patch go into the mainline kernel or will this break other drivers? I
> > am using Kernel version 2.6.10.
> 
> There is no reason why this would be necessary. Once SDA is set high on
> the master's side, the client will be controlling it for the rest of the
> byte (transferred from client to master). Setting SDA high again on the
> master's side for each bit shouldn't have any effet, let alone the
> substantial slowdown. If it changes something for you, then either your
> implementation of setscl or getsda is broken and does actually change
> SDA as a side effect, or what really helps is the additional delay, not
> setting SDA high per se. In the former case, check your code. If you
> can't figure out what's wrong, post it here and I'll take at look.
> What's your bus master BTW? In the latter case, you might simply need to
> lower the bus speed (increase udelay).

Increasing udelay from 10us to 100us, 1ms, 10ms or 100ms did not help.

Here's my I2C code:

#define REG_SLCS                0x003c
#define SLCS_SCL                (0x0001 <<  7)
#define SLCS_SDA                (0x0001 <<  6)

static inline u32 pluto_readreg(struct pluto *pluto, u32 reg)
{
        return readl(&pluto->io_mem[reg]);
}

static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val)
{
        writel(val, &pluto->io_mem[reg]);
}

static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32
bits)
{
        u32 val = pluto_readreg(pluto, reg);
        val &= ~mask;
        val |= bits;
        pluto_writereg(pluto, reg, val);
}

static void pluto_setsda(void *data, int state)
{
        struct pluto *pluto = data;

        if (state)
                pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA);
        else
                pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0);
}

static void pluto_setscl(void *data, int state)
{
        struct pluto *pluto = data;

        if (state)
                pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL);
        else
                pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0);
}

static int pluto_getsda(void *data)
{
        struct pluto *pluto = data;

        return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA;
}

static int pluto_getscl(void *data)
{
        struct pluto *pluto = data;

        return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL;
}

in the pci probe function:

        i2c_set_adapdata(&pluto->i2c_adap, pluto);
        strcpy(pluto->i2c_adap.name, DRIVER_NAME);
        pluto->i2c_adap.owner = THIS_MODULE;
        pluto->i2c_adap.id = I2C_ALGO_BIT;
        pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
        pluto->i2c_adap.dev.parent = &pdev->dev;
        pluto->i2c_adap.algo_data = &pluto->i2c_bit;
        pluto->i2c_bit.data = pluto;
        pluto->i2c_bit.setsda = pluto_setsda;
        pluto->i2c_bit.setscl = pluto_setscl;
        pluto->i2c_bit.getsda = pluto_getsda;
        pluto->i2c_bit.getscl = pluto_getscl;
        pluto->i2c_bit.udelay = 10;
        pluto->i2c_bit.timeout = 10;

        /* Raise SCL and SDA */
        pluto_setsda(pluto, 1);
        pluto_setscl(pluto, 1);

	ret = i2c_bit_add_bus(&pluto->i2c_adap);

The bus master is a so called Pluto2 by SCM (part of a DVB-T card sold
by Satelco). If this is a hardware bug, is it possible to add a flag to
struct i2c_algo_bit_data to workaround this bug?

Regards,
Andreas

WARNING: multiple messages have this Message-ID (diff)
From: Andreas Oberritter <obi@saftware.de>
To: LM Sensors <sensors@stimpy.netroedge.com>,
	LKML <linux-kernel@vger.kernel.org>
Cc: Greg KH <greg@kroah.com>
Subject: Re: [PATCH] possible bug in i2c-algo-bit's inb function
Date: Sun, 27 Feb 2005 19:13:54 +0100	[thread overview]
Message-ID: <1109528034.4564.16.camel@localhost.localdomain> (raw)
In-Reply-To: <20050227103538.218fa1b0.khali@linux-fr.org>

Hi Jean,

On Sun, 2005-02-27 at 10:35 +0100, Jean Delvare wrote:
> > while writing a driver for a cardbus card which is supposed to use the
> > bit-banging algorithm I noticed that communication with the I2C slave
> > (Philips TDA10046) would fail without this patch. It forces SDA to
> > high for every bit in i2c_inb() instead of once per byte. Can this
> > patch go into the mainline kernel or will this break other drivers? I
> > am using Kernel version 2.6.10.
> 
> There is no reason why this would be necessary. Once SDA is set high on
> the master's side, the client will be controlling it for the rest of the
> byte (transferred from client to master). Setting SDA high again on the
> master's side for each bit shouldn't have any effet, let alone the
> substantial slowdown. If it changes something for you, then either your
> implementation of setscl or getsda is broken and does actually change
> SDA as a side effect, or what really helps is the additional delay, not
> setting SDA high per se. In the former case, check your code. If you
> can't figure out what's wrong, post it here and I'll take at look.
> What's your bus master BTW? In the latter case, you might simply need to
> lower the bus speed (increase udelay).

Increasing udelay from 10us to 100us, 1ms, 10ms or 100ms did not help.

Here's my I2C code:

#define REG_SLCS                0x003c
#define SLCS_SCL                (0x0001 <<  7)
#define SLCS_SDA                (0x0001 <<  6)

static inline u32 pluto_readreg(struct pluto *pluto, u32 reg)
{
        return readl(&pluto->io_mem[reg]);
}

static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val)
{
        writel(val, &pluto->io_mem[reg]);
}

static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32
bits)
{
        u32 val = pluto_readreg(pluto, reg);
        val &= ~mask;
        val |= bits;
        pluto_writereg(pluto, reg, val);
}

static void pluto_setsda(void *data, int state)
{
        struct pluto *pluto = data;

        if (state)
                pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA);
        else
                pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0);
}

static void pluto_setscl(void *data, int state)
{
        struct pluto *pluto = data;

        if (state)
                pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL);
        else
                pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0);
}

static int pluto_getsda(void *data)
{
        struct pluto *pluto = data;

        return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA;
}

static int pluto_getscl(void *data)
{
        struct pluto *pluto = data;

        return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL;
}

in the pci probe function:

        i2c_set_adapdata(&pluto->i2c_adap, pluto);
        strcpy(pluto->i2c_adap.name, DRIVER_NAME);
        pluto->i2c_adap.owner = THIS_MODULE;
        pluto->i2c_adap.id = I2C_ALGO_BIT;
        pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
        pluto->i2c_adap.dev.parent = &pdev->dev;
        pluto->i2c_adap.algo_data = &pluto->i2c_bit;
        pluto->i2c_bit.data = pluto;
        pluto->i2c_bit.setsda = pluto_setsda;
        pluto->i2c_bit.setscl = pluto_setscl;
        pluto->i2c_bit.getsda = pluto_getsda;
        pluto->i2c_bit.getscl = pluto_getscl;
        pluto->i2c_bit.udelay = 10;
        pluto->i2c_bit.timeout = 10;

        /* Raise SCL and SDA */
        pluto_setsda(pluto, 1);
        pluto_setscl(pluto, 1);

	ret = i2c_bit_add_bus(&pluto->i2c_adap);

The bus master is a so called Pluto2 by SCM (part of a DVB-T card sold
by Satelco). If this is a hardware bug, is it possible to add a flag to
struct i2c_algo_bit_data to workaround this bug?

Regards,
Andreas


  reply	other threads:[~2005-05-19  6:25 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-27  4:49 [PATCH] possible bug in i2c-algo-bit's inb function Andreas Oberritter
2005-05-19  6:25 ` Andreas Oberritter
2005-02-27  9:35 ` Jean Delvare
2005-05-19  6:25   ` Jean Delvare
2005-02-27 18:13   ` Andreas Oberritter [this message]
2005-05-19  6:25     ` Andreas Oberritter
2005-02-27 18:52     ` Jean Delvare
2005-05-19  6:25       ` Jean Delvare
2005-02-27 21:55       ` Andreas Oberritter
2005-05-19  6:25         ` Andreas Oberritter

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=1109528034.4564.16.camel@localhost.localdomain \
    --to=obi@saftware.de \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sensors@stimpy.netroedge.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.