Re: [PATCH 1/2] pwm: Add __weak attributed functions for pwm operations

2011-05-13 Thread David Brown
On Fri, May 13 2011, Mohan Pallaka wrote:

> For chip drivers that support both pwm and non-pwm modes
> would encounter compilation errors if the platform doesn't
> have support for pwm though the chip is programmed to work
> in non-pwm mode. Add __weak attributed pwm functions to avoid
> compilation issues in these scenarios.
>
> Change-Id: Ia507bf659d4d67d71f135012e7d919aca6c45c6c

Make sure you remove these 'Change-Id' lines before sending patches.
They aren't supposed to be in the kernel since they refer to an internal
server, and aren't useful to anyone else.

David

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
--
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 2/2] input: misc: Add support for isa1200 chip

2011-05-13 Thread Mohan Pallaka
From: Kyungmin Park 

isa1200 chip can be used to generate vibrations to indicate
silent alerts, providing gaming haptic actions or vibrations
in response to touches. It can operate in two modes, pwm
generation and pwm input mode. Pwm generation mode requires
external clock and pwm input mode needs the pwm signal to be
given as input to the chip.

This patch has been derived based on Kyungmin Park's haptic
framework patches at http://lkml.org/lkml/2009/10/7/50 . Park's
isa1200 driver registers to the haptic class, which is also
introduced as part of the same patch series, and userspace will
operate the vibrator through exported sysfs entries. This version
supports only pwm input mode.

This derived patch converts the driver from haptic framework to
the Linux supported force feeback framework. It also supports the
chip operation in both pwm input and generation modes.

Change-Id: If253c71e833e629431a35864e33824d8d6dadb35
Signed-off-by: Kyungmin Park 
Signed-off-by: Mohan Pallaka 
---
 drivers/input/misc/Kconfig|   12 +
 drivers/input/misc/Makefile   |1 +
 drivers/input/misc/isa1200.c  |  442 +
 include/linux/input/isa1200.h |   46 +
 4 files changed, 501 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/misc/isa1200.c
 create mode 100644 include/linux/input/isa1200.h

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index f9cf088..9fd762d 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -302,6 +302,18 @@ config HP_SDC_RTC
  Say Y here if you want to support the built-in real time clock
  of the HP SDC controller.
 
+config INPUT_ISA1200
+   tristate "ISA1200 haptic support"
+   depends on I2C
+   select INPUT_FF_MEMLESS
+   help
+ ISA1200 is a high performance enhanced haptic chip.
+ Say Y here if you want to support ISA1200 connected via I2C,
+ and select N if you are unsure.
+
+ To compile this driver as a module, choose M here: the
+ module will be called isa1200.
+
 config INPUT_PCF50633_PMU
tristate "PCF50633 PMU events"
depends on MFD_PCF50633
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index e3f7984..47f74f7 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_INPUT_CMA3000_I2C)   += 
cma3000_d0x_i2c.o
 obj-$(CONFIG_INPUT_COBALT_BTNS)+= cobalt_btns.o
 obj-$(CONFIG_INPUT_DM355EVM)   += dm355evm_keys.o
 obj-$(CONFIG_HP_SDC_RTC)   += hp_sdc_rtc.o
+obj-$(CONFIG_INPUT_ISA1200)+= isa1200.o
 obj-$(CONFIG_INPUT_IXP4XX_BEEPER)  += ixp4xx-beeper.o
 obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
 obj-$(CONFIG_INPUT_M68K_BEEP)  += m68kspkr.o
diff --git a/drivers/input/misc/isa1200.c b/drivers/input/misc/isa1200.c
new file mode 100644
index 000..0f5448a
--- /dev/null
+++ b/drivers/input/misc/isa1200.c
@@ -0,0 +1,442 @@
+/*
+ *  Copyright (C) 2009 Samsung Electronics
+ *  Kyungmin Park 
+ *
+ *  Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ISA1200_HCTRL0 0x30
+#define HCTRL0_MODE_CTRL_BIT   (3)
+#define HCTRL0_OVERDRIVE_HIGH_BIT  (5)
+#define HCTRL0_OVERDRIVE_EN_BIT(6)
+#define HCTRL0_HAP_EN  (7)
+#define HCTRL0_RESET   0x01
+#define HCTRL1_RESET   0x4B
+
+#define ISA1200_HCTRL1 0x31
+#define HCTRL1_SMART_ENABLE_BIT(3)
+#define HCTRL1_ERM_BIT (5)
+#define HCTRL1_EXT_CLK_ENABLE_BIT  (7)
+
+#define ISA1200_HCTRL5 0x35
+#define HCTRL5_VIB_STRT0xD5
+#define HCTRL5_VIB_STOP0x6B
+
+#define DIVIDER_128(128)
+#define DIVIDER_1024   (1024)
+#define DIVIDE_SHIFTER_128 (7)
+
+#define FREQ_22400 (22400)
+#define FREQ_172600(172600)
+
+#define POR_DELAY_USEC (250)
+
+struct isa1200_chip {
+   const struct isa1200_platform_data *pdata;
+   struct i2c_client *client;
+   struct input_dev *input_device;
+   struct pwm_device *pwm;
+   unsigned int period_ns;
+   unsigned int state;
+   struct work_struct work;
+};
+
+static void isa1200_vib_set(struct isa1200_chip *haptic, bool enable)
+{
+   int rc;
+
+   if (enable) {
+   if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
+   rc = pwm_config(haptic->pwm,
+

[PATCH 1/2] pwm: Add __weak attributed functions for pwm operations

2011-05-13 Thread Mohan Pallaka
For chip drivers that support both pwm and non-pwm modes
would encounter compilation errors if the platform doesn't
have support for pwm though the chip is programmed to work
in non-pwm mode. Add __weak attributed pwm functions to avoid
compilation issues in these scenarios.

Change-Id: Ia507bf659d4d67d71f135012e7d919aca6c45c6c
Signed-off-by: Mohan Pallaka 
---
 include/linux/pwm.h |   12 +++-
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 7c77575..e0c8c3f 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -3,29 +3,31 @@
 
 struct pwm_device;
 
+/* Add __weak functions to support PWM */
+
 /*
  * pwm_request - request a PWM device
  */
-struct pwm_device *pwm_request(int pwm_id, const char *label);
+struct pwm_device __weak *pwm_request(int pwm_id, const char *label);
 
 /*
  * pwm_free - free a PWM device
  */
-void pwm_free(struct pwm_device *pwm);
+void __weak pwm_free(struct pwm_device *pwm);
 
 /*
  * pwm_config - change a PWM device configuration
  */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
+int __weak pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
 
 /*
  * pwm_enable - start a PWM output toggling
  */
-int pwm_enable(struct pwm_device *pwm);
+int __weak pwm_enable(struct pwm_device *pwm);
 
 /*
  * pwm_disable - stop a PWM output toggling
  */
-void pwm_disable(struct pwm_device *pwm);
+void __weak pwm_disable(struct pwm_device *pwm);
 
 #endif /* __LINUX_PWM_H */

-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
--
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 0/2] Support for isa1200 haptic chip

2011-05-13 Thread Mohan Pallaka
This patchset includes a __weak attributed pwm apis in pwm.h and
a ff-memless based isa1200 driver.

ISA1200 chip can operate in two modes and if the chip has been
configured for pwm-generation mode, which doesn't use pwm standard
apis then it'd encounter compilation errors if the host doesn't
support PWM. This driver is based on Park's isa1200 driver that uses
haptic class.

Kyungmin Park (1):
  input: misc: Add support for isa1200 chip

Mohan Pallaka (1):
  pwm: Add __weak attributed functions for pwm operations

 drivers/input/misc/Kconfig|   12 +
 drivers/input/misc/Makefile   |1 +
 drivers/input/misc/isa1200.c  |  442 +
 include/linux/input/isa1200.h |   46 +
 include/linux/pwm.h   |   12 +-
 5 files changed, 508 insertions(+), 5 deletions(-)
 create mode 100644 drivers/input/misc/isa1200.c
 create mode 100644 include/linux/input/isa1200.h

-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
--
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 13/14] i2c/i2c-nomadik: break out single messsage transmission

2011-05-13 Thread Linus Walleij
Reduce code size in the message transfer function by factoring out
a single-message transfer function.

Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |   80 +++---
 1 files changed, 48 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index fa7b106..0c731ca 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -525,6 +525,51 @@ static int write_i2c(struct nmk_i2c_dev *dev)
 }
 
 /**
+ * nmk_i2c_xfer_one() - transmit a single I2C message
+ * @dev: device with a message encoded into it
+ * @flags: message flags
+ */
+static int nmk_i2c_xfer_one(struct nmk_i2c_dev *dev, u16 flags)
+{
+   int status;
+
+   if (flags & I2C_M_RD) {
+   /* read operation */
+   dev->cli.operation = I2C_READ;
+   status = read_i2c(dev);
+   } else {
+   /* write operation */
+   dev->cli.operation = I2C_WRITE;
+   status = write_i2c(dev);
+   }
+
+   if (status || (dev->result)) {
+   u32 i2c_sr;
+   u32 cause;
+
+   i2c_sr = readl(dev->virtbase + I2C_SR);
+   /*
+* Check if the controller I2C operation status
+* is set to ABORT(11b).
+*/
+   if (((i2c_sr >> 2) & 0x3) == 0x3) {
+   /* get the abort cause */
+   cause = (i2c_sr >> 4) & 0x7;
+   dev_err(&dev->pdev->dev, "%s\n", cause
+   >= ARRAY_SIZE(abort_causes) ?
+   "unknown reason" :
+   abort_causes[cause]);
+   }
+
+   (void) init_hw(dev);
+
+   status = status ? status : dev->result;
+   }
+
+   return status;
+}
+
+/**
  * nmk_i2c_xfer() - I2C transfer function used by kernel framework
  * @i2c_adap: Adapter pointer to the controller
  * @msgs: Pointer to data to be written.
@@ -576,9 +621,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 {
int status;
int i;
-   u32 cause;
struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
-   u32 i2c_sr;
int j;
 
dev->busy = true;
@@ -593,6 +636,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
if (status)
goto out;
 
+   /* Attempt three times to send the message queue */
for (j = 0; j < 3; j++) {
/* setup the i2c controller */
setup_i2c_controller(dev);
@@ -611,37 +655,9 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
dev->stop = (i < (num_msgs - 1)) ? 0 : 1;
dev->result = 0;
 
-   if (msgs[i].flags & I2C_M_RD) {
-   /* it is a read operation */
-   dev->cli.operation = I2C_READ;
-   status = read_i2c(dev);
-   } else {
-   /* write operation */
-   dev->cli.operation = I2C_WRITE;
-   status = write_i2c(dev);
-   }
-   if (status || (dev->result)) {
-   i2c_sr = readl(dev->virtbase + I2C_SR);
-   /*
-* Check if the controller I2C operation status
-* is set to ABORT(11b).
-*/
-   if (((i2c_sr >> 2) & 0x3) == 0x3) {
-   /* get the abort cause */
-   cause = (i2c_sr >> 4)
-   & 0x7;
-   dev_err(&dev->pdev->dev, "%s\n", cause
-   >= ARRAY_SIZE(abort_causes) ?
-   "unknown reason" :
-   abort_causes[cause]);
-   }
-
-   (void) init_hw(dev);
-
-   status = status ? status : dev->result;
-
+   status = nmk_i2c_xfer_one(dev, msgs[i].flags);
+   if (status != 0)
break;
-   }
}
if (status == 0)
break;
-- 
1.7.5.1

--
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 12/14] i2c/i2c-nomadik: reset the hw after status check

2011-05-13 Thread Linus Walleij
From: Virupax Sadashivpetimath 

In case of I2C timeout, reset the HW only after the HW status
is read, otherwise the staus will be lost.

Signed-off-by: Virupax Sadashivpetimath 

Reviewed-by: Jonas Aberg 
Reviewed-by: Srinidhi Kasagar 
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index b2de1a5..fa7b106 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -428,10 +428,9 @@ static int read_i2c(struct nmk_i2c_dev *dev)
}
 
if (timeout == 0) {
-   /* controller has timedout, re-init the h/w */
+   /* Controller timed out */
dev_err(&dev->pdev->dev, "read from slave 0x%x timed out\n",
dev->cli.slave_adr);
-   (void) init_hw(dev);
status = -ETIMEDOUT;
}
return status;
@@ -516,10 +515,9 @@ static int write_i2c(struct nmk_i2c_dev *dev)
}
 
if (timeout == 0) {
-   /* controller has timedout, re-init the h/w */
+   /* Controller timed out */
dev_err(&dev->pdev->dev, "write to slave 0x%x timed out\n",
dev->cli.slave_adr);
-   (void) init_hw(dev);
status = -ETIMEDOUT;
}
 
@@ -638,6 +636,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
abort_causes[cause]);
}
 
+   (void) init_hw(dev);
+
status = status ? status : dev->result;
 
break;
-- 
1.7.5.1

--
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 11/14] i2c/i2c-nomadik: remove the unnecessary delay

2011-05-13 Thread Linus Walleij
From: Virupax Sadashivpetimath 

The delay in the driver seems to be not needed, so remove it.

Signed-off-by: Virupax Sadashivpetimath 

Reviewed-by: Markus Grape 
Tested-by: Per Persson 
Tested-by: Chethan Krishna N 
Reviewed-by: Srinidhi Kasagar 
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |   20 ++--
 1 files changed, 2 insertions(+), 18 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index e3cd62e..b2de1a5 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -105,9 +104,6 @@
 /* maximum threshold value */
 #define MAX_I2C_FIFO_THRESHOLD 15
 
-/* per-transfer delay, required for the hardware to stabilize */
-#define I2C_DELAY  150
-
 enum i2c_status {
I2C_NOP,
I2C_ON_GOING,
@@ -269,12 +265,6 @@ static int init_hw(struct nmk_i2c_dev *dev)
dev->cli.operation = I2C_NO_OPERATION;
 
 exit:
-   /*
-* TODO: What is this delay for?
-* Must be pretty pointless since the hw block
-* is frozen. Or?
-*/
-   udelay(I2C_DELAY);
return stat;
 }
 
@@ -652,7 +642,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 
break;
}
-   udelay(I2C_DELAY);
}
if (status == 0)
break;
@@ -778,13 +767,8 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
}
}
 
-   i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MTD);
-   i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MTDWS);
-
-   disable_interrupts(dev,
-   (I2C_IT_TXFNE | I2C_IT_TXFE | I2C_IT_TXFF
-   | I2C_IT_TXFOVR | I2C_IT_RXFNF
-   | I2C_IT_RXFF | I2C_IT_RXFE));
+   disable_all_interrupts(dev);
+   clear_all_interrupts(dev);
 
if (dev->cli.count) {
dev->result = -EIO;
-- 
1.7.5.1

--
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 14/14] mach-ux500: set proper I2C platform data from MOP500s

2011-05-13 Thread Linus Walleij
This specifies the new per-platform timeout per I2C bus and
switches the I2C buses to fast mode, and increase the FIFO
depth to 8 for reads and writes.

Signed-off-by: Linus Walleij 
---
 arch/arm/mach-ux500/board-mop500.c |   14 --
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-ux500/board-mop500.c 
b/arch/arm/mach-ux500/board-mop500.c
index 6e1907fa..bb26f40 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -204,7 +204,7 @@ static struct i2c_board_info __initdata 
mop500_i2c2_devices[] = {
},
 };
 
-#define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \
+#define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, t_out, _sm)   \
 static struct nmk_i2c_controller u8500_i2c##id##_data = { \
/*  \
 * slave data setup time, which is  \
@@ -219,19 +219,21 @@ static struct nmk_i2c_controller u8500_i2c##id##_data = { 
\
.rft= _rft, \
/* std. mode operation */   \
.clk_freq   = clk,  \
+   /* Slave response timeout(ms) */\
+   .timeout= t_out,\
.sm = _sm,  \
 }
 
 /*
  * The board uses 4 i2c controllers, initialize all of
  * them with slave data setup time of 250 ns,
- * Tx & Rx FIFO threshold values as 1 and standard
+ * Tx & Rx FIFO threshold values as 8 and standard
  * mode of operation
  */
-U8500_I2C_CONTROLLER(0, 0xe, 1, 1, 10, I2C_FREQ_MODE_STANDARD);
-U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 10, I2C_FREQ_MODE_STANDARD);
-U8500_I2C_CONTROLLER(2,0xe, 1, 1, 10, I2C_FREQ_MODE_STANDARD);
-U8500_I2C_CONTROLLER(3,0xe, 1, 1, 10, I2C_FREQ_MODE_STANDARD);
+U8500_I2C_CONTROLLER(0, 0xe, 1, 8, 10, 200, I2C_FREQ_MODE_FAST);
+U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 10, 200, I2C_FREQ_MODE_FAST);
+U8500_I2C_CONTROLLER(2,0xe, 1, 8, 10, 200, I2C_FREQ_MODE_FAST);
+U8500_I2C_CONTROLLER(3,0xe, 1, 8, 10, 200, I2C_FREQ_MODE_FAST);
 
 static void __init mop500_i2c_init(void)
 {
-- 
1.7.5.1

--
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 01/14] i2c/i2c-nomadik: add regulator support

2011-05-13 Thread Linus Walleij
From: Jonas Aberg 

This on-chip I2C controller needs to fetch the regulator
representing its voltage domain so that it won't be switched off.

Signed-off-by: Jonas Aberg 
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |   73 ++
 1 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index e10e5cf..182761e 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -151,6 +152,7 @@ struct i2c_nmk_client {
  * @stop: stop condition
  * @xfer_complete: acknowledge completion for a I2C message
  * @result: controller propogated result
+ * @busy: Busy doing transfer
  */
 struct nmk_i2c_dev {
struct platform_device  *pdev;
@@ -163,6 +165,8 @@ struct nmk_i2c_dev {
int stop;
struct completion   xfer_complete;
int result;
+   struct regulator*regulator;
+   boolbusy;
 };
 
 /* controller's abort causes */
@@ -257,7 +261,7 @@ static int init_hw(struct nmk_i2c_dev *dev)
 
stat = flush_i2c_fifo(dev);
if (stat)
-   return stat;
+   goto exit;
 
/* disable the controller */
i2c_clr_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
@@ -268,10 +272,16 @@ static int init_hw(struct nmk_i2c_dev *dev)
 
dev->cli.operation = I2C_NO_OPERATION;
 
+exit:
+   /* TODO: Why disable clocks after init hw? */
clk_disable(dev->clk);
-
+   /*
+* TODO: What is this delay for?
+* Must be pretty pointless since the hw block
+* is frozen. Or?
+*/
udelay(I2C_DELAY);
-   return 0;
+   return stat;
 }
 
 /* enable peripheral, master mode operation */
@@ -562,9 +572,14 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
u32 cause;
struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
 
+   dev->busy = true;
+
+   if (dev->regulator)
+   regulator_enable(dev->regulator);
+
status = init_hw(dev);
if (status)
-   return status;
+   goto out2;
 
clk_enable(dev->clk);
 
@@ -575,7 +590,9 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
if (unlikely(msgs[i].flags & I2C_M_TEN)) {
dev_err(&dev->pdev->dev, "10 bit addressing"
"not supported\n");
-   return -EINVAL;
+
+   status = -EINVAL;
+   goto out;
}
dev->cli.slave_adr  = msgs[i].addr;
dev->cli.buffer = msgs[i].buf;
@@ -600,12 +617,19 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
dev_err(&dev->pdev->dev, "%s\n",
cause >= ARRAY_SIZE(abort_causes)
? "unknown reason" : abort_causes[cause]);
-   clk_disable(dev->clk);
-   return status;
+
+   goto out;
}
udelay(I2C_DELAY);
}
+
+out:
clk_disable(dev->clk);
+out2:
+   if (dev->regulator)
+   regulator_disable(dev->regulator);
+
+   dev->busy = false;
 
/* return the no. messages processed */
if (status)
@@ -805,6 +829,21 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
 }
 
+
+#ifdef CONFIG_PM
+static int nmk_i2c_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+   struct nmk_i2c_dev *dev = platform_get_drvdata(pdev);
+
+   if (dev->busy)
+   return -EBUSY;
+   else
+   return 0;
+}
+#else
+#define nmk_i2c_suspendNULL
+#endif
+
 static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
 {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
@@ -830,7 +869,7 @@ static int __devinit nmk_i2c_probe(struct platform_device 
*pdev)
ret = -ENOMEM;
goto err_no_mem;
}
-
+   dev->busy = false;
dev->pdev = pdev;
platform_set_drvdata(pdev, dev);
 
@@ -860,6 +899,12 @@ static int __devinit nmk_i2c_probe(struct platform_device 
*pdev)
goto err_irq;
}
 
+   dev->regulator = regulator_get(&pdev->dev, "v-i2c");
+   if (IS_ERR(dev->regulator)) {
+   dev_warn(&pdev->dev, "could not get i2c regulator\n");
+   dev->regulator = NULL;
+   }
+
dev->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk)) {
dev_err(&pdev->dev, "could not get i2c clock\n");
@@ -887,12 +932,6 @@ static int __devinit nmk_i2c_probe(struct platform_device 
*pdev)
 
i2c_set_adapdata(adap, dev);
 
-   ret = i

[PATCH 10/14] i2c/i2c-nomadik: change the TX and RX threshold

2011-05-13 Thread Linus Walleij
From: Virupax Sadashivpetimath 

1) Increase RX FIFO threshold so that there is a reduction in
the number of interrupts handled to complete a transaction.

2) Fill TX FIFO in the write function.

Signed-off-by: Virupax Sadashivpetimath 

Reviewed-by: Jonas Aberg 
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |   39 +
 1 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index b49ff25..e3cd62e 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -447,6 +447,24 @@ static int read_i2c(struct nmk_i2c_dev *dev)
return status;
 }
 
+static void fill_tx_fifo(struct nmk_i2c_dev *dev, int no_bytes)
+{
+   int count;
+
+   for (count = (no_bytes - 2);
+   (count > 0) &&
+   (dev->cli.count != 0);
+   count--) {
+   /* write to the Tx FIFO */
+   writeb(*dev->cli.buffer,
+   dev->virtbase + I2C_TFR);
+   dev->cli.buffer++;
+   dev->cli.count--;
+   dev->cli.xfer_bytes++;
+   }
+
+}
+
 /**
  * write_i2c() - Write data to I2C client.
  * @dev: private data of I2C Driver
@@ -474,8 +492,13 @@ static int write_i2c(struct nmk_i2c_dev *dev)
init_completion(&dev->xfer_complete);
 
/* enable interrupts by settings the masks */
-   irq_mask = (I2C_IT_TXFNE | I2C_IT_TXFOVR |
-   I2C_IT_MAL | I2C_IT_BERR);
+   irq_mask = (I2C_IT_TXFOVR | I2C_IT_MAL | I2C_IT_BERR);
+
+   /* Fill the TX FIFO with transmit data */
+   fill_tx_fifo(dev, MAX_I2C_FIFO_THRESHOLD);
+
+   if (dev->cli.count != 0)
+   irq_mask |= I2C_IT_TXFNE;
 
/*
 * check if we want to transfer a single or multiple bytes, if so
@@ -702,17 +725,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 */
disable_interrupts(dev, I2C_IT_TXFNE);
} else {
-   for (count = (MAX_I2C_FIFO_THRESHOLD - tft - 2);
-   (count > 0) &&
-   (dev->cli.count != 0);
-   count--) {
-   /* write to the Tx FIFO */
-   writeb(*dev->cli.buffer,
-   dev->virtbase + I2C_TFR);
-   dev->cli.buffer++;
-   dev->cli.count--;
-   dev->cli.xfer_bytes++;
-   }
+   fill_tx_fifo(dev, (MAX_I2C_FIFO_THRESHOLD - tft));
/*
 * if done, close the transfer by disabling the
 * corresponding TXFNE interrupt
-- 
1.7.5.1

--
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 05/14] i2c/i2c-nomadik: remove the redundant error message

2011-05-13 Thread Linus Walleij
From: srinidhi kasagar 

The abort cause string itself is an error, so remove the redundant
explicit error message.

Signed-off-by: Srinidhi Kasagar 
Reviewed-by: Jonas Aberg 
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index a02141a..dbd93b2 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -609,8 +609,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
if (status || (dev->result)) {
/* get the abort cause */
cause = (readl(dev->virtbase + I2C_SR) >> 4) & 0x7;
-   dev_err(&dev->pdev->dev, "error during I2C"
-   "message xfer: %d\n", cause);
dev_err(&dev->pdev->dev, "%s\n",
cause >= ARRAY_SIZE(abort_causes)
? "unknown reason" : abort_causes[cause]);
-- 
1.7.5.1

--
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 03/14] i2c/i2c-nomadik: fix speed enumerator

2011-05-13 Thread Linus Walleij
The I2C speed enumerators in the i2c-nomadik header file were in
the wrong order.

Signed-off-by: Linus Walleij 
---
 arch/arm/plat-nomadik/include/plat/i2c.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/plat-nomadik/include/plat/i2c.h 
b/arch/arm/plat-nomadik/include/plat/i2c.h
index 4ed4e27..8ba70ff 100644
--- a/arch/arm/plat-nomadik/include/plat/i2c.h
+++ b/arch/arm/plat-nomadik/include/plat/i2c.h
@@ -11,8 +11,8 @@
 enum i2c_freq_mode {
I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */
I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */
+   I2C_FREQ_MODE_HIGH_SPEED,   /* up to 3.4 Mb/s */
I2C_FREQ_MODE_FAST_PLUS,/* up to 1 Mb/s */
-   I2C_FREQ_MODE_HIGH_SPEED/* up to 3.4 Mb/s */
 };
 
 /**
-- 
1.7.5.1

--
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 02/14] i2c/i2c-nomadik: make i2c timeout specific per i2c bus

2011-05-13 Thread Linus Walleij
From: Virupax Sadashivpetimath 

Add option to have different i2c timeout delay for different i2c buses
specified in platform data. Default to the old value unless specified.

Signed-off-by: Virupax Sadashivpetimath 

Reviewed-by: Srinidhi Kasagar 
Signed-off-by: Linus Walleij 
---
 arch/arm/plat-nomadik/include/plat/i2c.h |6 --
 drivers/i2c/busses/i2c-nomadik.c |   10 --
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm/plat-nomadik/include/plat/i2c.h 
b/arch/arm/plat-nomadik/include/plat/i2c.h
index 1621db6..4ed4e27 100644
--- a/arch/arm/plat-nomadik/include/plat/i2c.h
+++ b/arch/arm/plat-nomadik/include/plat/i2c.h
@@ -24,13 +24,15 @@ enum i2c_freq_mode {
  * to the values of 14, 6, 2 for a 48 MHz i2c clk
  * @tft:   Tx FIFO Threshold in bytes
  * @rft:   Rx FIFO Threshold in bytes
+ * @timeoutSlave response timeout(ms)
  * @sm:speed mode
  */
 struct nmk_i2c_controller {
unsigned long   clk_freq;
unsigned short  slsu;
-   unsigned char   tft;
-   unsigned char   rft;
+   unsigned char   tft;
+   unsigned char   rft;
+   int timeout;
enum i2c_freq_mode  sm;
 };
 
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 182761e..3bf95b9 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -121,9 +121,6 @@ enum i2c_operation {
I2C_READ = 0x01
 };
 
-/* controller response timeout in ms */
-#define I2C_TIMEOUT_MS 2000
-
 /**
  * struct i2c_nmk_client - client specific data
  * @slave_adr: 7-bit slave address
@@ -213,7 +210,7 @@ static int flush_i2c_fifo(struct nmk_i2c_dev *dev)
writel((I2C_CR_FTX | I2C_CR_FRX), dev->virtbase + I2C_CR);
 
for (i = 0; i < LOOP_ATTEMPTS; i++) {
-   timeout = jiffies + msecs_to_jiffies(I2C_TIMEOUT_MS);
+   timeout = jiffies + msecs_to_jiffies(dev->adap.timeout);
 
while (!time_after(jiffies, timeout)) {
if ((readl(dev->virtbase + I2C_CR) &
@@ -434,7 +431,7 @@ static int read_i2c(struct nmk_i2c_dev *dev)
dev->virtbase + I2C_IMSCR);
 
timeout = wait_for_completion_interruptible_timeout(
-   &dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
+   &dev->xfer_complete, msecs_to_jiffies(dev->adap.timeout));
 
if (timeout < 0) {
dev_err(&dev->pdev->dev,
@@ -498,7 +495,7 @@ static int write_i2c(struct nmk_i2c_dev *dev)
dev->virtbase + I2C_IMSCR);
 
timeout = wait_for_completion_interruptible_timeout(
-   &dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
+   &dev->xfer_complete, msecs_to_jiffies(dev->adap.timeout));
 
if (timeout < 0) {
dev_err(&dev->pdev->dev,
@@ -917,6 +914,7 @@ static int __devinit nmk_i2c_probe(struct platform_device 
*pdev)
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->algo  = &nmk_i2c_algo;
+   adap->timeout   = pdata->timeout ? pdata->timeout : 2;
snprintf(adap->name, sizeof(adap->name),
 "Nomadik I2C%d at %lx", pdev->id, (unsigned long)res->start);
 
-- 
1.7.5.1

--
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 07/14] i2c/i2c-nomadik: print abort cause only on abort tag

2011-05-13 Thread Linus Walleij
From: Virupax Sadashivpetimath 

Modify the code to:
1)Print the cause of i2c failure only if the status is set to ABORT.
2)Print slave address on send/receive fail, will help in which slave
failed.

Signed-off-by: Virupax Sadashivpetimath 

Reviewed-by: Jonas Aberg 
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |   27 +++
 1 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 28389c2..c8bf81a 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -442,7 +442,8 @@ static int read_i2c(struct nmk_i2c_dev *dev)
 
if (timeout == 0) {
/* controller has timedout, re-init the h/w */
-   dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
+   dev_err(&dev->pdev->dev, "read from slave 0x%x timed out\n",
+   dev->cli.slave_adr);
(void) init_hw(dev);
status = -ETIMEDOUT;
}
@@ -506,7 +507,8 @@ static int write_i2c(struct nmk_i2c_dev *dev)
 
if (timeout == 0) {
/* controller has timedout, re-init the h/w */
-   dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
+   dev_err(&dev->pdev->dev, "write to slave 0x%x timed out\n",
+   dev->cli.slave_adr);
(void) init_hw(dev);
status = -ETIMEDOUT;
}
@@ -568,6 +570,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
int i;
u32 cause;
struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
+   u32 i2c_sr;
 
dev->busy = true;
 
@@ -607,14 +610,22 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
status = write_i2c(dev);
}
if (status || (dev->result)) {
-   /* get the abort cause */
-   cause = (readl(dev->virtbase + I2C_SR) >> 4) & 0x7;
-   dev_err(&dev->pdev->dev, "%s\n",
-   cause >= ARRAY_SIZE(abort_causes)
-   ? "unknown reason" : abort_causes[cause]);
+   i2c_sr = readl(dev->virtbase + I2C_SR);
+   /*
+* Check if the controller I2C operation status is set
+* to ABORT(11b).
+*/
+   if (((i2c_sr >> 2) & 0x3) == 0x3) {
+   /* get the abort cause */
+   cause = (i2c_sr >> 4)
+   & 0x7;
+   dev_err(&dev->pdev->dev, "%s\n", cause >=
+   ARRAY_SIZE(abort_causes) ?
+   "unknown reason" :
+   abort_causes[cause]);
+   }
 
status = status ? status : dev->result;
-
goto out;
}
udelay(I2C_DELAY);
-- 
1.7.5.1

--
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 08/14] i2c/i2c-nomadik: use pm_runtime API

2011-05-13 Thread Linus Walleij
From: Rabin Vincent 

Use the pm_runtime API for pins control.

Signed-off-by: Rabin Vincent 
Reviewed-by: Srinidhi Kasagar 
Reviewed-by: Jonas Aberg 
[deleted some surplus runtime PM code]
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |   37 +++--
 1 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index c8bf81a..234e4a9 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -576,6 +577,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 
if (dev->regulator)
regulator_enable(dev->regulator);
+   pm_runtime_get_sync(&dev->pdev->dev);
 
status = init_hw(dev);
if (status)
@@ -634,6 +636,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 out:
clk_disable(dev->clk);
 out2:
+   pm_runtime_put_sync(&dev->pdev->dev);
if (dev->regulator)
regulator_disable(dev->regulator);
 
@@ -839,19 +842,36 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 
 
 #ifdef CONFIG_PM
-static int nmk_i2c_suspend(struct platform_device *pdev, pm_message_t mesg)
+static int nmk_i2c_suspend(struct device *dev)
 {
-   struct nmk_i2c_dev *dev = platform_get_drvdata(pdev);
+   struct platform_device *pdev = to_platform_device(dev);
+   struct nmk_i2c_dev *nmk_i2c = platform_get_drvdata(pdev);
 
-   if (dev->busy)
+   if (nmk_i2c->busy)
return -EBUSY;
-   else
-   return 0;
+
+   return 0;
+}
+
+static int nmk_i2c_resume(struct device *dev)
+{
+   return 0;
 }
 #else
 #define nmk_i2c_suspendNULL
+#define nmk_i2c_resume NULL
 #endif
 
+/*
+ * We use noirq so that we suspend late and resume before the wakeup interrupt
+ * to ensure that we do the !pm_runtime_suspended() check in resume before
+ * there has been a regular pm runtime resume (via pm_runtime_get_sync()).
+ */
+static const struct dev_pm_ops nmk_i2c_pm = {
+   .suspend_noirq  = nmk_i2c_suspend,
+   .resume_noirq   = nmk_i2c_resume,
+};
+
 static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
 {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
@@ -913,6 +933,9 @@ static int __devinit nmk_i2c_probe(struct platform_device 
*pdev)
dev->regulator = NULL;
}
 
+   pm_suspend_ignore_children(&pdev->dev, true);
+   pm_runtime_enable(&pdev->dev);
+
dev->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk)) {
dev_err(&pdev->dev, "could not get i2c clock\n");
@@ -958,6 +981,7 @@ static int __devinit nmk_i2c_probe(struct platform_device 
*pdev)
  err_no_clk:
if (dev->regulator)
regulator_put(dev->regulator);
+   pm_runtime_disable(&pdev->dev);
free_irq(dev->irq, dev);
  err_irq:
iounmap(dev->virtbase);
@@ -990,6 +1014,7 @@ static int __devexit nmk_i2c_remove(struct platform_device 
*pdev)
clk_put(dev->clk);
if (dev->regulator)
regulator_put(dev->regulator);
+   pm_runtime_disable(&pdev->dev);
platform_set_drvdata(pdev, NULL);
kfree(dev);
 
@@ -1000,10 +1025,10 @@ static struct platform_driver nmk_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = DRIVER_NAME,
+   .pm = &nmk_i2c_pm,
},
.probe = nmk_i2c_probe,
.remove = __devexit_p(nmk_i2c_remove),
-   .suspend = nmk_i2c_suspend,
 };
 
 static int __init nmk_i2c_init(void)
-- 
1.7.5.1

--
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 09/14] i2c/i2c-nomadik: add code to retry on timeout failure

2011-05-13 Thread Linus Walleij
From: Virupax Sadashivpetimath 

It is seen that i2c-nomadik controller randomly stops generating the
interrupts leading to a i2c timeout. As a workaround to this problem,
add retries to the on going transfer on failure.

Signed-off-by: Virupax Sadashivpetimath 

Reviewed-by: Jonas ABERG 
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |   97 +++---
 1 files changed, 49 insertions(+), 48 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 234e4a9..b49ff25 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -255,8 +255,6 @@ static int init_hw(struct nmk_i2c_dev *dev)
 {
int stat;
 
-   clk_enable(dev->clk);
-
stat = flush_i2c_fifo(dev);
if (stat)
goto exit;
@@ -271,8 +269,6 @@ static int init_hw(struct nmk_i2c_dev *dev)
dev->cli.operation = I2C_NO_OPERATION;
 
 exit:
-   /* TODO: Why disable clocks after init hw? */
-   clk_disable(dev->clk);
/*
 * TODO: What is this delay for?
 * Must be pretty pointless since the hw block
@@ -572,6 +568,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
u32 cause;
struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
u32 i2c_sr;
+   int j;
 
dev->busy = true;
 
@@ -579,63 +576,67 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
regulator_enable(dev->regulator);
pm_runtime_get_sync(&dev->pdev->dev);
 
+   clk_enable(dev->clk);
+
status = init_hw(dev);
if (status)
-   goto out2;
+   goto out;
 
-   clk_enable(dev->clk);
-
-   /* setup the i2c controller */
-   setup_i2c_controller(dev);
+   for (j = 0; j < 3; j++) {
+   /* setup the i2c controller */
+   setup_i2c_controller(dev);
 
-   for (i = 0; i < num_msgs; i++) {
-   if (unlikely(msgs[i].flags & I2C_M_TEN)) {
-   dev_err(&dev->pdev->dev, "10 bit addressing"
-   "not supported\n");
+   for (i = 0; i < num_msgs; i++) {
+   if (unlikely(msgs[i].flags & I2C_M_TEN)) {
+   dev_err(&dev->pdev->dev, "10 bit addressing"
+   "not supported\n");
 
-   status = -EINVAL;
-   goto out;
-   }
-   dev->cli.slave_adr  = msgs[i].addr;
-   dev->cli.buffer = msgs[i].buf;
-   dev->cli.count  = msgs[i].len;
-   dev->stop = (i < (num_msgs - 1)) ? 0 : 1;
-   dev->result = 0;
-
-   if (msgs[i].flags & I2C_M_RD) {
-   /* it is a read operation */
-   dev->cli.operation = I2C_READ;
-   status = read_i2c(dev);
-   } else {
-   /* write operation */
-   dev->cli.operation = I2C_WRITE;
-   status = write_i2c(dev);
-   }
-   if (status || (dev->result)) {
-   i2c_sr = readl(dev->virtbase + I2C_SR);
-   /*
-* Check if the controller I2C operation status is set
-* to ABORT(11b).
-*/
-   if (((i2c_sr >> 2) & 0x3) == 0x3) {
-   /* get the abort cause */
-   cause = (i2c_sr >> 4)
-   & 0x7;
-   dev_err(&dev->pdev->dev, "%s\n", cause >=
-   ARRAY_SIZE(abort_causes) ?
+   status = -EINVAL;
+   goto out;
+   }
+   dev->cli.slave_adr  = msgs[i].addr;
+   dev->cli.buffer = msgs[i].buf;
+   dev->cli.count  = msgs[i].len;
+   dev->stop = (i < (num_msgs - 1)) ? 0 : 1;
+   dev->result = 0;
+
+   if (msgs[i].flags & I2C_M_RD) {
+   /* it is a read operation */
+   dev->cli.operation = I2C_READ;
+   status = read_i2c(dev);
+   } else {
+   /* write operation */
+   dev->cli.operation = I2C_WRITE;
+   status = write_i2c(dev);
+   }
+   if (status || (dev->result)) {
+   i2c_sr = readl(dev->virtbase + I2C_SR);
+   /*
+* Check if the controller I2C operation status
+* is set to ABORT

[PATCH 04/14] i2c/i2c-nomadik: corrrect returned error numbers

2011-05-13 Thread Linus Walleij
From: Virupax Sadashivpetimath 

The code was returning bad error numbers or just -1 in some cases.

Signed-off-by: Virupax Sadashivpetimath 

Reviewed-by: Srinidhi Kasagar 
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |   10 ++
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 3bf95b9..a02141a 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -615,6 +615,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
cause >= ARRAY_SIZE(abort_causes)
? "unknown reason" : abort_causes[cause]);
 
+   status = status ? status : dev->result;
+
goto out;
}
udelay(I2C_DELAY);
@@ -759,7 +761,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
| I2C_IT_RXFF | I2C_IT_RXFE));
 
if (dev->cli.count) {
-   dev->result = -1;
+   dev->result = -EIO;
dev_err(&dev->pdev->dev, "%lu bytes still remain to be"
"xfered\n", dev->cli.count);
(void) init_hw(dev);
@@ -770,7 +772,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 
/* Master Arbitration lost interrupt */
case I2C_IT_MAL:
-   dev->result = -1;
+   dev->result = -EIO;
(void) init_hw(dev);
 
i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MAL);
@@ -784,7 +786,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 * during the transaction.
 */
case I2C_IT_BERR:
-   dev->result = -1;
+   dev->result = -EIO;
/* get the status */
if (((readl(dev->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
(void) init_hw(dev);
@@ -800,7 +802,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 * the Tx FIFO is full.
 */
case I2C_IT_TXFOVR:
-   dev->result = -1;
+   dev->result = -EIO;
(void) init_hw(dev);
 
dev_err(&dev->pdev->dev, "Tx Fifo Over run\n");
-- 
1.7.5.1

--
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 06/14] i2c/i2c-nomadik: correct adapter timeout initialization

2011-05-13 Thread Linus Walleij
From: Virupax Sadashivpetimath 

Correct the incorrect initialization of adapter timeout not to be
in milliseconds, as it needs to be done in jiffies.

Signed-off-by: Virupax Sadashivpetimath 

Reviewed-by: Srinidhi Kasagar 
Signed-off-by: Linus Walleij 
---
 drivers/i2c/busses/i2c-nomadik.c |9 +
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index dbd93b2..28389c2 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -210,7 +210,7 @@ static int flush_i2c_fifo(struct nmk_i2c_dev *dev)
writel((I2C_CR_FTX | I2C_CR_FRX), dev->virtbase + I2C_CR);
 
for (i = 0; i < LOOP_ATTEMPTS; i++) {
-   timeout = jiffies + msecs_to_jiffies(dev->adap.timeout);
+   timeout = jiffies + dev->adap.timeout;
 
while (!time_after(jiffies, timeout)) {
if ((readl(dev->virtbase + I2C_CR) &
@@ -431,7 +431,7 @@ static int read_i2c(struct nmk_i2c_dev *dev)
dev->virtbase + I2C_IMSCR);
 
timeout = wait_for_completion_interruptible_timeout(
-   &dev->xfer_complete, msecs_to_jiffies(dev->adap.timeout));
+   &dev->xfer_complete, dev->adap.timeout);
 
if (timeout < 0) {
dev_err(&dev->pdev->dev,
@@ -495,7 +495,7 @@ static int write_i2c(struct nmk_i2c_dev *dev)
dev->virtbase + I2C_IMSCR);
 
timeout = wait_for_completion_interruptible_timeout(
-   &dev->xfer_complete, msecs_to_jiffies(dev->adap.timeout));
+   &dev->xfer_complete, dev->adap.timeout);
 
if (timeout < 0) {
dev_err(&dev->pdev->dev,
@@ -914,7 +914,8 @@ static int __devinit nmk_i2c_probe(struct platform_device 
*pdev)
adap->owner = THIS_MODULE;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->algo  = &nmk_i2c_algo;
-   adap->timeout   = pdata->timeout ? pdata->timeout : 2;
+   adap->timeout   = pdata->timeout ? msecs_to_jiffies(pdata->timeout) :
+   msecs_to_jiffies(2);
snprintf(adap->name, sizeof(adap->name),
 "Nomadik I2C%d at %lx", pdev->id, (unsigned long)res->start);
 
-- 
1.7.5.1

--
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 00/14] Various updates to the Nomadik I2C controller v2

2011-05-13 Thread Linus Walleij
This is an interation of the previous patch set that hopefully
adress Ben's comments: we took some runtime PM hooks out and
added a refactoring on the tail.

Actually the last patch fixing the platform config can be fed into the
I2C tree as well, if subsys maintainers are comfortable with it. I
won't be changing much stuff in the ux500 in this merge window due to
kernel consolidations taking place.

Jonas Aberg (1):
  i2c/i2c-nomadik: add regulator support

Linus Walleij (3):
  i2c/i2c-nomadik: fix speed enumerator
  i2c/i2c-nomadik: break out single messsage transmission
  mach-ux500: set proper I2C platform data from MOP500s

Rabin Vincent (1):
  i2c/i2c-nomadik: use pm_runtime API

Virupax Sadashivpetimath (8):
  i2c/i2c-nomadik: make i2c timeout specific per i2c bus
  i2c/i2c-nomadik: corrrect returned error numbers
  i2c/i2c-nomadik: correct adapter timeout initialization
  i2c/i2c-nomadik: print abort cause only on abort tag
  i2c/i2c-nomadik: add code to retry on timeout failure
  i2c/i2c-nomadik: change the TX and RX threshold
  i2c/i2c-nomadik: remove the unnecessary delay
  i2c/i2c-nomadik: reset the hw after status check

srinidhi kasagar (1):
  i2c/i2c-nomadik: remove the redundant error message

 arch/arm/mach-ux500/board-mop500.c   |   14 +-
 arch/arm/plat-nomadik/include/plat/i2c.h |8 +-
 drivers/i2c/busses/i2c-nomadik.c |  276 --
 3 files changed, 197 insertions(+), 101 deletions(-)

-- 
1.7.5.1

--
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] i2c-i801: Don't depend on other kernel driver config options

2011-05-13 Thread Woodhouse, David
On Fri, 2011-05-13 at 11:01 +0100, Jean Delvare wrote:
> Don't let other driver config options influence us, as it makes the
> code more complex and fragile for a small benefit. There's nothing
> wrong with instantiating I2C devices even if they don't have a driver.
> And we're talking about 835 extra bytes in the binary on x86-64,
> that's hardly worth arguing about. 

Looks sane to me; thanks. Should it be CONFIG_DMI instead of (or in
addition to) CONFIG_X86?
-- 
David WoodhouseOpen Source Technology Centre
david.woodho...@intel.com  Intel Corporation


smime.p7s
Description: S/MIME cryptographic signature


[PATCH] i2c-i801: Don't depend on other kernel driver config options

2011-05-13 Thread Jean Delvare
Don't let other driver config options influence us, as it makes the
code more complex and fragile for a small benefit. There's nothing
wrong with instantiating I2C devices even if they don't have a driver.
And we're talking about 835 extra bytes in the binary on x86-64,
that's hardly worth arguing about.

Signed-off-by: Jean Delvare 
Cc: David Woodhouse 
Cc: Hans de Goede 
---
David, would this make you feel better? Hans, any objection?

 drivers/i2c/busses/i2c-i801.c |   13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

--- linux-2.6.39-rc7.orig/drivers/i2c/busses/i2c-i801.c 2011-05-12 
10:17:45.0 +0200
+++ linux-2.6.39-rc7/drivers/i2c/busses/i2c-i801.c  2011-05-12 
16:41:33.0 +0200
@@ -638,7 +638,7 @@ static const struct pci_device_id i801_i
 
 MODULE_DEVICE_TABLE(pci, i801_ids);
 
-#if defined CONFIG_INPUT_APANEL || defined CONFIG_INPUT_APANEL_MODULE
+#ifdef CONFIG_X86
 static unsigned char apanel_addr;
 
 /* Scan the system ROM for the signature "FJKEYINF" */
@@ -668,11 +668,7 @@ static void __init input_apanel_init(voi
}
iounmap(bios);
 }
-#else
-static void __init input_apanel_init(void) {}
-#endif
 
-#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
 struct dmi_onboard_device_info {
const char *name;
u8 type;
@@ -738,6 +734,8 @@ static void __devinit dmi_check_onboard_
dmi_check_onboard_device(type, name, adap);
}
 }
+#else
+static void __init input_apanel_init(void) {}
 #endif
 
 /* Register optional slaves */
@@ -747,7 +745,7 @@ static void __devinit i801_probe_optiona
if (priv->features & FEATURE_IDF)
return;
 
-#if defined CONFIG_INPUT_APANEL || defined CONFIG_INPUT_APANEL_MODULE
+#ifdef CONFIG_X86
if (apanel_addr) {
struct i2c_board_info info;
 
@@ -756,8 +754,7 @@ static void __devinit i801_probe_optiona
strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
i2c_new_device(&priv->adapter, &info);
}
-#endif
-#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+
if (dmi_name_in_vendors("FUJITSU"))
dmi_walk(dmi_check_onboard_devices, &priv->adapter);
 #endif


-- 
Jean Delvare
--
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 09/13] i2c/i2c-nomadik: add code to retry on timeout failure

2011-05-13 Thread Linus Walleij
2011/5/11 Ben Dooks :

>> @@ -579,63 +576,67 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
(...)

> this code is getting a bit complicated, could some of it be factored
> into a new sub-function?

Yep I have added a new patch on top of this stack breaking out the single
message transfer. Will repost this now including deletion of the runtime PM
quirks.

Linus Walleij
--
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: How to use one I2C device from two modules?

2011-05-13 Thread Jean Delvare
Hi Lars,

On Fri, 13 May 2011 00:47:37 -0700 (PDT), Lars Michael wrote:
> --- On Sat, 7/5/11, Jean Delvare  wrote:
> > On Fri, 6 May 2011 04:30:33 -0700 (PDT), Lars Michael
> > wrote:
> > > But how do I access the same I2C device from several
> > modules? Ideally I want to specify the adapter and slave
> > address. If a client is found, I get the i2c_client
> > otherwise I have to create it by i2c_new_device (or probe
> > it). Is it possible?
> > > 
> > 
> > In general I would have pointed you to drivers/mfd and told
> > you to
> > write a mfd core driver for your chip. However in your case
> > I don't
> > think you have a multifunction device. You have a single
> > function
> > device (GPIO) with multiple users. So I suggest that you
> > simply write a
> > proper gpio driver for your chip, and get the device
> > registered as an
> > I2C GPIO device. Then, in your function drivers (power
> > supply control
> > and button control) get a reference to the gpio device in
> > question, and
> > use it.
> 
> Thanks for the advice. I wrote a simple driver for my chip and
> instantiated it in the platform code. In order to access the

Please submit your driver for integration in the upstream kernel.
Others are certainly using the same device!

> device from the function modules, I exported an i2c_client get
> function, in order to get a reference to the client:
> 
> struct i2c_client *pca950x_get_i2c_client(void)
> .
> EXPORT_SYMBOL(pca950x_get_i2c_client);
> 
> Not sure this is the perfect way to do it, but it works.

No, this doesn't seem right. A given system may have more than one
PCA950x chip. And symbol dependencies are a hell to handle as soon as
things get more complex. Such an export will never be accepted upstream.

I can think of 2 ways to handle your problem.

1* Use gpiochip_find(). It is currently only available to drivers if
gpiolib is built into the kernel, but I consider this a bug, patch
submitted [1] but no reply so far.

2a* Install a bus notifier on i2c bus type, and catch event
BUS_NOTIFY_BIND_DRIVER. This only works if you can install the notifier
before the pca950x driver binds to the GPIO chip.

2b* Use i2c_for_each_dev() to get a handle to your i2c client. This
only works if you are certain that the GPIO chip driver is loaded
before the drivers which need it.

Option 1* seems much cleaner to me, as it abstracts the bus type
completely. After all, sub-drivers should only care about the GPIO
functionality and not the technical implementation details.

If neither works for you for whatever reason, maybe we can add a helper
function to i2c-core to retrieve an i2c_client by bus number and
address. Maybe others would find it useful as well.

[1] http://marc.info/?l=linux-kernel&m=130293906304999&w=2

-- 
Jean Delvare
--
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


How to use one I2C device from two modules?

2011-05-13 Thread Lars Michael
--- On Sat, 7/5/11, Jean Delvare  wrote:
> On Fri, 6 May 2011 04:30:33 -0700 (PDT), Lars Michael
> wrote:
> > But how do I access the same I2C device from several
> modules? Ideally I want to specify the adapter and slave
> address. If a client is found, I get the i2c_client
> otherwise I have to create it by i2c_new_device (or probe
> it). Is it possible?
> > 
> 
> In general I would have pointed you to drivers/mfd and told
> you to
> write a mfd core driver for your chip. However in your case
> I don't
> think you have a multifunction device. You have a single
> function
> device (GPIO) with multiple users. So I suggest that you
> simply write a
> proper gpio driver for your chip, and get the device
> registered as an
> I2C GPIO device. Then, in your function drivers (power
> supply control
> and button control) get a reference to the gpio device in
> question, and
> use it.

Thanks for the advice. I wrote a simple driver for my chip and
instantiated it in the platform code. In order to access the
device from the function modules, I exported an i2c_client get
function, in order to get a reference to the client:

struct i2c_client *pca950x_get_i2c_client(void)
.
EXPORT_SYMBOL(pca950x_get_i2c_client);

Not sure this is the perfect way to do it, but it works.

Thanks and regards,
- Lars
--
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: Tegra I2C slave address patches

2011-05-13 Thread Wei Ni
Hi, Marc

Configuring tegra i2c slave address does not put it into slave mode (as opposed 
to master mode).
Tegra can act as an i2c master as well as i2c slave.
And 0xFC is not a special address. It's just an i2c address which is not being 
used by any other i2c slave devices.

Thanks
Wei.

-Original Message-
From: Marc Dietrich [mailto:marvi...@gmx.de] 
Sent: Friday, May 13, 2011 1:39 PM
To: Wei Ni
Cc: Stephen Warren; Bharat Nihalani; linux-i2c@vger.kernel.org; 
linux-te...@vger.kernel.org
Subject: Re: Tegra I2C slave address patches


Hi Wei,

Am Fri, 13 May 2011 12:28:27 +0800
schrieb Wei Ni :

> Hi, Stephen, Marc
> These i2c fix are come from the android-tegra-2.6.36, they will
> Fix some i2c transfer bugs.
> 
> Tegra2 has an improved new i2c slave controller. This should be
> used instead of the old i2c slave controller. With old i2c slave
> controller, occasionally it generates spurious slave interrupts
> causing disruptions in master i2c transfers.
> And new i2c slave should be configured with a non-zero i2c address.
> Configure i2c slave with an i2c address assigned by platform
> data for an i2c dev.

until now I was unter the impression that programming an i2c slave
addresss puts the contoller into slave mode (opposed to master mode).
Sorry if this sounds like a dumb question, but is 0xfc some kind of
special address or is the master/slave operation programmed in some
different way?

Thanks,

Marc

> Marc Dietrich wrote at Thursday, May 12, 2011 1:09 PM:
> > Hi Stephen,
> > 
> > Am Donnerstag 12 Mai 2011, 20:15:08 schrieb Stephen Warren:
> > > Wei,
> > >
> > > I'm trying to consolidate the two Tegra I2C slave mode patches we
> > > posted to the mailing lists:
> > >
> > > Yours: http://www.spinics.net/lists/linux-i2c/msg05437.html
> > > Mine: http://www.spinics.net/lists/linux-i2c/msg05464.html
> > >
> > > I had some questions:
> > >
> > > 1) Why does your patch enable I2C_SL_CNFG_NACK. According to the
> > > Tegra documentation, this prevents the slave I2C controller from
> > > ACKing any transfers. Doesn't this prevent the slave
> > > functionality from working at all?
> > >
> > > 2) Your patch sets up the slave_addr registers based on platform
> > > data. However, I don't see any code in i2c-tegra.c to actually
> > > act as a slave device. Hence, it seems pointless to configure the
> > > slave address.
> > >
> > > Are those two things bug workarounds or something?
> > >
> > > I know that Marc said he'd like to see the slave address
> > > configuration code merged, since the AC100 uses it. However, I'm
> > > having a hard time seeing how it'll make any difference to the
> > > driver right now; it seems if/when slave mode is actually
> > > implemented, the slave_addr setup should be part of that patch.
> > 
> > you are right, slave implementation requires at least an additional
> > ISR. As we don't have any tegra documentation, it will probably
> > take a little longer to implement it correctly. Maybe I hoped that
> > there are some other devices using it. Because there seem to be
> > none, it's ok from my side to drop that part. If we ever get
> > something hacked together, I'm going resubmit it.
> > 
> > Btw, I was a little bit "shocked" that seaboard addedd the
> > slave_addr (0xfc) to the board file, which looks like all ports
> > (except dvc) became slaves now. Is this a special kind of address,
> > because it is the last possible one?
> 
> Interesting. For reference, you're talking about the following in
> http://git.chromium.org/chromiumos/third_party/kernel.git
> chromeos-2.6.38
> 
>   1eb243925afed4ef70a04f632f5288e320607ac0
>   CHROMIUM: tegra: seaboard: i2c address for new i2c slaves
>   New i2c slave should be configured with a non-zero i2c address.
>   Configure i2c slave with an i2c address assigned by platform
>   data for an i2c dev.
>   Assign 0xFC as i2c slave address for all new i2c slaves.
> 
> I'll have to let Wei comment on that; he wrote the change. It
> certainly sounds like it's setting an unused slave address as some
> kind of bug workaround.
> 

--
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