Hi Marek,
On Fri, Nov 30, 2012 at 06:48:35PM +0100, Marek Vasut wrote:
> This patch drops the i2c timing tables from this driver and instead
> derives the timing based from the requested clock sleep. The timing
> tables were completely wrong anyway when observed on a scope.
>
> This new algorithm is also only derived by using a scope, but it seems
> to produce much more accurate result.
>
> Signed-off-by: Marek Vasut <[email protected]>
> Cc: Fabio Estevam <[email protected]>
> Cc: Shawn Guo <[email protected]>
> Cc: Wolfram Sang <[email protected]>
> ---
> drivers/i2c/busses/i2c-mxs.c | 94
> ++++++++++++++++++++++++------------------
> 1 file changed, 55 insertions(+), 39 deletions(-)
>
> NOTE: Can someone please test if this patch works for them as well?
> I tested this on DENX M28EVK and Freescale MX28EVK.
Second call for testers.
>
> diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
> index 9048f34..ad28a7b 100644
> --- a/drivers/i2c/busses/i2c-mxs.c
> +++ b/drivers/i2c/busses/i2c-mxs.c
> @@ -93,35 +93,6 @@
> #define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \
> MXS_I2C_CTRL0_MASTER_MODE)
>
> -struct mxs_i2c_speed_config {
> - uint32_t timing0;
> - uint32_t timing1;
> - uint32_t timing2;
> -};
> -
> -/*
> - * Timing values for the default 24MHz clock supplied into the i2c block.
> - *
> - * The bus can operate at 95kHz or at 400kHz with the following timing
> - * register configurations. The 100kHz mode isn't present because it's
> - * values are not stated in the i.MX233/i.MX28 datasheet. The 95kHz mode
> - * shall be close enough replacement. Therefore when the bus is configured
> - * for 100kHz operation, 95kHz timing settings are actually loaded.
> - *
> - * For details, see i.MX233 [25.4.2 - 25.4.4] and i.MX28 [27.5.2 - 27.5.4].
> - */
> -static const struct mxs_i2c_speed_config mxs_i2c_95kHz_config = {
> - .timing0 = 0x00780030,
> - .timing1 = 0x00800030,
> - .timing2 = 0x00300030,
> -};
> -
> -static const struct mxs_i2c_speed_config mxs_i2c_400kHz_config = {
> - .timing0 = 0x000f0007,
> - .timing1 = 0x001f000f,
> - .timing2 = 0x00300030,
> -};
> -
> /**
> * struct mxs_i2c_dev - per device, private MXS-I2C data
> *
> @@ -137,7 +108,9 @@ struct mxs_i2c_dev {
> struct completion cmd_complete;
> u32 cmd_err;
> struct i2c_adapter adapter;
> - const struct mxs_i2c_speed_config *speed;
> +
> + uint32_t timing0;
> + uint32_t timing1;
>
> /* DMA support components */
> int dma_channel;
> @@ -153,9 +126,16 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
> {
> stmp_reset_block(i2c->regs);
>
> - writel(i2c->speed->timing0, i2c->regs + MXS_I2C_TIMING0);
> - writel(i2c->speed->timing1, i2c->regs + MXS_I2C_TIMING1);
> - writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2);
> + /*
> + * Configure timing for the I2C block. The I2C TIMING2 register has to
> + * be programmed with this particular magic number. The rest is derived
> + * from the XTAL speed and requested I2C speed.
> + *
> + * For details, see i.MX233 [25.4.2 - 25.4.4] and i.MX28 [27.5.2 -
> 27.5.4].
> + */
> + writel(i2c->timing0, i2c->regs + MXS_I2C_TIMING0);
> + writel(i2c->timing1, i2c->regs + MXS_I2C_TIMING1);
> + writel(0x00300030, i2c->regs + MXS_I2C_TIMING2);
>
> writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
> }
> @@ -540,6 +520,43 @@ static bool mxs_i2c_dma_filter(struct dma_chan *chan,
> void *param)
> return true;
> }
>
> +static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, int speed)
> +{
> + /* The I2C block clock run at 24MHz */
> + const uint32_t clk = 24000000;
> + uint32_t base;
> + uint16_t high_count, low_count, rcv_count, xmit_count;
> + struct device *dev = i2c->dev;
> +
> + if (speed > 540000) {
> + dev_err(dev, "Speed too high (%d Hz), using 540 kHz\n", speed);
> + speed = 540000;
> + } else if (speed < 12000) {
> + dev_err(dev, "Speed too low (%d Hz), using 12 kHz\n", speed);
> + speed = 12000;
> + }
I'd think dev_warn would do, since we are able to continue. No need to
resend, though.
Rest looks good, thanks!
Wolfram
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html