Re: [PATCH 4/5] i2c: MPC837xRDB Power Management and GPIO expander driver
Incidentally I used some weird .config without preemption and CONFIG_ENABLE_MUST_CHECK. Heh. [...] > + * I don't have specifications for the MCU firmware that is used on the > + * MPC8349E-mITX/MPC837XRDB boards, I found this register and bits positions > + * by the trial&error method. > + */ > +#define MCU_REG_CTRL 0x20 > +#define MCU_CTRL_POFF0x40 > +#define MCU_NUM_GPIO 2 > + > +struct mcu { > + spinlock_t lock; This should be mutex of course, otherwise preemptable kernel will complain. [...] > + gpiochip_remove(&mcu->of_gc.gc); Should check return value. -- Anton Vorontsov email: [EMAIL PROTECTED] irc://irc.freenode.net/bd2 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 4/5] i2c: MPC837xRDB Power Management and GPIO expander driver
On Thu, Mar 27, 2008 at 01:56:11AM +0300, Anton Vorontsov wrote: > On Wed, Mar 26, 2008 at 03:56:37PM -0500, Timur Tabi wrote: > > Anton Vorontsov wrote: > > > > > +config MCU_MPC837XRDB > > > + tristate "MPC837XRDB MCU driver" > > > + depends on I2C && MPC837x_RDB && OF_GPIO > > > > The MPC8349E-mITX also has this chip. Can you include support for that > > board as > > well? > > Well, only if it has the same (or compatible) firmware.. then yes. Ok, they're the same and everything works fine. Except one mitx-specific thing though... on the power-off call I can see that MCU is driving its PTA1 pin low as expected, but the board doesn't turn off. PTA1 pin is wired to the J19 jumper pin1, pin2 is PORESET# and pin3 is RESET#. It doesn't work in both [1-2] and [2-3] positions... This is surely not a software issue though. And just in case, on the board I have the PWR button isn't functional, so this is hw issues (or just need to find another jumper somewhere ;-). Updated patch follows. - - - - From: Anton Vorontsov <[EMAIL PROTECTED]> Subject: [POWERPC] mpc8349emitx/mpc837xrdb: add support for MCU MCU is an external Freescale MC9S08QG8 microcontroller, mainly used to provide soft power-off function, but also exports two GPIOs (wired to the LEDs, but also available from the external headers). Signed-off-by: Anton Vorontsov <[EMAIL PROTECTED]> --- arch/powerpc/boot/dts/mpc8349emitx.dts| 39 - arch/powerpc/boot/dts/mpc8377_rdb.dts | 29 - arch/powerpc/boot/dts/mpc8378_rdb.dts | 29 - arch/powerpc/boot/dts/mpc8379_rdb.dts | 29 - arch/powerpc/platforms/83xx/mpc834x_itx.c |1 + arch/powerpc/platforms/83xx/mpc837x_rdb.c |1 + arch/powerpc/sysdev/fsl_soc.c |1 + 7 files changed, 125 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 9426676..0ad85af 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -51,6 +51,8 @@ [EMAIL PROTECTED] { #address-cells = <1>; #size-cells = <1>; + compatible = "fsl,immr-mpc8349e", "fsl,immr", "fsl,soc", +"simple-bus"; device_type = "soc"; ranges = <0x0 0xe000 0x0010>; reg = <0xe000 0x0200>; @@ -66,11 +68,46 @@ #address-cells = <1>; #size-cells = <0>; cell-index = <0>; - compatible = "fsl-i2c"; + compatible = "fsl-i2c", "simple-bus"; reg = <0x3000 0x100>; interrupts = <14 0x8>; interrupt-parent = <&ipic>; dfsrr; + + [EMAIL PROTECTED] { + device_type = "rtc"; + compatible = "dallas,ds1339"; + reg = <0x68>; + }; + + mcu_pio: [EMAIL PROTECTED] { + #address-cells = <0>; + #size-cells = <0>; + #gpio-cells = <1>; + compatible = "fsl,mc9s08qg8-mpc8349emitx", +"fsl,mcu-mpc8349emitx", +"simple-bus"; + reg = <0x0a>; + gpio-controller; + + [EMAIL PROTECTED] { + compatible = "fsl,mcu-mpc8349emitx-led2", +"gpio-led"; + linux,name = "pwr"; + linux,brightness = <1>; + linux,active-low; + gpios = <&mcu_pio 0>; + }; + + [EMAIL PROTECTED] { + compatible = "fsl,mcu-mpc8349emitx-led1", +"gpio-led"; + linux,name = "hdd"; + linux,default-trigger = "ide-disk"; + linux,active-low; + gpios = <&mcu_pio 1>; + }; + }; }; [EMAIL PROTECTED] { diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 440aa4d..20d7e29 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -111,7 +111,7 @@ #address-cells = <1>;
Re: [PATCH 4/5] i2c: MPC837xRDB Power Management and GPIO expander driver
On Wed, Mar 26, 2008 at 11:25:11PM +0300, Anton Vorontsov wrote: > On the MPC837xRDB boards there is MC9S08QG8 (MCU) chip with the custom > firmware pre-programmed. This firmware offers to control some of the MCU > GPIO pins via I2C (two pins, connected to the LEDs, but also available > from the J28 and J43 headers, plus another (third) pin is a GPIO as well > but on this board it is reserved for Power-Off function). MCU have some > other functions, but these are not implemented yet. > > Signed-off-by: Anton Vorontsov <[EMAIL PROTECTED]> > --- > > This patch depends on the not yet applied OF/PowerPC GPIO patches, so > please consider this for RFC only. > > Thanks. Since the same chip with the identical firmware also found on the MPC8349E-mITXE board (thanks to Timur Tabi for noticing) here is an updated patch. MPC8349E-mITX board predates MPC837X-RDB boards, so I renamed this driver to mcu_mpc8349emitx. - - - - From: Anton Vorontsov <[EMAIL PROTECTED]> Subject: i2c: MPC8349E-mITX/MPC837x-RDB Power Management and GPIO expander driver On the MPC8349E-mITX and MPC837x-RDB boards there is MC9S08QG8 (MCU) chip with the custom firmware pre-programmed. This firmware offers to control some of the MCU GPIO pins (used for LEDs and soft power-off) via I2C. MCU have some other functions, but these are not implemented yet. Signed-off-by: Anton Vorontsov <[EMAIL PROTECTED]> --- drivers/i2c/chips/Kconfig| 11 ++ drivers/i2c/chips/Makefile |1 + drivers/i2c/chips/mcu_mpc8349emitx.c | 189 ++ 3 files changed, 201 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/chips/mcu_mpc8349emitx.c diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 09d4937..d3e3bfb 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -150,4 +150,15 @@ config OZ99X This driver can also be built as a module. If so, the module will be called oz99x. +config MCU_MPC8349EMITX + tristate "MPC8349E-mITX/MPC837X-RDB MCU driver" + depends on I2C && (MPC834x_ITX || MPC837x_RDB) + select GENERIC_GPIO + select HAVE_GPIO_LIB + help + Say Y here to enable soft power-off functionality on the Freescale + MPC8349E-mITX and MPC837X-RDB boards, plus this driver will register + MCU GPIOs as a generic GPIO API chip, so you'll able to use some MCU + pins as a GPIOs and LEDs. + endmenu diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index c69f891..89c92df 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_TPS65010)+= tps65010.o obj-$(CONFIG_MENELAUS) += menelaus.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_OZ99X)+= oz99x.o +obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/i2c/chips/mcu_mpc8349emitx.c b/drivers/i2c/chips/mcu_mpc8349emitx.c new file mode 100644 index 000..b90dbe9 --- /dev/null +++ b/drivers/i2c/chips/mcu_mpc8349emitx.c @@ -0,0 +1,189 @@ +/* + * MPC8349E-mITX/MPC837x-RDB Power Management and GPIO expander driver + * + * On the MPC8349E-mITX and MPC837x-RDB boards there is MC9S08QG8 (MCU) chip + * with the custom firmware pre-programmed. This firmware offers to control + * some of the MCU GPIO pins (used for LEDs and soft power-off) via I2C. MCU + * have some other functions, but these are not implemented yet. + * + * Copyright (c) 2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +/* + * I don't have specifications for the MCU firmware that is used on the + * MPC8349E-mITX/MPC837XRDB boards, I found this register and bits positions + * by the trial&error method. + */ +#define MCU_REG_CTRL 0x20 +#define MCU_CTRL_POFF 0x40 +#define MCU_NUM_GPIO 2 + +struct mcu { + spinlock_t lock; + struct device_node *np; + struct i2c_client *client; + struct of_gpio_chip of_gc; + u8 reg_ctrl; +}; + +static struct mcu *glob_mcu; + +static void mcu_power_off(void) +{ + struct mcu *mcu = glob_mcu; + + pr_info("Sending power-off request to the MCU...\n"); + spin_lock(&mcu->lock); + i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL, + mcu->reg_ctrl | MCU_CTRL_POFF); + spin_unlock(&mcu->lock); +} + +static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); + struct mcu *mcu = container_of(of_gc, struct mcu, of_gc);
Re: [PATCH 4/5] i2c: MPC837xRDB Power Management and GPIO expander driver
On Wed, Mar 26, 2008 at 03:56:37PM -0500, Timur Tabi wrote: > Anton Vorontsov wrote: > > > +config MCU_MPC837XRDB > > + tristate "MPC837XRDB MCU driver" > > + depends on I2C && MPC837x_RDB && OF_GPIO > > The MPC8349E-mITX also has this chip. Can you include support for that board > as > well? Well, only if it has the same (or compatible) firmware.. then yes. Thanks for the info, I'll look into this. -- Anton Vorontsov email: [EMAIL PROTECTED] irc://irc.freenode.net/bd2 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 4/5] i2c: MPC837xRDB Power Management and GPIO expander driver
Anton Vorontsov wrote: > +config MCU_MPC837XRDB > + tristate "MPC837XRDB MCU driver" > + depends on I2C && MPC837x_RDB && OF_GPIO The MPC8349E-mITX also has this chip. Can you include support for that board as well? -- Timur Tabi Linux kernel developer at Freescale ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 4/5] i2c: MPC837xRDB Power Management and GPIO expander driver
On the MPC837xRDB boards there is MC9S08QG8 (MCU) chip with the custom firmware pre-programmed. This firmware offers to control some of the MCU GPIO pins via I2C (two pins, connected to the LEDs, but also available from the J28 and J43 headers, plus another (third) pin is a GPIO as well but on this board it is reserved for Power-Off function). MCU have some other functions, but these are not implemented yet. Signed-off-by: Anton Vorontsov <[EMAIL PROTECTED]> --- This patch depends on the not yet applied OF/PowerPC GPIO patches, so please consider this for RFC only. Thanks. drivers/i2c/chips/Kconfig |9 ++ drivers/i2c/chips/Makefile |1 + drivers/i2c/chips/mcu_mpc837xrdb.c | 185 3 files changed, 195 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/chips/mcu_mpc837xrdb.c diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 09d4937..db81018 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -150,4 +150,13 @@ config OZ99X This driver can also be built as a module. If so, the module will be called oz99x. +config MCU_MPC837XRDB + tristate "MPC837XRDB MCU driver" + depends on I2C && MPC837x_RDB && OF_GPIO + help + Say Y here to enable soft power-off functionality on the Freescale + MPC837X-RDB boards, plus this driver will register MCU GPIOs as a + generic GPIO API chip, so you'll able to use MCU1 and MCU2 as GPIOs + and LEDs. + endmenu diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index c69f891..bbe7495 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_TPS65010)+= tps65010.o obj-$(CONFIG_MENELAUS) += menelaus.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_OZ99X)+= oz99x.o +obj-$(CONFIG_MCU_MPC837XRDB) += mcu_mpc837xrdb.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/i2c/chips/mcu_mpc837xrdb.c b/drivers/i2c/chips/mcu_mpc837xrdb.c new file mode 100644 index 000..a461c0e --- /dev/null +++ b/drivers/i2c/chips/mcu_mpc837xrdb.c @@ -0,0 +1,190 @@ +/* + * MPC837xRDB Power Management and GPIO expander driver + * + * On the MPC837xRDB boards there is MC9S08QG8 (MCU) chip with the custom + * firmware pre-programmed. This firmware offers to control some of the MCU + * GPIO pins via I2C (two pins, connected to the LEDs, but also available + * from the J28 and J43 headers, plus another (third) pin is a GPIO as well + * but on this board it is reserved for Power-Off function). MCU have some + * other functions, but these are not implemented yet. + * + * Copyright (c) 2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +/* + * I don't have specifications for the MCU firmware that is used on the + * MPC837XRDB board, I found this register and bits positions by the + * trial&error method. + */ +#define MCU_REG_CTRL 0x20 +#define MCU_CTRL_POFF 0x40 +#define MCU_NUM_GPIO 2 + +struct mcu { + spinlock_t lock; + struct device_node *np; + struct i2c_client *client; + struct of_gpio_chip of_gc; + u8 reg_ctrl; +}; + +static struct mcu *glob_mcu; + +static void mcu_power_off(void) +{ + struct mcu *mcu = glob_mcu; + + pr_info("Sending power-off request to the MCU...\n"); + spin_lock(&mcu->lock); + i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL, + mcu->reg_ctrl | MCU_CTRL_POFF); + spin_unlock(&mcu->lock); +} + +static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); + struct mcu *mcu = container_of(of_gc, struct mcu, of_gc); + u8 bit = 1 << (4 + gpio); + + spin_lock(&mcu->lock); + if (val) + mcu->reg_ctrl |= bit; + else + mcu->reg_ctrl &= ~bit; + + i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, mcu->reg_ctrl); + spin_unlock(&mcu->lock); +} + +static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + mcu_gpio_set(gc, gpio, val); + return 0; +} + +static int mcu_gpiochip_add(struct mcu *mcu) +{ + struct device_node *np; + struct of_gpio_chip *of_gc = &mcu->of_gc; + struct gpio_chip *gc = &of_gc->gc; + + np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc837xrdb"); + if (!np) + return -ENODEV; + + gc->label = np->full_name; + gc->can_sleep = 1; + gc->ngpio = MCU