public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Wolfgang Denk <wd@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/9] i2c driver support for SPEAr SoCs
Date: Wed, 16 Dec 2009 23:31:53 +0100	[thread overview]
Message-ID: <20091216223153.7D4344C026@gemini.denx.de> (raw)
In-Reply-To: <1260955110-5656-2-git-send-email-vipin.kumar@st.com>

Dear Vipin KUMAR,

In message <1260955110-5656-2-git-send-email-vipin.kumar@st.com> you wrote:
> 
> Signed-off-by: Vipin <vipin.kumar@st.com>
> ---
>  drivers/i2c/Makefile                 |    1 +
>  drivers/i2c/spr_i2c.c                |  321 ++++++++++++++++++++++++++++++++++
>  include/asm-arm/arch-spear/spr_i2c.h |  143 +++++++++++++++
>  3 files changed, 465 insertions(+), 0 deletions(-)
>  mode change 100644 => 100755 drivers/i2c/Makefile
>  create mode 100755 drivers/i2c/spr_i2c.c
>  create mode 100755 include/asm-arm/arch-spear/spr_i2c.h

Your patch order is, um, sub-optimal.

You start adding an I2C driver for a non-existing CPU here.

This makes no sense, please reorder.

> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -38,6 +38,7 @@ COBJS-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o
>  COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
>  COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
>  COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
> +COBJS-$(CONFIG_SPEARI2C) += spr_i2c.o

Please keep lists sorted (fix globally).

> +/**
> + * i2c_setfreq - Set i2c working mode frequency
> + *
> + * Set i2c working mode frequency
> + */

Incorrect multiline comment style. Please fix globally.

> +static void set_speed(int i2c_spd)
> +{
> +	unsigned int cntl;
> +
> +	if (i2c_spd == IC_SPEED_MODE_MAX) {
> +		cntl = readl(&i2c_regs_p->ic_con);
> +		cntl |= IC_CON_SPH | IC_CON_SPL;
> +		writel(cntl, &i2c_regs_p->ic_con);
> +		i2c_setfreq(MIN_HS_SCL_HIGHTIME, MIN_HS_SCL_LOWTIME);
> +	} else if (i2c_spd == IC_SPEED_MODE_FAST) {
> +		cntl = readl(&i2c_regs_p->ic_con);
> +		cntl |= IC_CON_SPH;
> +		cntl &= ~IC_CON_SPL;
> +		writel(cntl, &i2c_regs_p->ic_con);
> +		i2c_setfreq(MIN_FS_SCL_HIGHTIME, MIN_FS_SCL_LOWTIME);
> +	} else if (i2c_spd == IC_SPEED_MODE_STANDARD) {
> +		cntl = readl(&i2c_regs_p->ic_con);
> +		cntl |= IC_CON_SPF;
> +		cntl &= ~IC_CON_SPL;
> +		writel(cntl, &i2c_regs_p->ic_con);
> +		i2c_setfreq(MIN_SS_SCL_HIGHTIME, MIN_SS_SCL_LOWTIME);
> +	}

It seems you can move the lines

	writel(cntl, &i2c_regs_p->ic_con);
	i2c_setfreq(MIN_FS_SCL_HIGHTIME, MIN_FS_SCL_LOWTIME);

out of the if/else blocks and make them common code.

> +void i2c_set_bus_speed(int speed)
> +{
> +	if (speed >= I2C_MAX_SPEED)
> +		set_speed(IC_SPEED_MODE_MAX);
> +	else
> +	if (speed >= I2C_FAST_SPEED)

Missing braces (mandatory for multiline statements).

> +		set_speed(IC_SPEED_MODE_FAST);
> +	else
> +		set_speed(IC_SPEED_MODE_STANDARD);
> +}

> +/**
> + * i2c_get_bus_speed - Gets the i2c speed
> + *
> + * Gets the i2c speed.
> + */
> +int i2c_get_bus_speed(void)
> +{
> +	if (((readl(&i2c_regs_p->ic_con) & IC_CON_SPH) == IC_CON_SPH) &&
> +	   ((readl(&i2c_regs_p->ic_con) & IC_CON_SPL) == IC_CON_SPL)) {
> +		return I2C_MAX_SPEED;
> +
> +	} else if (((readl(&i2c_regs_p->ic_con) & IC_CON_SPH) == IC_CON_SPH) &&
> +	   ((readl(&i2c_regs_p->ic_con) & IC_CON_SPL) == 0)) {
> +		return I2C_FAST_SPEED;
> +
> +	} else if (((readl(&i2c_regs_p->ic_con) & IC_CON_SPF) == IC_CON_SPF) &&
> +	   ((readl(&i2c_regs_p->ic_con) & IC_CON_SPL) == 0)) {
> +		return I2C_STANDARD_SPEED;
> +	}

It makes no sense to run "readl(&i2c_regs_p->ic_con)" six times - run
it once and latch the value.

Also I tend to think the logic can be written clearer.

> +void i2c_init(int speed, int slaveadd)
> +{
> +	unsigned int enbl;
> +
> +	/* Disable i2c */
> +	enbl = readl(&i2c_regs_p->ic_enable);
> +	enbl &= ~IC_ENABLE_0B;
> +	writel(enbl, &i2c_regs_p->ic_enable);
> +
> +	writel((IC_CON_SD | IC_CON_SPF | IC_CON_MM), &i2c_regs_p->ic_con);
> +	writel(IC_TL0, &i2c_regs_p->ic_rx_tl);
> +	writel(IC_TL0, &i2c_regs_p->ic_tx_tl);

Is this duplication intentional? If so, a comment is needed to explain
why.

> +/**
> + * i2c_probe - Probe the i2c chip
> + *
> + * TBD
> + */
> +int i2c_probe(uchar chip)
> +{
> +	return 0;
> +}

Please do not add dead code.

> +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
> +{
> +	unsigned long start_time_rx;
> +
> +	if (buffer == NULL) {
> +		printf("I2C read: buffer is invalid\n");
> +		return 1;
> +	}
> +
> +	if (alen > 1) {
> +		printf("I2C read: addr len %d not supported\n", alen);
> +		return 1;
> +	}
> +
> +	if (addr + len > 256) {
> +		printf("I2C read: address out of range\n");
> +		return 1;
> +	}
> +
> +	if (i2c_wait_for_bb())
> +		return 1;

Why no error message here?

> +	i2c_setaddress(chip);
> +	writel(addr, &i2c_regs_p->ic_cmd_data);
> +
> +	start_time_rx = get_timer_masked();
> +	while (len) {
> +		writel(IC_CMD, &i2c_regs_p->ic_cmd_data);
> +		if ((readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) ==
> +				IC_STATUS_RFNE) {
> +			*buffer++ = (uchar)readl(&i2c_regs_p->ic_cmd_data);
> +			len--;
> +			start_time_rx = get_timer_masked();
> +		} else {
> +			if (get_timer(start_time_rx) > I2C_BYTE_TO)
> +				return 1;

Why no error message here?

> +	udelay(4000);

Why is this needed?

> +	if ((readl(&i2c_regs_p->ic_raw_intr_stat) & IC_STOP_DET))
> +		readl(&i2c_regs_p->ic_clr_stop_det);
> +
> +	if (i2c_wait_for_bb())
> +		return 1;

Why no error message here?

> +	i2c_flush_rxfifo();
> +
> +	return 0;
> +}
> +
> +/**
> + * i2c_write - Write to i2c memory
> + * @chip:	target i2c address
> + * @addr:	address to read from
> + * @alen:
> + * @buffer:	buffer for read data
> + * @len:	no of bytes to be read
> + *
> + * Write to i2c memory.
> + */
> +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
> +{
> +	int nb = len;
> +	unsigned long start_time_tx;
> +
> +	if (buffer == NULL) {
> +		printf("I2C write: buffer is invalid\n");
> +		return 1;
> +	}
> +
> +	if (alen > 1) {
> +		printf("I2C write: addr len %d not supported\n", alen);
> +		return 1;
> +	}
> +
> +	if (addr + len > 256) {
> +		printf("I2C write: address out of range\n");
> +		return 1;
> +	}
> +
> +	if (i2c_wait_for_bb())
> +		return 1;
> +
> +	i2c_setaddress(chip);
> +
> +	writel(addr, &i2c_regs_p->ic_cmd_data);
> +
> +	start_time_tx = get_timer_masked();
> +	while (len) {
> +		if ((readl(&i2c_regs_p->ic_status) & IC_STATUS_TFNF)
> +			== IC_STATUS_TFNF) {
> +			writel(*buffer, &i2c_regs_p->ic_cmd_data);
> +			buffer++;
> +			len--;
> +			start_time_tx = get_timer_masked();
> +		} else {
> +			if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO))
> +				return 1;
> +		}
> +	}
> +
> +	udelay(4000);
> +	if ((readl(&i2c_regs_p->ic_raw_intr_stat) & IC_STOP_DET))
> +		readl(&i2c_regs_p->ic_clr_stop_det);
> +
> +	if (i2c_wait_for_bb())
> +		return 1;
> +
> +	i2c_flush_rxfifo();
> +
> +	return 0;
> +}

This shares a _lot_ of common code with i2c_read() - factor out?


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
I have a theory that it's impossible to prove anything, but  I  can't
prove it.

  parent reply	other threads:[~2009-12-16 22:31 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-16  9:18 [U-Boot] [PATCH 0/9] Support for SPEAr SoCs Vipin KUMAR
2009-12-16  9:18 ` [U-Boot] [PATCH 1/9] i2c driver support " Vipin KUMAR
2009-12-16  9:18   ` [U-Boot] [PATCH 2/9] smi " Vipin KUMAR
2009-12-16  9:18     ` [U-Boot] [PATCH 3/9] nand " Vipin KUMAR
2009-12-16  9:18       ` [U-Boot] [PATCH 4/9] usbd driver and usb boot firmware " Vipin KUMAR
2009-12-16  9:18         ` [U-Boot] [PATCH 5/9] SPEAr600 SoC support added Vipin KUMAR
2009-12-16  9:18           ` [U-Boot] [PATCH 6/9] SPEAr300 " Vipin KUMAR
2009-12-16  9:18             ` [U-Boot] [PATCH 7/9] SPEAr310 " Vipin KUMAR
2009-12-16  9:18               ` [U-Boot] [PATCH 8/9] SPEAr320 " Vipin KUMAR
2009-12-16  9:18                 ` [U-Boot] [PATCH 9/9] SPEAr600 build " Vipin KUMAR
2009-12-17 20:14                   ` Wolfgang Denk
2009-12-19  7:26                     ` Vipin Kumar
2009-12-17 20:14                 ` [U-Boot] [PATCH 8/9] SPEAr320 SoC " Wolfgang Denk
2009-12-19  7:21                   ` Vipin Kumar
2009-12-17 20:13               ` [U-Boot] [PATCH 7/9] SPEAr310 " Wolfgang Denk
2009-12-19  7:19                 ` Vipin Kumar
2009-12-17 20:09             ` [U-Boot] [PATCH 6/9] SPEAr300 " Wolfgang Denk
2009-12-19  7:10               ` Vipin Kumar
2009-12-19  7:25                 ` Wolfgang Denk
2009-12-19  7:58                   ` Vipin Kumar
2009-12-16 17:30           ` [U-Boot] [PATCH 5/9] SPEAr600 " Peter Tyser
2009-12-16 18:00             ` Armando VISCONTI
2009-12-16 18:28               ` Peter Tyser
2009-12-17 22:44                 ` Wolfgang Denk
2009-12-17 22:54                   ` Peter Tyser
2009-12-17 23:13                     ` Wolfgang Denk
2009-12-19  7:31                       ` Vipin Kumar
2009-12-16 23:09           ` Wolfgang Denk
2009-12-19  8:56             ` Vipin Kumar
2009-12-16 22:56         ` [U-Boot] [PATCH 4/9] usbd driver and usb boot firmware support for SPEAr SoCs Wolfgang Denk
2009-12-19  7:02           ` Vipin Kumar
2009-12-19  7:24             ` Wolfgang Denk
2009-12-19  8:46               ` Vipin Kumar
2010-01-04 23:06       ` [U-Boot] [PATCH 3/9] nand driver " Scott Wood
2010-01-05  3:53         ` Vipin KUMAR
2009-12-16 22:44     ` [U-Boot] [PATCH 2/9] smi " Wolfgang Denk
2009-12-19  6:44       ` Vipin Kumar
2009-12-19  7:20         ` Wolfgang Denk
2009-12-19  7:56           ` Vipin Kumar
2009-12-19  7:59             ` Albert ARIBAUD
2009-12-19  8:28               ` Vipin Kumar
2009-12-19 21:37             ` Wolfgang Denk
2009-12-16 22:31   ` Wolfgang Denk [this message]
2009-12-16 16:49 ` [U-Boot] [PATCH 0/9] Support " Armando VISCONTI

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=20091216223153.7D4344C026@gemini.denx.de \
    --to=wd@denx.de \
    --cc=u-boot@lists.denx.de \
    /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