[MeeGo-Dev][PATCH v2] Topcliff: Update PCH_I2C driver to 2.6.35

2010-09-16 Thread Masayuki Ohtak
I2C driver of Topcliff PCH

Topcliff PCH is the platform controller hub that is going to be used in
Intel's upcoming general embedded platform. All IO peripherals in
Topcliff PCH are actually devices sitting on AMBA bus. 
Topcliff PCH has I2C I/F. Using this I/F, it is able to access system
devices connected to I2C.

Signed-off-by: Masayuki Ohtake masa-k...@dsn.okisemi.com
Reviewed-by: Linus Walleij linus.wall...@stericsson.com
---
 drivers/i2c/busses/Kconfig   |8 +
 drivers/i2c/busses/Makefile  |1 +
 drivers/i2c/busses/i2c-pch.c |  908 ++
 3 files changed, 917 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-pch.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index bceafbf..b7b132d 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -613,6 +613,14 @@ config I2C_XILINX
  This driver can also be built as a module.  If so, the module
  will be called xilinx_i2c.
 
+config PCH_I2C
+   tristate PCH I2C of Intel Topcliff
+   depends on PCI
+   help
+ This driver is for PCH(Platform controller Hub) I2C of Topcliff which
+ is an IOH(Input/Output Hub) for x86 embedded processor.
+ This driver can access PCH I2C bus device.
+
 comment External I2C/SMBus adapter drivers
 
 config I2C_PARPORT
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 936880b..aa04135 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_I2C_STU300)  += i2c-stu300.o
 obj-$(CONFIG_I2C_VERSATILE)+= i2c-versatile.o
 obj-$(CONFIG_I2C_OCTEON)   += i2c-octeon.o
 obj-$(CONFIG_I2C_XILINX)   += i2c-xiic.o
+obj-$(CONFIG_PCH_I2C)  += i2c-pch.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_PARPORT)  += i2c-parport.o
diff --git a/drivers/i2c/busses/i2c-pch.c b/drivers/i2c/busses/i2c-pch.c
new file mode 100644
index 000..37491d7
--- /dev/null
+++ b/drivers/i2c/busses/i2c-pch.c
@@ -0,0 +1,908 @@
+/*
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/delay.h
+#include linux/init.h
+#include linux/errno.h
+#include linux/i2c.h
+#include linux/fs.h
+#include linux/io.h
+#include linux/types.h
+#include linux/interrupt.h
+#include linux/jiffies.h
+#include linux/pci.h
+#include linux/mutex.h
+#include linux/ktime.h
+
+#define PCH_EVENT_SET  0   /* I2C Interrupt Event Set Status */
+#define PCH_EVENT_NONE 1   /* I2C Interrupt Event Clear Status */
+#define PCH_MAX_CLK10  /* Maximum Clock speed in MHz */
+#define PCH_BUFFER_MODE_ENABLE 0x0002  /* flag for Buffer mode enable */
+#define PCH_EEPROM_SW_RST_MODE_ENABLE  0x0008  /* EEPROM SW RST enable flag */
+
+#define PCH_I2CSADR0x00/* I2C slave address register */
+#define PCH_I2CCTL 0x04/* I2C control register */
+#define PCH_I2CSR  0x08/* I2C status register */
+#define PCH_I2CDR  0x0C/* I2C data register */
+#define PCH_I2CMON 0x10/* I2C bus monitor register */
+#define PCH_I2CBC  0x14/* I2C bus transfer rate setup counter */
+#define PCH_I2CMOD 0x18/* I2C mode register */
+#define PCH_I2CBUFSLV  0x1C/* I2C buffer mode slave address register */
+#define PCH_I2CBUFSUB  0x20/* I2C buffer mode subaddress register */
+#define PCH_I2CBUFFOR  0x24/* I2C buffer mode format register */
+#define PCH_I2CBUFCTL  0x28/* I2C buffer mode control register */
+#define PCH_I2CBUFMSK  0x2C/* I2C buffer mode interrupt mask register */
+#define PCH_I2CBUFSTA  0x30/* I2C buffer mode status register */
+#define PCH_I2CBUFLEV  0x34/* I2C buffer mode level register */
+#define PCH_I2CESRFOR  0x38/* EEPROM software reset mode format register */
+#define PCH_I2CESRCTL  0x3C/* EEPROM software reset mode ctrl register */
+#define PCH_I2CESRMSK  0x40/* EEPROM software reset mode */
+#define PCH_I2CESRSTA  0x44/* EEPROM software reset mode status register */
+#define PCH_I2CTMR 0x48/* I2C timer register */
+#define PCH_I2CSRST0xFC/* I2C reset register */
+#define PCH_I2CNF  0xF8/* I2C noise filter register */
+
+#define BUS_IDLE_TIMEOUT   20
+#define 

[PATCH 1/4] leds: driver for National Semiconductor LP5521 chip

2010-09-16 Thread Samu Onkalo
LP5521 chip is three channel led driver with programmable engines.
Driver provides support for that chip for direct access via led class or
via programmable engines.

Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com
---
 drivers/leds/leds-lp5521.c  |  820 +++
 include/linux/leds-lp5521.h |   46 +++
 2 files changed, 866 insertions(+), 0 deletions(-)
 create mode 100644 drivers/leds/leds-lp5521.c
 create mode 100644 include/linux/leds-lp5521.h

diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
new file mode 100644
index 000..f57adb0
--- /dev/null
+++ b/drivers/leds/leds-lp5521.c
@@ -0,0 +1,820 @@
+/*
+ * LP5521 LED chip driver.
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Samu Onkalo samu.p.onk...@nokia.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include linux/module.h
+#include linux/init.h
+#include linux/i2c.h
+#include linux/mutex.h
+#include linux/gpio.h
+#include linux/interrupt.h
+#include linux/delay.h
+#include linux/ctype.h
+#include linux/spinlock.h
+#include linux/wait.h
+#include linux/leds.h
+#include linux/leds-lp5521.h
+#include linux/workqueue.h
+#include linux/slab.h
+
+#define LP5521_PROGRAM_LENGTH  32  /* in bytes */
+
+#define LP5521_MAX_LEDS3   /* Maximum number of 
LEDs */
+#define LP5521_MAX_ENGINES 3   /* Maximum number of engines */
+
+#define LP5521_ENG_MASK_BASE   0x30/* 0011 */
+#define LP5521_ENG_STATUS_MASK 0x07/* 0111 */
+
+#define LP5521_CMD_LOAD0x15/* 00010101 */
+#define LP5521_CMD_RUN 0x2a/* 00101010 */
+#define LP5521_CMD_DIRECT  0x3f/* 0011 */
+#define LP5521_CMD_DISABLED0x00/*  */
+
+/* Registers */
+#define LP5521_REG_ENABLE  0x00
+#define LP5521_REG_OP_MODE 0x01
+#define LP5521_REG_R_PWM   0x02
+#define LP5521_REG_G_PWM   0x03
+#define LP5521_REG_B_PWM   0x04
+#define LP5521_REG_R_CURRENT   0x05
+#define LP5521_REG_G_CURRENT   0x06
+#define LP5521_REG_B_CURRENT   0x07
+#define LP5521_REG_CONFIG  0x08
+#define LP5521_REG_R_CHANNEL_PC0x09
+#define LP5521_REG_G_CHANNEL_PC0x0A
+#define LP5521_REG_B_CHANNEL_PC0x0B
+#define LP5521_REG_STATUS  0x0C
+#define LP5521_REG_RESET   0x0D
+#define LP5521_REG_GPO 0x0E
+#define LP5521_REG_R_PROG_MEM  0x10
+#define LP5521_REG_G_PROG_MEM  0x30
+#define LP5521_REG_B_PROG_MEM  0x50
+
+#define LP5521_PROG_MEM_BASE   LP5521_REG_R_PROG_MEM
+#define LP5521_PROG_MEM_SIZE   0x20
+
+/* Base register to set LED current */
+#define LP5521_REG_LED_CURRENT_BASELP5521_REG_R_CURRENT
+
+/* Base register to set the brightness */
+#define LP5521_REG_LED_PWM_BASELP5521_REG_R_PWM
+
+/* Bits in ENABLE register */
+#define LP5521_MASTER_ENABLE   0x40/* Chip master enable */
+#define LP5521_LOGARITHMIC_PWM 0x80/* Logarithmic PWM adjustment */
+#define LP5521_EXEC_RUN0x2A
+
+/* Bits in CONFIG register */
+#define LP5521_PWM_HF  0x40/* PWM: 0 = 256Hz, 1 = 558Hz */
+#define LP5521_PWRSAVE_EN  0x20/* 1 = Power save mode */
+#define LP5521_CP_MODE_OFF 0   /* Charge pump (CP) off */
+#define LP5521_CP_MODE_BYPASS  8   /* CP forced to bypass mode */
+#define LP5521_CP_MODE_1X5 0x10/* CP forced to 1.5x mode */
+#define LP5521_CP_MODE_AUTO0x18/* Automatic mode selection */
+#define LP5521_R_TO_BATT   4   /* R out: 0 = CP, 1 = Vbat */
+#define LP5521_CLK_SRC_EXT 0   /* Ext-clk source (CLK_32K) */
+#define LP5521_CLK_INT 1   /* Internal clock */
+#define LP5521_CLK_AUTO2   /* Automatic clock 
selection */
+
+/* Status */
+#define LP5521_EXT_CLK_USED0x08
+
+struct lp5521_engine {
+   const struct attribute_group *attributes;
+   int id;
+   u8  mode;
+   u8  prog_page;
+   u8  engine_mask;
+};
+
+struct lp5521_led {
+   int  

[PATCH 2/4] leds: Driver for National Semiconductors LP5523 chip

2010-09-16 Thread Samu Onkalo
LP5523 chip is nine channel led driver with programmable engines.
Driver provides support for that chip for direct access via led class or
via programmable engines.

Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com
---
 drivers/leds/leds-lp5523.c  | 1063 +++
 include/linux/leds-lp5523.h |   46 ++
 2 files changed, 1109 insertions(+), 0 deletions(-)
 create mode 100644 drivers/leds/leds-lp5523.c
 create mode 100644 include/linux/leds-lp5523.h

diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
new file mode 100644
index 000..b255463
--- /dev/null
+++ b/drivers/leds/leds-lp5523.c
@@ -0,0 +1,1063 @@
+/*
+ * lp5523.c - LP5523 LED Driver
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Samu Onkalo samu.p.onk...@nokia.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include linux/module.h
+#include linux/init.h
+#include linux/i2c.h
+#include linux/mutex.h
+#include linux/gpio.h
+#include linux/interrupt.h
+#include linux/delay.h
+#include linux/ctype.h
+#include linux/spinlock.h
+#include linux/wait.h
+#include linux/leds.h
+#include linux/leds-lp5523.h
+#include linux/workqueue.h
+#include linux/slab.h
+
+#define LP5523_REG_ENABLE  0x00
+#define LP5523_REG_OP_MODE 0x01
+#define LP5523_REG_RATIOMETRIC_MSB 0x02
+#define LP5523_REG_RATIOMETRIC_LSB 0x03
+#define LP5523_REG_ENABLE_LEDS_MSB 0x04
+#define LP5523_REG_ENABLE_LEDS_LSB 0x05
+#define LP5523_REG_LED_CNTRL_BASE  0x06
+#define LP5523_REG_LED_PWM_BASE0x16
+#define LP5523_REG_LED_CURRENT_BASE0x26
+#define LP5523_REG_CONFIG  0x36
+#define LP5523_REG_CHANNEL1_PC 0x37
+#define LP5523_REG_CHANNEL2_PC 0x38
+#define LP5523_REG_CHANNEL3_PC 0x39
+#define LP5523_REG_STATUS  0x3a
+#define LP5523_REG_GPO 0x3b
+#define LP5523_REG_VARIABLE0x3c
+#define LP5523_REG_RESET   0x3d
+#define LP5523_REG_TEMP_CTRL   0x3e
+#define LP5523_REG_TEMP_READ   0x3f
+#define LP5523_REG_TEMP_WRITE  0x40
+#define LP5523_REG_LED_TEST_CTRL   0x41
+#define LP5523_REG_LED_TEST_ADC0x42
+#define LP5523_REG_ENG1_VARIABLE   0x45
+#define LP5523_REG_ENG2_VARIABLE   0x46
+#define LP5523_REG_ENG3_VARIABLE   0x47
+#define LP5523_REG_MASTER_FADER1   0x48
+#define LP5523_REG_MASTER_FADER2   0x49
+#define LP5523_REG_MASTER_FADER3   0x4a
+#define LP5523_REG_CH1_PROG_START  0x4c
+#define LP5523_REG_CH2_PROG_START  0x4d
+#define LP5523_REG_CH3_PROG_START  0x4e
+#define LP5523_REG_PROG_PAGE_SEL   0x4f
+#define LP5523_REG_PROG_MEM0x50
+
+#define LP5523_CMD_LOAD0x15 /* 00010101 */
+#define LP5523_CMD_RUN 0x2a /* 00101010 */
+#define LP5523_CMD_DISABLED0x00 /*  */
+
+#define LP5523_ENABLE  0x40
+#define LP5523_AUTO_INC0x40
+#define LP5523_PWR_SAVE0x20
+#define LP5523_PWM_PWR_SAVE0x04
+#define LP5523_CP_10x08
+#define LP5523_CP_1_5  0x10
+#define LP5523_CP_AUTO 0x18
+#define LP5523_INT_CLK 0x01
+#define LP5523_AUTO_CLK0x02
+#define LP5523_EN_LEDTEST  0x80
+#define LP5523_LEDTEST_DONE0x80
+
+#define LP5523_DEFAULT_CURRENT 50 /* microAmps */
+#define LP5523_PROGRAM_LENGTH  32 /* in bytes */
+#define LP5523_PROGRAM_PAGES   6
+#define LP5523_ADC_SHORTCIRC_LIM   80
+
+#define LP5523_LEDS9
+#define LP5523_ENGINES 3
+
+#define LP5523_ENG_MASK_BASE   0x30 /* 0011 */
+
+#define LP5523_ENG_STATUS_MASK  0x07 /* 0111 */
+
+#define LP5523_IRQ_FLAGSIRQF_TRIGGER_FALLING
+
+#define LP5523_EXT_CLK_USED0x08
+
+#define LED_ACTIVE(mux, led)   (!!(mux  (0x0001  led)))
+#define SHIFT_MASK(id) (((id) - 1) * 2)
+
+struct lp5523_engine {
+   const struct attribute_group *attributes;
+   int id;
+   u8  mode;
+   u8  prog_page;
+   u8  mux_page;
+   u16 led_mux;
+   u8  engine_mask;
+};
+
+struct lp5523_led {
+   

[PATCH 0/4] Led driver support for LP5521 and LP5523 chips

2010-09-16 Thread Samu Onkalo
Patch set provides support for LP5521 and LP5523 LED driver chips
from National Semicondutor. Both drivers supports programmable engines
and naturally LED class features.

Documentation is provided as a part of the patch set.
I created leds sub directory to Documentation.
Perhaps rest of the leds* documentation should be moved
there.

Datasheets are freely available at National Semiconductor www pages.

Tested to work in top of 2.6.36-RC4 kernel.

Samu Onkalo (4):
  leds: driver for National Semiconductor LP5521 chip
  leds: Driver for National Semiconductors LP5523 chip
  leds: Update LP552x support Kconfig and Makefile
  Documentation: led drivers lp5521 and lp5523

 Documentation/leds/leds-lp5521.txt |   85 +++
 Documentation/leds/leds-lp5523.txt |   81 +++
 drivers/leds/Kconfig   |   18 +
 drivers/leds/Makefile  |2 +
 drivers/leds/leds-lp5521.c |  820 +++
 drivers/leds/leds-lp5523.c | 1063 
 include/linux/leds-lp5521.h|   46 ++
 include/linux/leds-lp5523.h|   46 ++
 8 files changed, 2161 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/leds/leds-lp5521.txt
 create mode 100644 Documentation/leds/leds-lp5523.txt
 create mode 100644 drivers/leds/leds-lp5521.c
 create mode 100644 drivers/leds/leds-lp5523.c
 create mode 100644 include/linux/leds-lp5521.h
 create mode 100644 include/linux/leds-lp5523.h

--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] Documentation: led drivers lp5521 and lp5523

2010-09-16 Thread Samu Onkalo
Create sub directory Documentation/leds and
add short documentation for LP5521 and LP5523 drivers.

Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com
---
 Documentation/leds/leds-lp5521.txt |   85 
 Documentation/leds/leds-lp5523.txt |   81 ++
 2 files changed, 166 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/leds/leds-lp5521.txt
 create mode 100644 Documentation/leds/leds-lp5523.txt

diff --git a/Documentation/leds/leds-lp5521.txt 
b/Documentation/leds/leds-lp5521.txt
new file mode 100644
index 000..62a8066
--- /dev/null
+++ b/Documentation/leds/leds-lp5521.txt
@@ -0,0 +1,85 @@
+Kernel driver for lp5521
+
+
+* National Semiconductor LP5521 led driver chip
+* Datasheet: http://www.national.com/pf/LP/LP5521.html
+
+Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
+Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
+
+Description
+---
+
+LP5521 can drive up to 3 channels. Leds can be controlled directly via
+led class control interface. Channels have a generic names:
+lp5521:channelx, where x is 0 .. 2
+
+All three channels can be also controlled using engine micro programs.
+More details of the instructions can be found from public data sheet.
+
+Control interface for engines:
+x is 1 .. 3
+enginex_mode : disabled, load, run
+enginex_load : store program (visible only in engine load mode)
+
+Example (start to blink the channel 2 led):
+cd   /sys/class/leds/lp5521:channel2/device
+echo load  engine3_mode
+echo 037f4d0003ff6000  engine3_load
+echo run  engine3_mode
+
+stop the engine:
+echo disabled  engine3_mode
+
+sysfs contains also selftest entry.
+It communicates with the chip and checks that
+clock mode is automatically set to requested one.
+
+Each channel contains led current settings.
+/sys/class/leds/lp5521:channel0/led_current - RW
+/sys/class/leds/lp5521:channel0/max_current - RO
+Format: 10x mA i.e 10 means 1.0 mA
+
+example platform data:
+static struct lp5521_led_config lp5521_led_config[] = {
+{
+.chan_nr= 0,
+.led_current= 50,
+   .max_current= 130,
+}, {
+.chan_nr= 1,
+.led_current= 0,
+   .max_current= 130,
+}, {
+.chan_nr= 2,
+.led_current= 0,
+   .max_current= 130,
+}
+};
+
+static int lp5521_setup(void)
+{
+   /* setup HW resources */
+}
+
+static void lp5521_release(void)
+{
+   /* Release HW resources */
+}
+
+static void lp5521_enable(bool state)
+{
+   /* Control of chip enable signal */
+}
+
+static struct lp5521_platform_data lp5521_platform_data = {
+.led_config = lp5521_led_config,
+.num_channels   = ARRAY_SIZE(lp5521_led_config),
+.clock_mode = LP5521_CLOCK_EXT,
+.setup_resources   = lp5521_setup,
+.release_resources = lp5521_release,
+.enable= lp5521_enable,
+};
+
+If the current is set to 0 in the platform data, that channel is
+disabled and it is not visible in the sysfs.
diff --git a/Documentation/leds/leds-lp5523.txt 
b/Documentation/leds/leds-lp5523.txt
new file mode 100644
index 000..915298d
--- /dev/null
+++ b/Documentation/leds/leds-lp5523.txt
@@ -0,0 +1,81 @@
+Kernel driver for lp5523
+
+
+* National Semiconductor LP5523 led driver chip
+* Datasheet: http://www.national.com/pf/LP/LP5523.html
+
+Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
+Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
+
+Description
+---
+LP5523 can drive up to 9 channels. Leds can be controlled directly via
+led class control interface. Channels have a generic names:
+lp5523:channelx where x is 0...8
+
+Chip provides 3 engines which can be control channels without main CPU
+interaction. Details of the micro engine code can be found from the
+public data sheet. Leds can be muxed to different channels.
+
+Control interface for engines:
+x is 1 .. 3
+enginex_mode : disabled, load, run
+enginex_load : microcode load (visible only in load mode)
+enginex_leds : led mux control (visible only in load mode)
+
+cd /sys/class/leds/lp5523:channel2/device
+echo load  engine3_mode
+echo 9d8044ff05ff437f  engine3_load
+echo 1  engine3_leds
+echo run  engine3_mode
+
+sysfs contains also selftest entry. It measures each channel
+voltage level and checks if it looks reasonable. Too high
+level means missing led and to low value means short circuit.
+Selftest uses always current from platform data.
+
+Each channel contains led current settings.
+/sys/class/leds/lp5523:channel2/led_current - RW
+/sys/class/leds/lp5523:channel2/max_current - RO
+Format: 10x mA i.e 10 means 1.0 mA
+
+Example platform data:
+
+static struct lp5523_led_config lp5523_led_config[] = {
+{
+.chan_nr= 0,
+.led_current= 

[PATCH 3/4] leds: Update LP552x support Kconfig and Makefile

2010-09-16 Thread Samu Onkalo
Provide configuration and compilation support for LP5521 and LP5523

Signed-off-by: Samu Onkalo samu.p.onk...@nokia.com
---
 drivers/leds/Kconfig  |   18 ++
 drivers/leds/Makefile |2 ++
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index e411262..c789087 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -176,6 +176,24 @@ config LEDS_LP3944
  To compile this driver as a module, choose M here: the
  module will be called leds-lp3944.
 
+config LEDS_LP5521
+   tristate LED Support for N.S. LP5521 LED driver chip
+   depends on LEDS_CLASS  I2C
+   help
+ If you say yes here you get support for the National Semiconductor
+ LP5521 LED driver. It is 3 channel chip with programmable engines.
+ Driver provides direct control via LED class and interface for
+ programming the engines.
+
+config LEDS_LP5523
+   tristate LED Support for N.S. LP5523 LED driver chip
+   depends on LEDS_CLASS  I2C
+   help
+ If you say yes here you get support for the National Semiconductor
+ LP5523 LED driver. It is 9 channel chip with programmable engines.
+ Driver provides direct control via LED class and interface for
+ programming the engines.
+
 config LEDS_CLEVO_MAIL
tristate Mail LED on Clevo notebook
depends on X86  SERIO_I8042  DMI
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 7d6b958..2ba98f6 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -23,6 +23,8 @@ obj-$(CONFIG_LEDS_SUNFIRE)+= leds-sunfire.o
 obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o
 obj-$(CONFIG_LEDS_GPIO)+= leds-gpio.o
 obj-$(CONFIG_LEDS_LP3944)  += leds-lp3944.o
+obj-$(CONFIG_LEDS_LP5521)  += leds-lp5521.o
+obj-$(CONFIG_LEDS_LP5523)  += leds-lp5523.o
 obj-$(CONFIG_LEDS_CLEVO_MAIL)  += leds-clevo-mail.o
 obj-$(CONFIG_LEDS_HP6XX)   += leds-hp6xx.o
 obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
-- 
1.6.0.4

--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2] staging: iio: tmd2771x: Add tmd2771x proximity and ambient light sensor driver

2010-09-16 Thread Jonathan Cameron
On 09/15/10 07:32, Donggeun Kim wrote:
 Changes from V1 to V2:
 - I2C read and write wrapping functions are removed.
 - The error handling routines are inserted.
 - The similar functions are created by macro invocation.
 - Some attribute names are changed.
 - Some event attribute names are changed.
 - The comments are added to the code to explain the non standard attributes
   and fields of the platform data.
 
 This driver supports TAOS TMD27711 and TMD27713
 proximity and ambient light sensor.
 When threshold condition for proximity or ambient light sensor is satisfied,
 an event is generated.
 The proximity raw value is exported through the 'proximity_raw' attribute.
 This driver uses 'illuminance0_input' attribute to export lux value by
 calculating ch0 and ch1 ADC values.
Hi,

Most of the comments inline are observations rather than requests that you 
change
anything.  You certainly like your macros!   I'll cleanup the naming of the 
event codes along with all the others in the tree so don't worry about that, 
except
to the extent that it may change and break your userspace code.

I think you have a race condition in your interrupt handler.  Please check that
and fix if necessary.  Also, I don't think you use anything from gpio.h so 
please
remove that. Otherwise, I'm happy so having cleaned up those two issues please 
add

Acked-by: Jonathan Cameron ji...@cam.ac.uk

and send on to Greg KH g...@kroah.com

 
 Signed-off-by: Donggeun Kim dg77@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 ---
  drivers/staging/iio/light/Kconfig|   11 +
  drivers/staging/iio/light/Makefile   |1 +
  drivers/staging/iio/light/tmd2771x.c |  706 
 ++
  drivers/staging/iio/light/tmd2771x.h |  169 
  drivers/staging/iio/sysfs.h  |3 +
  5 files changed, 890 insertions(+), 0 deletions(-)
  create mode 100644 drivers/staging/iio/light/tmd2771x.c
  create mode 100644 drivers/staging/iio/light/tmd2771x.h
 
 diff --git a/drivers/staging/iio/light/Kconfig 
 b/drivers/staging/iio/light/Kconfig
 index 3ddc478..ecf8e09 100644
 --- a/drivers/staging/iio/light/Kconfig
 +++ b/drivers/staging/iio/light/Kconfig
 @@ -12,3 +12,14 @@ config SENSORS_TSL2563
  
This driver can also be built as a module.  If so, the module
will be called tsl2563.
 +
 +config SENSORS_TMD2771X
I'll repeat that I'm anti wild cards in names.  These tend to become pretty 
much set
in stone once the merge occurs.  Do you have a really strong reason to believe 
TAOS
will not release either a chip outside this range that is compatible or one 
inside
the range that isn't?

 + tristate TAOS TMD2771X proximity and ambient light sensor
 + depends on I2C
 + help
 +  If you say yes here you get support for TAOS TMD27711, TMD27713
 +  proximity and ambient light sensor.
 +
 +  This driver can also be built as a module. If so, the module
 +  will be called tmd2771x.
 +
 diff --git a/drivers/staging/iio/light/Makefile 
 b/drivers/staging/iio/light/Makefile
 index 30f3300..03b0d10 100644
 --- a/drivers/staging/iio/light/Makefile
 +++ b/drivers/staging/iio/light/Makefile
 @@ -3,3 +3,4 @@
  #
  
  obj-$(CONFIG_SENSORS_TSL2563)+= tsl2563.o
 +obj-$(CONFIG_SENSORS_TMD2771X)   += tmd2771x.o
 diff --git a/drivers/staging/iio/light/tmd2771x.c 
 b/drivers/staging/iio/light/tmd2771x.c
 new file mode 100644
 index 000..7343d6c
 --- /dev/null
 +++ b/drivers/staging/iio/light/tmd2771x.c
 @@ -0,0 +1,706 @@
 +/*
 + *  tmd2771x.c - Texas Advanced Optoelectronic Solutions Inc.
 + *Proximity/Ambient light sensor
 + *
 + *  Copyright (C) 2010 Samsung Electronics
 + *  Donggeun Kim dg77@samsung.com
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +
 +#include linux/module.h
 +#include linux/init.h
 +#include linux/interrupt.h
 +#include linux/platform_device.h
 +#include linux/workqueue.h
 +#include linux/mutex.h
 +#include linux/err.h
 +#include linux/i2c.h
 +#include linux/delay.h
not seeing any calls to gpio functions in the code. 
 +#include linux/gpio.h
 +#include linux/slab.h
 +#include ../iio.h
 +#include light.h
 +#include tmd2771x.h
 +
 +struct tmd2771x_chip {
 + struct i2c_client   *client;
 + struct iio_dev  *indio_dev;
 + struct work_struct  work_thresh;
 + s64 last_timestamp;
 + struct mutexlock;
 +
 + struct tmd2771x_platform_data   *pdata;
 +};
 +
This heavy use of macros is a little unconventional, but it should work
fine. The only real issue is that it will (I think) add a fair bit of
bloat to the resulting binary size.

It looks to me like a lot of this could be avoided by putting the cleverness
of all these macros into the top level calling ones 

[PATCH] i2c: davinci: Fix race when setting up for TX

2010-09-16 Thread Jon Povey
When setting up to transmit, a race exists between the ISR and
i2c_davinci_xfer_msg() trying to load the first byte and adjust counters.
This is mostly visible for transmits  1 byte long.

The ISR may run at any time after the mode register has been set.
While we are setting up and loading the first byte, protect this critical
section from the ISR with a spinlock.

The RX path or zero-length transmits do not need this locking.

Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985

Signed-off-by: Jon Povey jon.po...@racelogic.co.uk
---
I suspect this hasn't shown up for others using single-byte transmits as the
interrupt tends to either run entirely before or entirely after this block
in i2c_davinci_xfer_msg():

/*
 * First byte should be set here, not after interrupt,
 * because transmit-data-ready interrupt can come before
 * NACK-interrupt during sending of previous message and
 * ICDXR may have wrong data
 */
if ((!(msg-flags  I2C_M_RD))  dev-buf_len) {
davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev-buf++);
dev-buf_len--;
}

Often the entire message would be sent before that test was executed
(observed with LED wiggling and a logic analyser), so dev-buf_len would
be untrue and things merrily went on their way. That seems to be counter
to the intent in the comment.

I tried some fiddling around reordering the register loads but couldn't
get things reliable so stuck in a spinlock. Better solutions welcome.

P.S.: Having run into the the bus reset code a lot during testing, I
am pretty sure that that generic_i2c_clock_pulse() does NOTHING due to
pinmuxing, at least on DM355, it is misleading and may be better
replaced with a comment saying It would be great to toggle SCL here.

 drivers/i2c/busses/i2c-davinci.c |   21 -
 1 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index c87..43aa55d 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -107,6 +107,7 @@ struct davinci_i2c_dev {
u8  *buf;
size_t  buf_len;
int irq;
+   spinlock_t  lock;
int stop;
u8  terminate;
struct i2c_adapter  adapter;
@@ -312,6 +313,8 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
i2c_msg *msg, int stop)
u32 flag;
u16 w;
int r;
+   unsigned long flags;
+   int preload = 0;
 
if (!pdata)
pdata = davinci_i2c_platform_data_default;
@@ -347,6 +350,15 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
i2c_msg *msg, int stop)
flag = ~DAVINCI_I2C_MDR_STP;
}
 
+   /*
+* When transmitting, lock ISR out to avoid it racing on the buffer and
+* DXR register before we are done
+*/
+   if ((!(msg-flags  I2C_M_RD))  dev-buf_len) {
+   preload = 1;
+   spin_lock_irqsave(dev-lock, flags);
+   }
+
/* Enable receive or transmit interrupts */
w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
if (msg-flags  I2C_M_RD)
@@ -366,13 +378,15 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
i2c_msg *msg, int stop)
 * NACK-interrupt during sending of previous message and
 * ICDXR may have wrong data
 */
-   if ((!(msg-flags  I2C_M_RD))  dev-buf_len) {
+   if (preload) {
davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev-buf++);
dev-buf_len--;
+   spin_unlock_irqrestore(dev-lock, flags);
}
 
r = wait_for_completion_interruptible_timeout(dev-cmd_complete,
  dev-adapter.timeout);
+
if (r == 0) {
dev_err(dev-dev, controller timed out\n);
i2c_recover_bus(dev);
@@ -490,6 +504,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void 
*dev_id)
int count = 0;
u16 w;
 
+   spin_lock(dev-lock);
+
while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
dev_dbg(dev-dev, %s: stat=0x%x\n, __func__, stat);
if (count++ == 100) {
@@ -579,6 +595,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void 
*dev_id)
}
}
 
+   spin_unlock(dev-lock);
+
return count ? IRQ_HANDLED : IRQ_NONE;
 }
 
@@ -662,6 +680,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
goto err_release_region;
}
 
+   spin_lock_init(dev-lock);
init_completion(dev-cmd_complete);
 #ifdef CONFIG_CPU_FREQ
init_completion(dev-xfr_complete);
-- 
1.6.3.3

--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to 

Re: [PATCH] i2c: davinci: Fix race when setting up for TX

2010-09-16 Thread Kevin Hilman
Jon Povey jon.po...@racelogic.co.uk writes:

 When setting up to transmit, a race exists between the ISR and
 i2c_davinci_xfer_msg() trying to load the first byte and adjust counters.
 This is mostly visible for transmits  1 byte long.

 The ISR may run at any time after the mode register has been set.
 While we are setting up and loading the first byte, protect this critical
 section from the ISR with a spinlock.

 The RX path or zero-length transmits do not need this locking.

 Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985

 Signed-off-by: Jon Povey jon.po...@racelogic.co.uk

This looks like a good fix. 

Anyone else care to test on other platforms and add a 'Tested-by'?

Thanks,

Kevin

 ---
 I suspect this hasn't shown up for others using single-byte transmits as the
 interrupt tends to either run entirely before or entirely after this block
 in i2c_davinci_xfer_msg():

   /*
* First byte should be set here, not after interrupt,
* because transmit-data-ready interrupt can come before
* NACK-interrupt during sending of previous message and
* ICDXR may have wrong data
*/
   if ((!(msg-flags  I2C_M_RD))  dev-buf_len) {
   davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev-buf++);
   dev-buf_len--;
   }

 Often the entire message would be sent before that test was executed
 (observed with LED wiggling and a logic analyser), so dev-buf_len would
 be untrue and things merrily went on their way. That seems to be counter
 to the intent in the comment.

 I tried some fiddling around reordering the register loads but couldn't
 get things reliable so stuck in a spinlock. Better solutions welcome.

 P.S.: Having run into the the bus reset code a lot during testing, I
 am pretty sure that that generic_i2c_clock_pulse() does NOTHING due to
 pinmuxing, at least on DM355, it is misleading and may be better
 replaced with a comment saying It would be great to toggle SCL here.

  drivers/i2c/busses/i2c-davinci.c |   21 -
  1 files changed, 20 insertions(+), 1 deletions(-)

 diff --git a/drivers/i2c/busses/i2c-davinci.c 
 b/drivers/i2c/busses/i2c-davinci.c
 index c87..43aa55d 100644
 --- a/drivers/i2c/busses/i2c-davinci.c
 +++ b/drivers/i2c/busses/i2c-davinci.c
 @@ -107,6 +107,7 @@ struct davinci_i2c_dev {
   u8  *buf;
   size_t  buf_len;
   int irq;
 + spinlock_t  lock;
   int stop;
   u8  terminate;
   struct i2c_adapter  adapter;
 @@ -312,6 +313,8 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
 i2c_msg *msg, int stop)
   u32 flag;
   u16 w;
   int r;
 + unsigned long flags;
 + int preload = 0;
  
   if (!pdata)
   pdata = davinci_i2c_platform_data_default;
 @@ -347,6 +350,15 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
 i2c_msg *msg, int stop)
   flag = ~DAVINCI_I2C_MDR_STP;
   }
  
 + /*
 +  * When transmitting, lock ISR out to avoid it racing on the buffer and
 +  * DXR register before we are done
 +  */
 + if ((!(msg-flags  I2C_M_RD))  dev-buf_len) {
 + preload = 1;
 + spin_lock_irqsave(dev-lock, flags);
 + }
 +
   /* Enable receive or transmit interrupts */
   w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
   if (msg-flags  I2C_M_RD)
 @@ -366,13 +378,15 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
 i2c_msg *msg, int stop)
* NACK-interrupt during sending of previous message and
* ICDXR may have wrong data
*/
 - if ((!(msg-flags  I2C_M_RD))  dev-buf_len) {
 + if (preload) {
   davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev-buf++);
   dev-buf_len--;
 + spin_unlock_irqrestore(dev-lock, flags);
   }
  
   r = wait_for_completion_interruptible_timeout(dev-cmd_complete,
 dev-adapter.timeout);
 +
   if (r == 0) {
   dev_err(dev-dev, controller timed out\n);
   i2c_recover_bus(dev);
 @@ -490,6 +504,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void 
 *dev_id)
   int count = 0;
   u16 w;
  
 + spin_lock(dev-lock);
 +
   while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
   dev_dbg(dev-dev, %s: stat=0x%x\n, __func__, stat);
   if (count++ == 100) {
 @@ -579,6 +595,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void 
 *dev_id)
   }
   }
  
 + spin_unlock(dev-lock);
 +
   return count ? IRQ_HANDLED : IRQ_NONE;
  }
  
 @@ -662,6 +680,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
   goto err_release_region;
   }
  
 + spin_lock_init(dev-lock);
   init_completion(dev-cmd_complete);
  #ifdef CONFIG_CPU_FREQ
   

Re: [PATCH] i2c: davinci: Fix race when setting up for TX

2010-09-16 Thread Troy Kisky
On 9/16/2010 10:37 AM, Kevin Hilman wrote:
 Jon Povey jon.po...@racelogic.co.uk writes:
 
 When setting up to transmit, a race exists between the ISR and
 i2c_davinci_xfer_msg() trying to load the first byte and adjust counters.
 This is mostly visible for transmits  1 byte long.

 The ISR may run at any time after the mode register has been set.
 While we are setting up and loading the first byte, protect this critical
 section from the ISR with a spinlock.

 The RX path or zero-length transmits do not need this locking.

 Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985

 Signed-off-by: Jon Povey jon.po...@racelogic.co.uk
 
 This looks like a good fix. 
 
 Anyone else care to test on other platforms and add a 'Tested-by'?
 
 Thanks,
 
 Kevin
 
 ---
 I suspect this hasn't shown up for others using single-byte transmits as the
 interrupt tends to either run entirely before or entirely after this block
 in i2c_davinci_xfer_msg():

  /*
   * First byte should be set here, not after interrupt,
   * because transmit-data-ready interrupt can come before
   * NACK-interrupt during sending of previous message and
   * ICDXR may have wrong data
   */
  if ((!(msg-flags  I2C_M_RD))  dev-buf_len) {
  davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev-buf++);
  dev-buf_len--;
  }

 Often the entire message would be sent before that test was executed
 (observed with LED wiggling and a logic analyser), so dev-buf_len would
 be untrue and things merrily went on their way. That seems to be counter
 to the intent in the comment.

 I tried some fiddling around reordering the register loads but couldn't
 get things reliable so stuck in a spinlock. Better solutions welcome.

 P.S.: Having run into the the bus reset code a lot during testing, I
 am pretty sure that that generic_i2c_clock_pulse() does NOTHING due to
 pinmuxing, at least on DM355, it is misleading and may be better
 replaced with a comment saying It would be great to toggle SCL here.

  drivers/i2c/busses/i2c-davinci.c |   21 -
  1 files changed, 20 insertions(+), 1 deletions(-)

 diff --git a/drivers/i2c/busses/i2c-davinci.c 
 b/drivers/i2c/busses/i2c-davinci.c
 index c87..43aa55d 100644
 --- a/drivers/i2c/busses/i2c-davinci.c
 +++ b/drivers/i2c/busses/i2c-davinci.c
 @@ -107,6 +107,7 @@ struct davinci_i2c_dev {
  u8  *buf;
  size_t  buf_len;
  int irq;
 +spinlock_t  lock;
  int stop;
  u8  terminate;
  struct i2c_adapter  adapter;
 @@ -312,6 +313,8 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
 i2c_msg *msg, int stop)
  u32 flag;
  u16 w;
  int r;
 +unsigned long flags;
 +int preload = 0;
  
  if (!pdata)
  pdata = davinci_i2c_platform_data_default;
 @@ -347,6 +350,15 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
 i2c_msg *msg, int stop)
  flag = ~DAVINCI_I2C_MDR_STP;
  }
  
 +/*
 + * When transmitting, lock ISR out to avoid it racing on the buffer and
 + * DXR register before we are done
 + */
 +if ((!(msg-flags  I2C_M_RD))  dev-buf_len) {
 +preload = 1;
 +spin_lock_irqsave(dev-lock, flags);
 +}
 +
  /* Enable receive or transmit interrupts */
  w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);


Maybe you can write 0 to IMR here, and move this interrupt enable (IMR) write 
to after the DXR write.
That would seem a better patch.


  if (msg-flags  I2C_M_RD)
 @@ -366,13 +378,15 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
 i2c_msg *msg, int stop)
   * NACK-interrupt during sending of previous message and
   * ICDXR may have wrong data
   */
 -if ((!(msg-flags  I2C_M_RD))  dev-buf_len) {
 +if (preload) {
  davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev-buf++);
  dev-buf_len--;
 +spin_unlock_irqrestore(dev-lock, flags);
  }
  
  r = wait_for_completion_interruptible_timeout(dev-cmd_complete,
dev-adapter.timeout);
 +
  if (r == 0) {
  dev_err(dev-dev, controller timed out\n);
  i2c_recover_bus(dev);
 @@ -490,6 +504,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void 
 *dev_id)
  int count = 0;
  u16 w;
  
 +spin_lock(dev-lock);
 +
  while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
  dev_dbg(dev-dev, %s: stat=0x%x\n, __func__, stat);
  if (count++ == 100) {
 @@ -579,6 +595,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void 
 *dev_id)
  }
  }
  
 +spin_unlock(dev-lock);
 +
  return count ? IRQ_HANDLED : IRQ_NONE;
  }
  
 @@ -662,6 +680,7 @@ static int davinci_i2c_probe(struct platform_device 
 *pdev)
  goto err_release_region;

Re: [PATCH] i2c-omap: Make sure i2c bus is free before setting it to idle

2010-09-16 Thread Tony Lindgren
* Felipe Balbi felipe.ba...@nokia.com [100826 00:34]:
 Hi,
 
 On Thu, Aug 26, 2010 at 09:36:44AM +0200, Nyman Mathias (Nokia-MS/Helsinki) 
 wrote:
 If the i2c bus receives an interrupt with both BB (bus busy) and
 ARDY (register access ready) statuses set during the tranfer of the last 
 message
 the bus was put to idle while still busy.
 
 This caused bus to timeout.
 
 Signed-off-by: Mathias Nyman mathias.ny...@nokia.com
 
 adding linux-i2c and Ben Dooks to Cc list.

Ben, can you please take this? The patchwork.kernel.org link is:

http://patchwork.kernel.org/patch/133641/

Or let Mathias know if he should repost.

Acked-by: Tony Lindgren t...@atomide.com
 
 ---
 drivers/i2c/busses/i2c-omap.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
 index 824ac1c..3271ce1 100644
 --- a/drivers/i2c/busses/i2c-omap.c
 +++ b/drivers/i2c/busses/i2c-omap.c
 @@ -602,6 +602,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg 
 msgs[], int num)
 
  if (r == 0)
  r = num;
 +
 +omap_i2c_wait_for_bb(dev);
 out:
  omap_i2c_idle(dev);
  return r;
 -- 
 1.5.6.5
 
 --
 To unsubscribe from this list: send the line unsubscribe linux-omap in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 
 -- 
 balbi
 
 DefectiveByDesign.org
 --
 To unsubscribe from this list: send the line unsubscribe linux-i2c in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] i2c: davinci: Fix race when setting up for TX

2010-09-16 Thread Jon Povey
When setting up to transmit, a race exists between the ISR and
i2c_davinci_xfer_msg() trying to load the first byte and adjust counters.
This is mostly visible for transmits  1 byte long.

The hardware starts sending immediately that MDR is loaded. IMR trickery
doesn't work because if we start sending, finish the first byte and an
XRDY event occurs before we load IMR to unmask it, we never get an
interrupt, and we timeout.

Move the MDR load after DXR,IMR loads to avoid this race without locking.

Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985

Signed-off-by: Jon Povey jon.po...@racelogic.co.uk
---
Troy, thanks for the input. I tried reordering the IMR load before but got
occasional timeouts. Went back to the logic analyser today and worked out
why, see above comment in the commit message.

Moving the MDR load seems to fix things without locking, much neater and
tiny patch.

As I understand it we can be confident inside i2c_davinci_xfer_msg() that
the peripheral is not busy sending or receiving something else, I had a
look at the other interrupt sources in the datasheet and this seems safe
enough.

I'm not sure what the correct thing to do for followup message IDs here..
My original email? Troy's? Clues welcome for next time.

 drivers/i2c/busses/i2c-davinci.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 72df4af..baa5209 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -349,9 +349,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
i2c_msg *msg, int stop)
 
dev-terminate = 0;
 
-   /* write the data into mode register */
-   davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
-
/*
 * First byte should be set here, not after interrupt,
 * because transmit-data-ready interrupt can come before
@@ -371,6 +368,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
i2c_msg *msg, int stop)
w |= DAVINCI_I2C_IMR_XRDY;
davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w);
 
+   /* write the data into mode register; start transmitting */
+   davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+
r = wait_for_completion_interruptible_timeout(dev-cmd_complete,
  dev-adapter.timeout);
if (r == 0) {
-- 
1.6.3.3

--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] i2c: davinci: Fix race when setting up for TX

2010-09-16 Thread Jon Povey
When setting up to transmit, a race exists between the ISR and
i2c_davinci_xfer_msg() trying to load the first byte and adjust counters.
This is mostly visible for transmits  1 byte long.

The hardware starts sending immediately that MDR is loaded. IMR trickery
doesn't work because if we start sending, finish the first byte and an
XRDY event occurs before we load IMR to unmask it, we never get an
interrupt, and we timeout.

Move the MDR load after DXR,IMR loads to avoid this race without locking.

Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985

Signed-off-by: Jon Povey jon.po...@racelogic.co.uk
---
Oops, v2 was based on the wrong version. Rebased so this should apply
against mainline.

Troy, thanks for the input. I tried reordering the IMR load before but got
occasional timeouts. Went back to the logic analyser today and worked out
why, see above comment in the commit message.

Moving the MDR load seems to fix things without locking, much neater and
tiny patch.

As I understand it we can be confident inside i2c_davinci_xfer_msg() that
the peripheral is not busy sending or receiving something else, I had a
look at the other interrupt sources in the datasheet and this seems safe
enough.

I'm not sure what the correct thing to do for followup message IDs here..
My original email? Troy's? Clues welcome for next time.

 drivers/i2c/busses/i2c-davinci.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index c87..b8feac5 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -357,9 +357,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
i2c_msg *msg, int stop)
 
dev-terminate = 0;
 
-   /* write the data into mode register */
-   davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
-
/*
 * First byte should be set here, not after interrupt,
 * because transmit-data-ready interrupt can come before
@@ -371,6 +368,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct 
i2c_msg *msg, int stop)
dev-buf_len--;
}
 
+   /* write the data into mode register; start transmitting */
+   davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
+
r = wait_for_completion_interruptible_timeout(dev-cmd_complete,
  dev-adapter.timeout);
if (r == 0) {
-- 
1.6.3.3

--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html