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.
next prev 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