From: Tony Lindgren <tony@atomide.com>
To: Manikandan Pillai <mani.pillai@ti.com>
Cc: linux-omap@vger.kernel.org, broonie@sirena.org.uk
Subject: Re: [PATCH 2/2] Changes for adding and building TPS6235x based PR785 board support
Date: Tue, 13 Jan 2009 16:59:10 +0200 [thread overview]
Message-ID: <20090113145909.GQ7344@atomide.com> (raw)
In-Reply-To: <1231832505-7166-1-git-send-email-mani.pillai@ti.com>
Hi,
Few comments below.
* Manikandan Pillai <mani.pillai@ti.com> [090113 09:42]:
> TPS6235x chip based PR785 power modules are from Texas Instruments
> for OMAP3 EVM boards. This patch supports the PR785 card
> and provides the driver support for the TPS devices.
>
> For compilation, the LCD and MMC drivers are modified and will not
> work. Further patches will be provided for support of LCD and MMC
> with PR785 boards.
>
> Signed-off-by: Manikandan Pillai <mani.pillai@ti.com>
> ---
> arch/arm/mach-omap2/Kconfig | 11 +++
> arch/arm/mach-omap2/board-omap3evm.c | 137 ++++++++++++++++++++++++++++++++++
> arch/arm/mach-omap2/mmc-twl4030.c | 4 +-
> arch/arm/plat-omap/i2c.c | 69 +++++++++++++++++-
> drivers/video/omap/lcd_omap3evm.c | 6 ++
> 5 files changed, 225 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> index 0a86a88..91890be 100644
> --- a/arch/arm/mach-omap2/Kconfig
> +++ b/arch/arm/mach-omap2/Kconfig
> @@ -121,6 +121,17 @@ config MACH_OMAP3EVM
> bool "OMAP 3530 EVM board"
> depends on ARCH_OMAP3 && ARCH_OMAP34XX
>
> +menu "PR785 Power board selection for OMAP3 EVM"
> +config OMAP3EVM_PR785
> + bool "Power board for OMAP3 EVM"
> + depends on I2C=y && ARCH_OMAP34XX
> + help
> + Say yes here if you are using the TPS6235x based PR785 Power Module
> + for the EVM boards. This core driver provides register access and IRQ
> + handling facilities, and registers devices for the various functions
> + so that function-specific drivers can bind to them.
> +endmenu
> +
> config MACH_OMAP3_BEAGLE
> bool "OMAP3 BEAGLE board"
> depends on ARCH_OMAP3 && ARCH_OMAP34XX
> diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
> index e4e60e2..60d2d22 100644
> --- a/arch/arm/mach-omap2/board-omap3evm.c
> +++ b/arch/arm/mach-omap2/board-omap3evm.c
> @@ -36,12 +36,19 @@
> #include <mach/usb-ehci.h>
> #include <mach/common.h>
> #include <mach/mcspi.h>
> +#include <mach/mux.h>
>
> #include "sdram-micron-mt46h32m32lf-6.h"
> #include "twl4030-generic-scripts.h"
> #include "mmc-twl4030.h"
> +#include <linux/regulator/machine.h>
> +#include <linux/regulator/driver.h>
>
> +#define TPS6235X_REG_MAX 3
>
> +#if defined(CONFIG_OMAP3EVM_PR785) && defined(CONFIG_TWL4030_CORE)
> +#error config err : only one of OMAP3EVM_PR785 or TWL4030_CORE can be defined
> +#endif
> static struct resource omap3evm_smc911x_resources[] = {
> [0] = {
> .start = OMAP3EVM_ETHR_START,
> @@ -89,6 +96,7 @@ static struct omap_uart_config omap3_evm_uart_config __initdata = {
> .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
> };
>
> +#if defined(CONFIG_TWL4030_CORE)
> static struct twl4030_gpio_platform_data omap3evm_gpio_data = {
> .gpio_base = OMAP_MAX_GPIO_LINES,
> .irq_base = TWL4030_GPIO_IRQ_BASE,
> @@ -150,16 +158,125 @@ static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
> .platform_data = &omap3evm_twldata,
> },
> };
> +#endif
> +
> +#if defined(CONFIG_OMAP3EVM_PR785)
> +/* CORE voltage regulator */
> +struct regulator_consumer_supply tps62352_core_consumers = {
> + .supply = "vdd2",
> +};
> +
> +/* MPU voltage regulator */
> +struct regulator_consumer_supply tps62352_mpu_consumers = {
> + .supply = "vdd1",
> +};
> +
> +struct regulator_init_data vdd2_tps_regulator_data = {
> + .constraints = {
> + .min_uV = 750000,
> + .max_uV = 1537000,
> + .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
> + REGULATOR_CHANGE_STATUS),
> + },
> + .num_consumer_supplies = 1,
> + .consumer_supplies = &tps62352_core_consumers,
> +};
> +
> +struct regulator_init_data vdd1_tps_regulator_data = {
> + .constraints = {
> + .min_uV = 750000,
> + .max_uV = 1537000,
> + .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
> + REGULATOR_CHANGE_STATUS),
> + },
> + .num_consumer_supplies = 1,
> + .consumer_supplies = &tps62352_mpu_consumers,
> +};
> +
> +static struct i2c_board_info __initdata tps_6235x_i2c_board_info[] = {
> + {
> + I2C_BOARD_INFO("tps62352", 0x4A),
> + .flags = I2C_CLIENT_WAKE,
> + .platform_data = &vdd2_tps_regulator_data,
> + },
> + {
> + I2C_BOARD_INFO("tps62353", 0x48),
> + .flags = I2C_CLIENT_WAKE,
> + .platform_data = &vdd1_tps_regulator_data,
> + },
> +};
> +#endif
>
> static int __init omap3_evm_i2c_init(void)
> {
> +#if defined(CONFIG_OMAP3EVM_PR785)
> + omap_register_i2c_bus(1, 2600, tps_6235x_i2c_board_info,
> + ARRAY_SIZE(tps_6235x_i2c_board_info));
> +#endif
> +#if defined(CONFIG_TWL4030_CORE)
> omap_register_i2c_bus(1, 2600, omap3evm_i2c_boardinfo,
> ARRAY_SIZE(omap3evm_i2c_boardinfo));
> +#endif
> omap_register_i2c_bus(2, 400, NULL, 0);
> omap_register_i2c_bus(3, 400, NULL, 0);
> return 0;
> }
>
> +/*
> + * Read a value from a register in an tps_6235x device.
> + * The value is returned in 'val'.
> + * Returns zero if successful, or non-zero otherwise.
> + */
> +int tps_6235x_read_reg(struct i2c_client *client, u8 reg, u8 *val)
> +{
> + u8 data;
> +
> + if (!client->adapter)
> + return -ENODEV;
> +
> + if (reg > TPS6235X_REG_MAX)
> + return -1;
> +
> + data = i2c_smbus_read_byte_data(client, reg);
> + *val = data;
> + return 0;
> +}
> +
> +/*
> + * Write a value to a register in an tps_6235x device.
> + * Returns zero if successful, or non-zero otherwise.
> + */
> +int tps_6235x_write_reg(struct i2c_client *client, u8 reg, u8 val)
> +{
> + int err;
> + int retry = 0;
> +
> + if (!client->adapter)
> + return -ENODEV;
> +
> + if (reg > TPS6235X_REG_MAX)
> + return -1;
> +
> +again:
> + err = i2c_smbus_write_byte_data(client, reg, val);
> + if (err >= 0)
> + return 0;
> +
> + dev_err(&client->dev,
> + "wrote 0x%.2x to offset 0x%.2x error %d\n", val, reg, err);
> +
> + /* Try 3 times */
> + if (retry <= 3) {
> + dev_info(&client->dev, "retry ... %d\n", retry);
> + retry++;
> + schedule_timeout(msecs_to_jiffies(20));
> + goto again;
> + }
> + return err;
> +}
> +
> +/*-------------------------------------------------------------------*/
> +
The the read/write_reg should be in drivers/mfd somewhere.
> static struct platform_device omap3_evm_lcd_device = {
> .name = "omap3evm_lcd",
> .id = -1,
> @@ -233,6 +350,7 @@ static struct platform_device *omap3_evm_devices[] __initdata = {
> &omap3evm_smc911x_device,
> };
>
> +#if defined(CONFIG_TWL4030_CORE)
> static struct twl4030_hsmmc_info mmc[] __initdata = {
> {
> .mmc = 1,
> @@ -242,6 +360,20 @@ static struct twl4030_hsmmc_info mmc[] __initdata = {
> },
> {} /* Terminator */
> };
> +#endif
> +
> +static void omap_init_pr785(void)
> +{
> + /* Initialize the mux settings for PR785 power module board */
> + if (cpu_is_omap343x()) {
> + omap_cfg_reg(AF26_34XX_GPIO0);
> + omap_cfg_reg(AF22_34XX_GPIO9);
> + omap_cfg_reg(AF6_34XX_GPIO140_UP);
> + omap_cfg_reg(AE6_34XX_GPIO141);
> + omap_cfg_reg(AF5_34XX_GPIO142);
> + omap_cfg_reg(AE5_34XX_GPIO143);
> + }
> +}
>
> static void __init omap3_evm_init(void)
> {
> @@ -255,7 +387,12 @@ static void __init omap3_evm_init(void)
> ARRAY_SIZE(omap3evm_spi_board_info));
>
> omap_serial_init();
> +#if defined(CONFIG_TWL4030_CORE)
> twl4030_mmc_init(mmc);
> +#endif
> +#if defined(CONFIG_OMAP3EVM_PR785)
> + omap_init_pr785();
> +#endif
> usb_musb_init();
> usb_ehci_init();
> omap3evm_flash_init();
> diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c
> index 437f520..d907889 100644
> --- a/arch/arm/mach-omap2/mmc-twl4030.c
> +++ b/arch/arm/mach-omap2/mmc-twl4030.c
> @@ -168,7 +168,7 @@ static int twl_mmc_resume(struct device *dev, int slot)
> */
> static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
> {
> - int ret;
> + int ret = 0;
> u8 vmmc, dev_grp_val;
>
> switch (1 << vdd) {
> @@ -223,6 +223,7 @@ static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
> else
> dev_grp_val = LDO_CLR; /* Power down */
>
> +#if defined(CONFIG_TWL4030_CORE)
> ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
> dev_grp_val, c->twl_vmmc_dev_grp);
> if (ret)
> @@ -231,6 +232,7 @@ static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
> ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
> vmmc, c->twl_mmc_dedicated);
>
> +#endif
> return ret;
> }
>
> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
> index 89a6ab0..3bc21bb 100644
> --- a/arch/arm/plat-omap/i2c.c
> +++ b/arch/arm/plat-omap/i2c.c
> @@ -27,6 +27,8 @@
> #include <linux/platform_device.h>
> #include <linux/i2c.h>
> #include <mach/mux.h>
> +#include <linux/string.h>
> +#include <linux/regulator/machine.h>
>
> #define OMAP_I2C_SIZE 0x3f
> #define OMAP1_I2C_BASE 0xfffb3800
> @@ -97,6 +99,15 @@ static const int omap34xx_pins[][2] = {
> static const int omap34xx_pins[][2] = {};
> #endif
>
> +#if defined(CONFIG_OMAP3EVM_PR785)
> +struct platform_device *vdd2_platform_device;
> +struct platform_device *vdd1_platform_device;
> +extern struct regulator_init_data vdd2_tps_regulator_data;
> +extern struct regulator_init_data vdd1_tps_regulator_data;
> +extern struct regulator_consumer_supply tps62352_core_consumers;
> +extern struct regulator_consumer_supply tps62352_mpu_consumers;
> +#endif
> +
> static void __init omap_i2c_mux_pins(int bus)
> {
> int scl, sda;
> @@ -118,6 +129,53 @@ static void __init omap_i2c_mux_pins(int bus)
> omap_cfg_reg(scl);
> }
>
> +#if defined(CONFIG_OMAP3EVM_PR785)
> +/* This is the callback function used to find the correct
> + * i2c platform child for the regulator consumer
> +*/
> +int omap_i2c_match_child(struct device *dev, void *data)
> +{
> + struct regulator_init_data *reg_init_data = dev->platform_data;
> + char *name = data;
> +
> + /* Child does not match */
> + if (strcmp(name, reg_init_data->consumer_supplies->supply))
> + return 0;
> + else
> + return 1;
> +}
> +
> +int omap_i2c_register_child(struct platform_device *pdev_parent,
> + const char *name, struct platform_device **pdev)
> +{
> + int ret = 0;
> +
> + *pdev = platform_device_alloc(name, -1);
> + if (pdev == NULL) {
> + dev_err(&(*pdev)->dev, "Failed to alloc i2c-child %s\n", name);
> + return -1;
> + }
> +
> + (*pdev)->dev.parent = &pdev_parent->dev;
> + if (strcmp(name, "vdd2_consumer") == 0) {
> + tps62352_core_consumers.dev = &(*pdev)->dev;
> + (*pdev)->dev.platform_data = &vdd2_tps_regulator_data;
> + } else if (strcmp(name, "vdd1_consumer") == 0) {
> + tps62352_mpu_consumers.dev = &(*pdev)->dev;
> + (*pdev)->dev.platform_data = &vdd1_tps_regulator_data;
> + }
> +
> + ret = platform_device_add(*pdev);
> + if (ret != 0) {
> + dev_err(&(*pdev)->dev, "Failed to register %s: %d\n",
> + name, ret);
> + platform_device_put(*pdev);
> + *pdev = NULL;
> + }
> + return ret;
> +}
> +#endif
> +
> int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
> struct i2c_board_info const *info,
> unsigned len)
> @@ -160,5 +218,14 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
> }
>
> omap_i2c_mux_pins(bus_id - 1);
> - return platform_device_register(pdev);
> + platform_device_register(pdev);
> +#if defined(CONFIG_OMAP3EVM_PR785)
> + if (bus_id == 1) {
> + omap_i2c_register_child(pdev, "vdd2_consumer", \
> + &vdd2_platform_device);
> + omap_i2c_register_child(pdev, "vdd1_consumer", \
> + &vdd1_platform_device);
> + }
> +#endif
> + return 0;
> }
Argh, i2c-omap.c is the _bus_ driver, not i2c device! Please move
the above code to drivers/mfd somewhere.
How different tps6235 is from the twl4030? Maybe you can just add
functionality to the existing drivers/mfd/twl4030-core.c.
> diff --git a/drivers/video/omap/lcd_omap3evm.c b/drivers/video/omap/lcd_omap3evm.c
> index 1c3d814..4f373b2 100644
> --- a/drivers/video/omap/lcd_omap3evm.c
> +++ b/drivers/video/omap/lcd_omap3evm.c
> @@ -66,9 +66,11 @@ static int omap3evm_panel_init(struct lcd_panel *panel,
> gpio_direction_output(LCD_PANEL_LR, 1);
> gpio_direction_output(LCD_PANEL_UD, 1);
>
> +#if defined(CONFIG_TWL4030_CORE)
> twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
> twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
> twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
> +#endif
> bklight_level = 100;
>
> return 0;
> @@ -97,6 +99,7 @@ static unsigned long omap3evm_panel_get_caps(struct lcd_panel *panel)
> static int omap3evm_bklight_setlevel(struct lcd_panel *panel,
> unsigned int level)
> {
> +#if defined(CONFIG_TWL4030_CORE)
> u8 c;
> if ((level >= 0) && (level <= 100)) {
> c = (125 * (100 - level)) / 100 + 2;
> @@ -104,6 +107,9 @@ static int omap3evm_bklight_setlevel(struct lcd_panel *panel,
> bklight_level = level;
> }
> return 0;
> +#endif
> + /* Fix this once patch fix is sent out for TPS-boards */
> + return -1;
> }
>
> static unsigned int omap3evm_bklight_getlevel(struct lcd_panel *panel)
Looks like the above needs some more work too.
Tony
next prev parent reply other threads:[~2009-01-13 14:59 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-13 7:41 [PATCH 2/2] Changes for adding and building TPS6235x based PR785 board support Manikandan Pillai
2009-01-13 14:59 ` Tony Lindgren [this message]
2009-01-13 21:49 ` David Brownell
2009-01-13 21:51 ` Mark Brown
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=20090113145909.GQ7344@atomide.com \
--to=tony@atomide.com \
--cc=broonie@sirena.org.uk \
--cc=linux-omap@vger.kernel.org \
--cc=mani.pillai@ti.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox