From: Stephen Warren <swarren@nvidia.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 4/7] tegra: Add I2C driver
Date: Mon, 09 Jan 2012 15:07:04 -0700 [thread overview]
Message-ID: <4F0B6508.9030502@nvidia.com> (raw)
In-Reply-To: <1324923111-340-5-git-send-email-sjg@chromium.org>
On 12/26/2011 11:11 AM, Simon Glass wrote:
> From: Yen Lin <yelin@nvidia.com>
>
> Add basic i2c driver for Tegra2 with 8- and 16-bit address support.
> The driver supports building both with and without CONFIG_OF_CONTROL.
>
> Without CONFIG_OF_CONTROL a number of CONFIG options must be supplied
> in the board config header file:
>
> I2CSPEED_KHZ - speed to run I2C bus at (typically 100000)
> CONFIG_I2Cx_PIN_MUX - pin mux setting for each port (P, 1, 2, 3)
> (typically this will be 0 to bring the port out the common
> pins)
...
> diff --git a/arch/arm/include/asm/arch-tegra2/tegra2_i2c.h b/arch/arm/include/asm/arch-tegra2/tegra2_i2c.h
...
> +#ifndef CONFIG_OF_CONTROL
> +enum {
> + I2CSPEED_KHZ = 100, /* in KHz */
> +};
> +#endif
The patch description says the board needs to define I2CSPEED_KHZ, yet
that seems to allow the board to override it, otherwise a default is
used. The patch description probably needs to be fixed.
The way the optional override is implemented is a little confusing. I'd
rather see:
#ifndef CONFIG_OF_CONTROL
#ifndef I2CSPEED_KHZ
#define I2CSPEED_KHZ 100
#endif
#endif
That makes it a lot more obvious it's a default. And actually, why not
put that within some other ifndef CONFIG_OF_CONTROL where the
enum/define is used, since it's presumably only used very locally in the
non-OF initialization code.
...
> diff --git a/drivers/i2c/tegra2_i2c.c b/drivers/i2c/tegra2_i2c.c
...
> +struct i2c_bus i2c_controllers[CONFIG_SYS_MAX_I2C_BUS];
What if there are I2C bus extenders/muxes/... such that there are more
I2C buses in the system than Tegra I2C controllers? I'd rather see an
explicit TEGRA_I2C_NUM_CONTROLLERS define used throughout this patch.
I didn't really review the I2C driver code itself, since I'm not
terribly familiar with the I2C HW details.
> +static int i2c_get_config(int *index, struct i2c_bus *i2c_bus)
> +{
> + const void *blob = gd->fdt_blob;
> + int node;
> +
> + node = fdtdec_next_alias(blob, "i2c", COMPAT_NVIDIA_TEGRA20_I2C,
> + index);
> + if (node < 0)
> + return -1;
I assume the I2C patches will also be reworked to enumerate based on
nodes with a specific compatible flag, and then optionally using aliases
to number them, just like you said you're rework USB?
> +int i2c_init_board(void)
> +{
> + struct i2c_bus *i2c_bus;
> + int index = 0;
> + int i;
> +
> + /* build the i2c_controllers[] for each controller */
> + for (i = 0; i < CONFIG_SYS_MAX_I2C_BUS; ++i) {
> + i2c_bus = &i2c_controllers[i];
> + i2c_bus->id = i;
> +
> + if (i2c_get_config(&index, i2c_bus)) {
> + printf("i2c_init_board: failed to find bus %d\n", i);
> + return -1;
> + }
> +
> + if (i2c_bus->periph_id == PERIPH_ID_DVC_I2C)
> + i2c_bus->control =
> + &((struct dvc_ctlr *)i2c_bus->regs)->control;
> + else
> + i2c_bus->control = &i2c_bus->regs->control;
When instantiating controllers from device tree (as opposed to the
static !CONFIG_OF_CONTROL case), that conditional should be driven by
device tree properties. The kernel already represents this using two
separate compatible values for the different HW: nvidia,tegra20-i2c and
nvidia,tegra20-i2c-dvc.
> +
> + i2c_init_controller(i2c_bus);
> + }
> +
> + return 0;
> +}
> +void i2c_init(int speed, int slaveaddr)
> +{
> + debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
> +}
Surely that function needs to actually do something, at least set up the
clocks so that the (user?) requested rate is honored, or print an error
message if you're only allowed to use the hard-coded bus rate.
> +/* Probe to see if a chip is present. */
> +int i2c_probe(uchar chip)
> +{
> + int rc;
> + uchar reg;
> +
> + debug("i2c_probe: addr=0x%x\n", chip);
> + reg = 0;
> + rc = i2c_write_data(chip, ®, 1);
> + if (rc) {
> + debug("Error probing 0x%x.\n", chip);
> + return 1;
> + }
> + return 0;
> +}
> +
> +static int i2c_addr_ok(const uint addr, const int alen)
> +{
> + if (alen < 0 || alen > sizeof(addr))
> + return 0;
> + if (alen != sizeof(addr)) {
> + uint max_addr = (1 << (8 * alen)) - 1;
> + if (addr > max_addr)
> + return 0;
> + }
> + return 1;
> +}
That seems rather roundabout. Only two address lengths are valid; 7 and
10-bit, so wouldn't it be better to only accept those specific values?
--
nvpublic
next prev parent reply other threads:[~2012-01-09 22:07 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-26 18:11 [U-Boot] [PATCH 0/7] tegra: Add I2C driver and associated parts Simon Glass
2011-12-26 18:11 ` [U-Boot] [PATCH 1/7] tegra: Rename NV_PA_PMC_BASE to TEGRA2_PMC_BASE Simon Glass
2011-12-26 19:12 ` Marek Vasut
2012-01-09 21:34 ` Stephen Warren
2011-12-26 18:11 ` [U-Boot] [PATCH 2/7] tegra: fdt: Add extra I2C definitions for U-Boot Simon Glass
2011-12-26 19:12 ` Marek Vasut
2011-12-27 4:35 ` Stephen Warren
2011-12-27 5:15 ` Simon Glass
2011-12-29 6:40 ` Stephen Warren
2011-12-29 7:11 ` Simon Glass
2011-12-26 18:11 ` [U-Boot] [PATCH 3/7] tegra: Add I2C support to funcmux Simon Glass
2012-01-09 21:36 ` Stephen Warren
2012-01-09 21:40 ` Simon Glass
2012-01-09 22:56 ` Simon Glass
2011-12-26 18:11 ` [U-Boot] [PATCH 4/7] tegra: Add I2C driver Simon Glass
2011-12-26 19:15 ` Marek Vasut
2012-01-08 16:57 ` Simon Glass
2012-01-08 17:06 ` Marek Vasut
2012-01-08 18:16 ` Simon Glass
2012-01-08 5:57 ` Mike Frysinger
2012-01-08 16:46 ` Simon Glass
2012-01-09 22:07 ` Stephen Warren [this message]
2012-01-12 4:17 ` Simon Glass
2012-01-12 19:14 ` Stephen Warren
2012-01-13 7:12 ` Heiko Schocher
2012-01-13 14:49 ` Simon Glass
2012-01-13 15:27 ` Heiko Schocher
2012-02-03 23:18 ` Simon Glass
2011-12-26 18:11 ` [U-Boot] [PATCH 5/7] tegra: Initialise I2C on Nvidia boards Simon Glass
2011-12-26 18:11 ` [U-Boot] [PATCH 6/7] tegra: Select I2C ordering for Seaboard Simon Glass
2012-01-09 21:42 ` Stephen Warren
2011-12-26 18:11 ` [U-Boot] [PATCH 7/7] tegra: Enable I2C on Seaboard Simon Glass
2012-01-09 21:45 ` Stephen Warren
[not found] ` <CAPnjgZ3jTm6j-fK_Kn==W3uGr=8pREEWXawP39kojLzzSH07wQ@mail.gmail.com>
[not found] ` <74CDBE0F657A3D45AFBB94109FB122FF17801D1D4A@HQMAIL01.nvidia.com>
2012-01-12 19:10 ` Simon Glass
2012-01-12 19:21 ` Stephen Warren
2012-01-12 19:28 ` Simon Glass
2012-01-13 7:34 ` Heiko Schocher
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=4F0B6508.9030502@nvidia.com \
--to=swarren@nvidia.com \
--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