[PATCH v4] i2c: rk3x: adjust the LOW divison based on characteristics of SCL

2014-10-09 Thread Addy Ke
As show in I2C specification:
- Standard-mode: the minimum HIGH period of the scl clock is 4.0us
 the minimum LOW period of the scl clock is 4.7us
- Fast-mode: the minimum HIGH period of the scl clock is 0.6us
 the minimum LOW period of the scl clock is 1.3us

I have measured i2c SCL waveforms in fast-mode by oscilloscope
on rk3288-pinky board. the LOW period of the scl clock is 1.3us.
It is so critical that we must adjust LOW division to increase
the LOW period of the scl clock.

Thanks Doug for the suggestion about division formulas.

Reviewed-by: Doug Anderson diand...@chromium.org
Tested-by: Doug Anderson diand...@chromium.org
Signed-off-by: Addy Ke addy...@rock-chips.com
---
Changes in v2:
- remove Fast-mode plus and HS-mode
- use new formulas suggested by Doug
Changes in V3:
- use new formulas (sep 30) suggested by Doug
Changes in V3:
- fix some wrong style
- WARN_ONCE if min_low_div  max_low_div

 drivers/i2c/busses/i2c-rk3x.c | 140 +++---
 1 file changed, 133 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index b41d979..f17f7a2 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -24,6 +24,7 @@
 #include linux/wait.h
 #include linux/mfd/syscon.h
 #include linux/regmap.h
+#include linux/math64.h
 
 
 /* Register Map */
@@ -428,18 +429,143 @@ out:
return IRQ_HANDLED;
 }
 
+static void rk3x_i2c_calc_divs(unsigned long i2c_rate, unsigned long scl_rate,
+  unsigned long *div_low, unsigned long *div_high)
+{
+   unsigned long min_low_ns, min_high_ns;
+   unsigned long max_data_hold_ns;
+   unsigned long data_hold_buffer_ns;
+   unsigned long max_low_ns, min_total_ns;
+
+   unsigned long i2c_rate_khz, scl_rate_khz;
+
+   unsigned long min_low_div, min_high_div;
+   unsigned long max_low_div;
+
+   unsigned long min_div_for_hold, min_total_div;
+   unsigned long extra_div, extra_low_div, ideal_low_div;
+
+   /* Only support standard-mode and fast-mode */
+   WARN_ON(scl_rate  40);
+
+   /*
+* min_low_ns:  The minimum number of ns we need to hold low
+*  to meet i2c spec
+* min_high_ns: The minimum number of ns we need to hold high
+*  to meet i2c spec
+* max_low_ns:  The maximum number of ns we can hold low
+*  to meet i2c spec
+*
+* Note: max_low_ns should be (max data hold time * 2 - buffer)
+*   This is because the i2c host on Rockchip holds the data line
+*   for half the low time.
+*/
+   if (scl_rate = 10) {
+   min_low_ns = 4700;
+   min_high_ns = 4000;
+   max_data_hold_ns = 3450;
+   data_hold_buffer_ns = 50;
+   } else {
+   min_low_ns = 1300;
+   min_high_ns = 600;
+   max_data_hold_ns = 900;
+   data_hold_buffer_ns = 50;
+   }
+   max_low_ns = max_data_hold_ns * 2 - data_hold_buffer_ns;
+   min_total_ns = min_low_ns + min_high_ns;
+
+   /* Adjust to avoid overflow */
+   i2c_rate_khz = DIV_ROUND_UP(i2c_rate, 1000);
+   scl_rate_khz = DIV_ROUND_UP(scl_rate, 1000);
+
+   /*
+* We need the total div to be = this number
+* so we don't clock too fast.
+*/
+   min_total_div = DIV_ROUND_UP(i2c_rate_khz, scl_rate_khz * 8);
+
+   /* These are the min dividers needed for min hold times. */
+   min_low_div = DIV_ROUND_UP(i2c_rate_khz * min_low_ns, 8 * 100);
+   min_high_div = DIV_ROUND_UP(i2c_rate_khz * min_high_ns, 8 * 100);
+   min_div_for_hold = (min_low_div + min_high_div);
+
+   /*
+* This is the maximum divider so we don't go over the max.
+* We don't round up here (we round down) since this is a max.
+*/
+   max_low_div = i2c_rate_khz * max_low_ns / (8 * 100);
+
+   if (min_low_div  max_low_div) {
+   WARN_ONCE(true,
+ Conflicting, min_low_div %lu, max_low_div %lu\n,
+ min_low_div, max_low_div);
+   max_low_div = min_low_div;
+   }
+
+   if (min_div_for_hold  min_total_div) {
+   /*
+* Time needed to meet hold requirements is important.
+* Just use that.
+*/
+   *div_low = min_low_div;
+   *div_high = min_high_div;
+   } else {
+   /*
+* We've got to distribute some time among the low and high
+* so we don't run too fast.
+*/
+   extra_div = min_total_div - min_div_for_hold;
+
+   /*
+* We'll try to split things up perfectly evenly,
+* biasing slightly towards having a higher div
+* for low (spend more time low).
+ 

Re: [PATCH v3 1/3] mfd: add support for Cypress CYUSBS234 USB Serial Bridge controller

2014-10-09 Thread Lee Jones
On Mon, 06 Oct 2014, Muthu Mani wrote:

 Adds support for USB-I2C/GPIO interfaces of Cypress Semiconductor
 CYUSBS234 USB-Serial Bridge controller.
 
 Details about the device can be found at:
 http://www.cypress.com/?rID=84126
 
 Signed-off-by: Muthu Mani m...@cypress.com
 Signed-off-by: Rajaram Regupathy r...@cypress.com
 ---
 Changes since v2:
 * Used auto mfd id to support multiple devices
 * Cleaned up the code
 
 Changes since v1:
 * Identified different serial interface and loaded correct cell driver
 * Formed a mfd id to support multiple devices
 * Removed unused platform device
 
  drivers/mfd/Kconfig   |  12 +++
  drivers/mfd/Makefile  |   1 +
  drivers/mfd/cyusbs23x.c   | 167 
 ++
  include/linux/mfd/cyusbs23x.h |  62 
  4 files changed, 242 insertions(+)
  create mode 100644 drivers/mfd/cyusbs23x.c
  create mode 100644 include/linux/mfd/cyusbs23x.h
 
 diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
 index de5abf2..a31e9e3 100644
 --- a/drivers/mfd/Kconfig
 +++ b/drivers/mfd/Kconfig
 @@ -116,6 +116,18 @@ config MFD_ASIC3
 This driver supports the ASIC3 multifunction chip found on many
 PDAs (mainly iPAQ and HTC based ones)
  
 +config MFD_CYUSBS23X
 +tristate Cypress CYUSBS23x USB Serial Bridge controller

White space issue here.

 + select MFD_CORE
 + depends on USB
 + default n
 + help
 +   Say yes here if you want support for Cypress Semiconductor
 +   CYUSBS23x USB-Serial Bridge controller.
 +
 +   This driver can also be built as a module. If so, the module will be
 +   called cyusbs23x.
 +
  config PMIC_DA903X
   bool Dialog Semiconductor DA9030/DA9034 PMIC Support
   depends on I2C=y
 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
 index f001487..fc5bcd1 100644
 --- a/drivers/mfd/Makefile
 +++ b/drivers/mfd/Makefile
 @@ -151,6 +151,7 @@ si476x-core-y := si476x-cmd.o si476x-prop.o si476x-i2c.o
  obj-$(CONFIG_MFD_SI476X_CORE)+= si476x-core.o
  
  obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
 +obj-$(CONFIG_MFD_CYUSBS23X) += cyusbs23x.o
  obj-$(CONFIG_MFD_OMAP_USB_HOST)  += omap-usb-host.o omap-usb-tll.o
  obj-$(CONFIG_MFD_PM8921_CORE)+= pm8921-core.o ssbi.o
  obj-$(CONFIG_TPS65911_COMPARATOR)+= tps65911-comparator.o
 diff --git a/drivers/mfd/cyusbs23x.c b/drivers/mfd/cyusbs23x.c
 new file mode 100644
 index 000..c70ea40
 --- /dev/null
 +++ b/drivers/mfd/cyusbs23x.c
 @@ -0,0 +1,167 @@
 +/*
 + * Cypress USB-Serial Bridge Controller USB adapter driver
 + *
 + * Copyright (c) 2014 Cypress Semiconductor Corporation.
 + *
 + * Author:
 + *   Muthu Mani m...@cypress.com
 + *
 + * Additional contributors include:
 + *   Rajaram Regupathy r...@cypress.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 is core MFD driver for Cypress Semiconductor CYUSBS234 USB-Serial
 + * Bridge controller. CYUSBS234 offers a single channel serial interface
 + * (I2C/SPI/UART). It can be configured to enable either of I2C, SPI, UART
 + * interfaces. The GPIOs are also available to access.
 + * Details about the device can be found at:
 + *http://www.cypress.com/?rID=84126
 + *
 + * Separate cell drivers are available for I2C and GPIO. SPI and UART are not
 + * supported yet. All GPIOs are exposed for get operation. However, only
 + * unused GPIOs can be set.
 + */
 +
 +#include linux/kernel.h
 +#include linux/errno.h
 +#include linux/module.h
 +#include linux/slab.h
 +#include linux/types.h
 +#include linux/mutex.h
 +

This '\n' is superfluous, please remove it.

 +#include linux/mfd/core.h
 +#include linux/mfd/cyusbs23x.h
 +
 +#include linux/usb.h
 +
 +static const struct usb_device_id cyusbs23x_usb_table[] = {
 + { USB_DEVICE(0x04b4, 0x0004) },   /* Cypress Semiconductor */
 + { }   /* Terminating entry */

This comment is not required, please remove it.

 +};
 +
 +MODULE_DEVICE_TABLE(usb, cyusbs23x_usb_table);
 +
 +static const struct mfd_cell cyusbs23x_i2c_devs[] = {
 + {
 + .name = cyusbs23x-i2c,
 + },
 + {
 + .name = cyusbs23x-gpio,
 + },
 +};
 +
 +static int update_ep_details(struct usb_interface *interface,
 + struct cyusbs23x *cyusbs)
 +{
 + struct usb_host_interface *iface_desc;
 + struct usb_endpoint_descriptor *ep;
 + int i;
 +
 + iface_desc = interface-cur_altsetting;
 +
 + for (i = 0; i  iface_desc-desc.bNumEndpoints; ++i) {
 +
 + ep = iface_desc-endpoint[i].desc;
 +
 + if (!cyusbs-bulk_in_ep_num  usb_endpoint_is_bulk_in(ep))
 + cyusbs-bulk_in_ep_num = ep-bEndpointAddress;
 + if (!cyusbs-bulk_out_ep_num  usb_endpoint_is_bulk_out(ep))
 + 

[PATCH 2/3] i2c: qup: Remove .owner field for driver

2014-10-09 Thread Kiran Padwal
There is no need to init .owner field.

Based on the patch from Peter Griffin peter.grif...@linaro.org
mmc: remove .owner field for drivers using module_platform_driver

This patch removes the superfluous .owner field for drivers which
use the module_platform_driver API, as this is overridden in
platform_driver_register anyway.

Signed-off-by: Kiran Padwal kiran.pad...@smartplayin.com
---
 drivers/i2c/busses/i2c-qup.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 3a4d64e..f14af2e 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -760,7 +760,6 @@ static struct platform_driver qup_i2c_driver = {
.remove = qup_i2c_remove,
.driver = {
.name = i2c_qup,
-   .owner = THIS_MODULE,
.pm = qup_i2c_qup_pm_ops,
.of_match_table = qup_i2c_dt_match,
},
-- 
1.7.9.5

--
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 v3 3/3] gpio: add support for Cypress CYUSBS234 USB-GPIO adapter

2014-10-09 Thread Alexandre Courbot
On Thu, Oct 9, 2014 at 8:46 AM, RR rajaram.officema...@gmail.com wrote:
 On Wed, Oct 8, 2014 at 12:18 AM, Alexandre Courbot gnu...@gmail.com wrote:
 On Wed, Oct 8, 2014 at 4:09 PM, Muthu Mani m...@cypress.com wrote:
 -Original Message-
 From: Alexandre Courbot [mailto:gnu...@gmail.com]
 Sent: Tuesday, October 07, 2014 3:34 PM
 To: Muthu Mani
 Cc: Samuel Ortiz; Lee Jones; Wolfram Sang; Linus Walleij; Greg Kroah-
 Hartman; linux-i2c@vger.kernel.org; linux-g...@vger.kernel.org; linux-
 u...@vger.kernel.org; Linux Kernel Mailing List; Rajaram Regupathy; Johan
 Hovold
 Subject: Re: [PATCH v3 3/3] gpio: add support for Cypress CYUSBS234 USB-
 GPIO adapter

 On Mon, Oct 6, 2014 at 11:47 PM, Muthu Mani m...@cypress.com wrote:
  +
  +static int cy_gpio_direction_input(struct gpio_chip *chip,
  +   unsigned offset) {
  +   return 0;
  +}
  +
  +static int cy_gpio_direction_output(struct gpio_chip *chip,
  +   unsigned offset, int value) {
  +   return 0;
  +}

 If that chip is capable of both output and input, shouldn't these 
 functions be
 implemented? I think this has already been pointed out in a previous 
 version
 but you did not reply.

 Thanks for your inputs.

 Only the GPIOs which are configured to be output GPIO can be set.

 In that case cy_gpio_set() should return an error for GPIOs which are
 not configured as outputs. Is that guaranteed by the current
 implementation?

 The set operation would fail trying to set the input or unconfigured GPIOs.
 In this version of driver, this support is not added, it can be introduced 
 in future versions.
 I will add a TODO note in the code.

 Argh, no TODO please. Actual code that will turn this code into a
 solid driver that can be merged.

 Does a driver targeted for a custom device has to implement every
 functionality in the 1st version ? My understanding is that Linux
 follows incremental model and allows incremental merge.

Certainly, but we are talking about very basic functionality here.

Right now this driver will incorrectly returns success when trying to
set the direction of a GPIO, even though it did not do anything. There
is also no hint that _set will return an error if called on an
input/unconfigured GPIO.

So while we are not asking for a driver to be perfect on the first
iteration, setting the direction of a GPIO is a very basic
functionality that is essential for a GPIO driver to just work. Custom
device or not, this is mainline. The rest of the driver seems to be
ok, so please take the last few steps that will allow us to merge a
featured driver.
--
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 v3 1/3] mfd: add support for Cypress CYUSBS234 USB Serial Bridge controller

2014-10-09 Thread Johan Hovold
On Thu, Oct 09, 2014 at 08:40:29AM +0100, Lee Jones wrote:
 On Mon, 06 Oct 2014, Muthu Mani wrote:

  +static int update_ep_details(struct usb_interface *interface,
  +   struct cyusbs23x *cyusbs)
  +{
  +   struct usb_host_interface *iface_desc;
  +   struct usb_endpoint_descriptor *ep;
  +   int i;
  +
  +   iface_desc = interface-cur_altsetting;
  +
  +   for (i = 0; i  iface_desc-desc.bNumEndpoints; ++i) {
  +
  +   ep = iface_desc-endpoint[i].desc;
  +
  +   if (!cyusbs-bulk_in_ep_num  usb_endpoint_is_bulk_in(ep))
  +   cyusbs-bulk_in_ep_num = ep-bEndpointAddress;
  +   if (!cyusbs-bulk_out_ep_num  usb_endpoint_is_bulk_out(ep))
  +   cyusbs-bulk_out_ep_num = ep-bEndpointAddress;
  +   if (!cyusbs-intr_in_ep_num  usb_endpoint_is_int_in(ep))
  +   cyusbs-intr_in_ep_num = ep-bEndpointAddress;
  +   }
 
 All of the USB specific code in this driver will require a USB Ack.

I'll review it once the incomplete gpio-driver issue has been resolved.

  +   dev_dbg(interface-dev, %s intr_in=%d, bulk_in=%d, bulk_out=%d\n,
  +   __func__, cyusbs-intr_in_ep_num ,
  +   cyusbs-bulk_in_ep_num, cyusbs-bulk_out_ep_num);
  +
  +   if (!cyusbs-bulk_in_ep_num || !cyusbs-bulk_out_ep_num ||
  +   !cyusbs-intr_in_ep_num)
  +   return -ENODEV;
  +
  +   return 0;
  +}

[...]

  diff --git a/include/linux/mfd/cyusbs23x.h b/include/linux/mfd/cyusbs23x.h

  +/* Serial interfaces (I2C, SPI, UART) differ in interface subclass */
  +enum cy_scb_modes {
  +   CY_USBS_SCB_DISABLED = 0,
  +   CY_USBS_SCB_UART = 1,
  +   CY_USBS_SCB_SPI = 2,
  +   CY_USBS_SCB_I2C = 3
 
 No need to number these.

As it's not an arbitrary enumeration, I think they should be initialised
explicitly. They could be defined in the mfd driver though, as they only
appear to be needed during probe.

Johan
--
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] at24: extend driver to allow writing via i2c_smbus_write_byte_data

2014-10-09 Thread Christian Gmeiner
I have a at24 EEPROM connected via i2c bus provided by ISCH i2c
bus driver. This bus driver does not support
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK and so I was looking for a way
to be able to write the eeprom. This patch adds support for
I2C_SMBUS_BYTE_DATA writing via i2c_smbus_write_byte_data.
It is quite slow, but it works.

Signed-off-by: Christian Gmeiner christian.gmei...@gmail.com
---
 drivers/misc/eeprom/at24.c | 35 +--
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index d87f77f..f51daac 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -56,6 +56,7 @@ struct at24_data {
struct at24_platform_data chip;
struct memory_accessor macc;
int use_smbus;
+   int use_smbuse_write;
 
/*
 * Lock protects against activities from other Linux tasks,
@@ -324,7 +325,7 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, 
const char *buf,
 {
struct i2c_client *client;
struct i2c_msg msg;
-   ssize_t status;
+   ssize_t status = 0;
unsigned long timeout, write_time;
unsigned next_page;
 
@@ -365,9 +366,18 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, 
const char *buf,
timeout = jiffies + msecs_to_jiffies(write_timeout);
do {
write_time = jiffies;
-   if (at24-use_smbus) {
-   status = i2c_smbus_write_i2c_block_data(client,
-   offset, count, buf);
+   if (at24-use_smbuse_write) {
+   switch (at24-use_smbuse_write) {
+   case I2C_SMBUS_I2C_BLOCK_DATA:
+   status = i2c_smbus_write_i2c_block_data(client,
+   offset, count, buf);
+   break;
+   case I2C_SMBUS_BYTE_DATA:
+   status = i2c_smbus_write_byte_data(client,
+   offset, buf[0]);
+   break;
+   }
+
if (status == 0)
status = count;
} else {
@@ -487,6 +497,7 @@ static int at24_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
struct at24_platform_data chip;
bool writable;
int use_smbus = 0;
+   int use_smbus_write = 0;
struct at24_data *at24;
int err;
unsigned i, num_addresses;
@@ -546,6 +557,18 @@ static int at24_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
}
}
 
+   /* Use I2C operations unless we're stuck with SMBus extensions. */
+   if (!i2c_check_functionality(client-adapter, I2C_FUNC_I2C)) {
+   if (i2c_check_functionality(client-adapter,
+   I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
+   use_smbus_write = I2C_SMBUS_I2C_BLOCK_DATA;
+   } else if (i2c_check_functionality(client-adapter,
+   I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
+   use_smbus_write = I2C_SMBUS_BYTE_DATA;
+   chip.page_size = 1;
+   }
+   }
+
if (chip.flags  AT24_FLAG_TAKE8ADDR)
num_addresses = 8;
else
@@ -559,6 +582,7 @@ static int at24_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
 
mutex_init(at24-lock);
at24-use_smbus = use_smbus;
+   at24-use_smbuse_write = use_smbus_write;
at24-chip = chip;
at24-num_addresses = num_addresses;
 
@@ -576,8 +600,7 @@ static int at24_probe(struct i2c_client *client, const 
struct i2c_device_id *id)
 
writable = !(chip.flags  AT24_FLAG_READONLY);
if (writable) {
-   if (!use_smbus || i2c_check_functionality(client-adapter,
-   I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
+   if (!use_smbus || use_smbus_write) {
 
unsigned write_max = chip.page_size;
 
-- 
1.9.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


Re: [PATCH v3 1/3] mfd: add support for Cypress CYUSBS234 USB Serial Bridge controller

2014-10-09 Thread Lee Jones
On Thu, 09 Oct 2014, Johan Hovold wrote:

 On Thu, Oct 09, 2014 at 08:40:29AM +0100, Lee Jones wrote:
  On Mon, 06 Oct 2014, Muthu Mani wrote:
 
   +static int update_ep_details(struct usb_interface *interface,
   + struct cyusbs23x *cyusbs)
   +{
   + struct usb_host_interface *iface_desc;
   + struct usb_endpoint_descriptor *ep;
   + int i;
   +
   + iface_desc = interface-cur_altsetting;
   +
   + for (i = 0; i  iface_desc-desc.bNumEndpoints; ++i) {
   +
   + ep = iface_desc-endpoint[i].desc;
   +
   + if (!cyusbs-bulk_in_ep_num  usb_endpoint_is_bulk_in(ep))
   + cyusbs-bulk_in_ep_num = ep-bEndpointAddress;
   + if (!cyusbs-bulk_out_ep_num  usb_endpoint_is_bulk_out(ep))
   + cyusbs-bulk_out_ep_num = ep-bEndpointAddress;
   + if (!cyusbs-intr_in_ep_num  usb_endpoint_is_int_in(ep))
   + cyusbs-intr_in_ep_num = ep-bEndpointAddress;
   + }
  
  All of the USB specific code in this driver will require a USB Ack.
 
 I'll review it once the incomplete gpio-driver issue has been resolved.

Okay, great.

   + dev_dbg(interface-dev, %s intr_in=%d, bulk_in=%d, bulk_out=%d\n,
   + __func__, cyusbs-intr_in_ep_num ,
   + cyusbs-bulk_in_ep_num, cyusbs-bulk_out_ep_num);
   +
   + if (!cyusbs-bulk_in_ep_num || !cyusbs-bulk_out_ep_num ||
   + !cyusbs-intr_in_ep_num)
   + return -ENODEV;
   +
   + return 0;
   +}
 
 [...]
 
   diff --git a/include/linux/mfd/cyusbs23x.h b/include/linux/mfd/cyusbs23x.h
 
   +/* Serial interfaces (I2C, SPI, UART) differ in interface subclass */
   +enum cy_scb_modes {
   + CY_USBS_SCB_DISABLED = 0,
   + CY_USBS_SCB_UART = 1,
   + CY_USBS_SCB_SPI = 2,
   + CY_USBS_SCB_I2C = 3
  
  No need to number these.
 
 As it's not an arbitrary enumeration, I think they should be initialised
 explicitly.

No need.  You are protected by the C Standard:

6.7.2.2 Enumeration specifiers

If the first enumerator has no =, the value of its enumeration
constant is 0. Each subsequent enumerator with no = defines its
enumeration constant as the value of the constant expression obtained
by adding 1 to the value of the previous enumeration constant.

There's nothing arbitrary about that.

 They could be defined in the mfd driver though, as they only
 appear to be needed during probe.


-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
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] i2c-designware: Add Intel Baytrail PMIC I2C bus support

2014-10-09 Thread Maxime Ripard
Hi David,

On Tue, Oct 07, 2014 at 12:14:20PM -0700, David E. Box wrote:
 Hi Maxime,
 
 On Thu, Sep 25, 2014 at 11:47:52AM +0200, Maxime Ripard wrote:
  Hi David,
  
  On Tue, Sep 23, 2014 at 12:58:54PM -0700, David E. Box wrote:
   Hi Maxime,
   
   On Tue, Sep 23, 2014 at 09:00:57PM +0200, Maxime Ripard wrote:
Hi David,

On Tue, Sep 23, 2014 at 11:40:26AM -0700, David E. Box wrote:
 This patch implements an I2C bus sharing mechanism between the host 
 and platform
 hardware on select Intel BayTrail SoC platforms using the X-Powers 
 AXP288 PMIC.
 
 On these platforms access to the PMIC must be shared with platform 
 hardware. The
 hardware unit assumes full control of the I2C bus and the host must 
 request
 access through a special semaphore. Hardware control of the bus also 
 makes it
 necessary to disable runtime pm to avoid interfering with hardware 
 transactions.
 
 Signed-off-by: David E. Box david.e@linux.intel.com

Sorry for stepping in like this without really knowing your platform,
but wouldn't using the hwspinlock framework make more sense than
hardcoding your own internal functions here?
   
   I looked into this but didn't see a clear way on our platform to identify 
   the
   semaphore seperately from doing it in the designware platform driver. The 
   way
   we can find it now is through evaluating an ACPI _SEM object on every i2c 
   device
   that gets probed by the dw driver since at probe time we can get the acpi 
   handle.
  
  And you have no way to turn it around and identify which semaphore is
  associated to which i2c bus?
  
  If so, there is probably some way to associate a given instance of the
  i2c driver to one semaphore.
  
   Without this handle however there isn't a clear way of evaluating the _SEM
   object which would be needed to register a hwspinlock in separate code.
   
   Plus it would still require changes to the designware i2c core, though 
   admittedly
   having a generic hwspinlock pointer added to the struct is cleaner.
  
  Not only cleaner, but that could also be used by other platforms that
  are using this I2C driver (and since it's a designware IP, there must
  be quite a lot) together with hardware locking.
  
 
 After again considering a way to make this work I don't think this api can fit
 well with our platform. Acquisition of this semaphore is through a mailbox
 sequence where we set one register and then poll another for a value that
 confirms we have the lock. For best performance we need to be able to
 periodically sleep while waiting for that confirmation. This time can vary
 widely as it's dependent on the component we are requesting the semaphore from
 which is itself a user of that bus.
 
 While we could simply fail after a short time, reattempts would still need
 to happen in the i2c-designware driver and the timing would be completely
 dependent on our hardware, making it less clean for reuse. In addition,
 if we timed out, we would have to immediately call unlock to cancel the
 mailbox transaction. This may not fit well with reuse either.

Ok, if Wolfram is ok with it, and if it makes your life much easier,
I'm ok :)

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


signature.asc
Description: Digital signature


Re: [PATCH v3 1/3] mfd: add support for Cypress CYUSBS234 USB Serial Bridge controller

2014-10-09 Thread Johan Hovold
On Thu, Oct 09, 2014 at 11:59:50AM +0100, Lee Jones wrote:
 On Thu, 09 Oct 2014, Johan Hovold wrote:
  On Thu, Oct 09, 2014 at 08:40:29AM +0100, Lee Jones wrote:
   On Mon, 06 Oct 2014, Muthu Mani wrote:

diff --git a/include/linux/mfd/cyusbs23x.h 
b/include/linux/mfd/cyusbs23x.h
  
+/* Serial interfaces (I2C, SPI, UART) differ in interface subclass */
+enum cy_scb_modes {
+   CY_USBS_SCB_DISABLED = 0,
+   CY_USBS_SCB_UART = 1,
+   CY_USBS_SCB_SPI = 2,
+   CY_USBS_SCB_I2C = 3
   
   No need to number these.
  
  As it's not an arbitrary enumeration, I think they should be initialised
  explicitly.
 
 No need.  You are protected by the C Standard:
 
 6.7.2.2 Enumeration specifiers
 
 If the first enumerator has no =, the value of its enumeration
 constant is 0. Each subsequent enumerator with no = defines its
 enumeration constant as the value of the constant expression obtained
 by adding 1 to the value of the previous enumeration constant.
 
 There's nothing arbitrary about that.

I obviously wasn't suggesting that the definition of an enum (and the
values of its constants) in c was arbitrary.

My point was that the values of the USB interface subclasses (defined
through the enum) are not arbitrary. In this case they just happen to be
zero-based and consecutive. You cannot reorder, or remove an unused
item, without breaking the driver. By initialising each constant
explicitly this would become apparent.

Using preprocessor defines could be an alternative if you really do not
like initialised enumeration constants.

  They could be defined in the mfd driver though, as they only
  appear to be needed during probe.

Johan
--
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 v6 1/4] mfd: add support for Diolan DLN-2 devices

2014-10-09 Thread Johan Hovold
On Wed, Oct 08, 2014 at 03:33:28PM +0300, Octavian Purdila wrote:
 On Wed, Oct 8, 2014 at 3:04 PM, Johan Hovold jo...@kernel.org wrote:
  On Wed, Oct 08, 2014 at 01:54:07PM +0300, Octavian Purdila wrote:
  On Wed, Oct 8, 2014 at 12:23 PM, Johan Hovold jo...@kernel.org wrote:
   On Thu, Sep 25, 2014 at 07:07:31PM +0300, Octavian Purdila wrote:
  
   +static void dln2_rx_transfer(struct dln2_dev *dln2, struct urb *urb,
   +  u16 handle, u16 rx_slot)
   +{
   + struct dln2_mod_rx_slots *rxs = dln2-mod_rx_slots[handle];
   + struct dln2_rx_context *rxc;
   + struct device *dev = dln2-interface-dev;
   +
   + spin_lock(rxs-lock);
  
   You must use spin_lock_irqsave here as you call it from the completion
   handler.
 
  Why? AFAICS the completion handler gets called from the HCD irq handler:
 
  The completion handler is currently called with local interrupts
  disabled but that is about to change once all drivers have been updated:
 
  http://marc.info/?l=linux-usbm=137353360511003w=2
 
  In this case you could probably get away with not disabling interrupts
  anyway, but using the irqsave versions would make it obvious.
 
 
 I was not assuming that interrupts are disabled while running the
 completion handler. Since that spinlock is not touched by any other
 interrupt context code I don't think irqsave is necessary.

No, it isn't necessary so leave it as it is.

But you are exporting interfaces to other drivers and it may appear to
someone that those could possibly end up indirectly calling a function
taking that lock in IRQ context. We know that isn't the case now, but I
bet someone will post conversion patch for that spinlock at some point.
;)

Johan
--
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: mpc: Report correct I2C error codes on Freescale MPC i2c bus driver

2014-10-09 Thread Mark Roszko
Hi,

1. You are going to want to resend your patch using git-send-mail, you
used an email client that destroyed all formatting. gmail in
particular is good at breaking things so your patch cannot be applied
correctly.
2. You need to add a Signed-off-by line like other patches people submit.
3. You may want to consider CCing Wolfram the i2c subsystem maintainer
since there's no bus driver maintainer

see: https://www.kernel.org/doc/Documentation/SubmittingPatches
--
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 v7 1/4] mfd: add support for Diolan DLN-2 devices

2014-10-09 Thread Octavian Purdila
This patch implements the USB part of the Diolan USB-I2C/SPI/GPIO
Master Adapter DLN-2. Details about the device can be found here:

https://www.diolan.com/i2c/i2c_interface.html.

Information about the USB protocol can be found in the Programmer's
Reference Manual [1], see section 1.7.

Because the hardware has a single transmit endpoint and a single
receive endpoint the communication between the various DLN2 drivers
and the hardware will be muxed/demuxed by this driver.

Each DLN2 module will be identified by the handle field within the DLN2
message header. If a DLN2 module issues multiple commands in parallel
they will be identified by the echo counter field in the message header.

The DLN2 modules can use the dln2_transfer() function to issue a
command and wait for its response. They can also register a callback
that is going to be called when a specific event id is generated by
the device (e.g. GPIO interrupts). The device uses handle 0 for
sending events.

[1] https://www.diolan.com/downloads/dln-api-manual.pdf

Signed-off-by: Octavian Purdila octavian.purd...@intel.com
---
 drivers/mfd/Kconfig  |   9 +
 drivers/mfd/Makefile |   1 +
 drivers/mfd/dln2.c   | 755 +++
 include/linux/mfd/dln2.h |  67 +
 4 files changed, 832 insertions(+)
 create mode 100644 drivers/mfd/dln2.c
 create mode 100644 include/linux/mfd/dln2.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c9200d3..8ae33dc 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -189,6 +189,15 @@ config MFD_DA9063
  Additional drivers must be enabled in order to use the functionality
  of the device.
 
+config MFD_DLN2
+   tristate Diolan DLN2 support
+   select MFD_CORE
+   depends on USB
+   help
+ This adds support for Diolan USB-I2C/SPI/GPIO Master Adapter DLN-2.
+ Additional drivers must be enabled in order to use the functionality
+ of the device.
+
 config MFD_MC13XXX
tristate
depends on (SPI_MASTER || I2C)
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 61f8dbf..2cd7e74 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -175,6 +175,7 @@ obj-$(CONFIG_MFD_STW481X)   += stw481x.o
 obj-$(CONFIG_MFD_IPAQ_MICRO)   += ipaq-micro.o
 obj-$(CONFIG_MFD_MENF21BMC)+= menf21bmc.o
 obj-$(CONFIG_MFD_HI6421_PMIC)  += hi6421-pmic-core.o
+obj-$(CONFIG_MFD_DLN2) += dln2.o
 
 intel-soc-pmic-objs:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)   += intel-soc-pmic.o
diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
new file mode 100644
index 000..c436f0a
--- /dev/null
+++ b/drivers/mfd/dln2.c
@@ -0,0 +1,755 @@
+/*
+ * Driver for the Diolan DLN-2 USB adapter
+ *
+ * Copyright (c) 2014 Intel Corporation
+ *
+ * Derived from:
+ *  i2c-diolan-u2c.c
+ *  Copyright (c) 2010-2011 Ericsson AB
+ *
+ * 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.
+ */
+
+#include linux/kernel.h
+#include linux/module.h
+#include linux/types.h
+#include linux/slab.h
+#include linux/usb.h
+#include linux/i2c.h
+#include linux/mutex.h
+#include linux/platform_device.h
+#include linux/mfd/core.h
+#include linux/mfd/dln2.h
+#include linux/rculist.h
+
+struct dln2_header {
+   __le16 size;
+   __le16 id;
+   __le16 echo;
+   __le16 handle;
+} __packed;
+
+struct dln2_response {
+   struct dln2_header hdr;
+   __le16 result;
+} __packed;
+
+#define DLN2_GENERIC_MODULE_ID 0x00
+#define DLN2_GENERIC_CMD(cmd)  DLN2_CMD(cmd, DLN2_GENERIC_MODULE_ID)
+#define CMD_GET_DEVICE_VER DLN2_GENERIC_CMD(0x30)
+#define CMD_GET_DEVICE_SN  DLN2_GENERIC_CMD(0x31)
+
+#define DLN2_HW_ID 0x200
+#define DLN2_USB_TIMEOUT   200 /* in ms */
+#define DLN2_MAX_RX_SLOTS  16
+#define DLN2_MAX_URBS  16
+#define DLN2_RX_BUF_SIZE   512
+
+enum dln2_handle {
+   DLN2_HANDLE_EVENT = 0,  /* don't change, hardware defined */
+   DLN2_HANDLE_CTRL,
+   DLN2_HANDLE_GPIO,
+   DLN2_HANDLE_I2C,
+   DLN2_HANDLES
+};
+
+/*
+ * Receive context used between the receive demultiplexer and the
+ * transfer routine. While sending a request the transfer routine
+ * will look for a free receive context and use it to wait for a
+ * response and to receive the URB and thus the response data.
+ */
+struct dln2_rx_context {
+   /* completion used to wait for a response */
+   struct completion done;
+
+   /* if non-NULL the URB contains the response */
+   struct urb *urb;
+
+   /* if true then this context is used to wait for a response */
+   bool in_use;
+};
+
+/*
+ * Receive contexts for a particular DLN2 module (i2c, gpio, etc.). We
+ * use the handle header field to identify the 

[PATCH v7 3/4] gpiolib: add irq_not_threaded flag to gpio_chip

2014-10-09 Thread Octavian Purdila
Some GPIO chips (e.g. the DLN2 USB adapter) have blocking get/set
operation but do not need a threaded irq handler.

Signed-off-by: Octavian Purdila octavian.purd...@intel.com
---
 drivers/gpio/gpiolib.c  | 2 +-
 include/linux/gpio/driver.h | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 15cc0bb..3fa7e73 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -447,7 +447,7 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned 
int irq,
irq_set_lockdep_class(irq, gpiochip_irq_lock_class);
irq_set_chip_and_handler(irq, chip-irqchip, chip-irq_handler);
/* Chips that can sleep need nested thread handlers */
-   if (chip-can_sleep)
+   if (chip-can_sleep  !chip-irq_not_threaded)
irq_set_nested_thread(irq, 1);
 #ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index e78a237..44161ac 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -56,6 +56,8 @@ struct seq_file;
  * as the chip access may sleep when e.g. reading out the IRQ status
  * registers.
  * @exported: flags if the gpiochip is exported for use from sysfs. Private.
+ * @irq_not_threaded: flag must be set if @can_sleep is set but the
+ * IRQs don't need to be threaded
  *
  * A gpio_chip can help platforms abstract various sources of GPIOs so
  * they can all be accessed through a common programing interface.
@@ -101,6 +103,7 @@ struct gpio_chip {
struct gpio_desc*desc;
const char  *const *names;
boolcan_sleep;
+   boolirq_not_threaded;
boolexported;
 
 #ifdef CONFIG_GPIOLIB_IRQCHIP
-- 
1.9.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 v7 2/4] i2c: add support for Diolan DLN-2 USB-I2C adapter

2014-10-09 Thread Octavian Purdila
From: Laurentiu Palcu laurentiu.pa...@intel.com

This patch adds support for the Diolan DLN-2 I2C master module. Due
to hardware limitations it does not support SMBUS quick commands.

Information about the USB protocol interface can be found in the
Programmer's Reference Manual [1], see section 6.2.2 for the I2C
master module commands and responses.

[1] https://www.diolan.com/downloads/dln-api-manual.pdf

Signed-off-by: Laurentiu Palcu laurentiu.pa...@intel.com
Signed-off-by: Octavian Purdila octavian.purd...@intel.com
---
 drivers/i2c/busses/Kconfig|  10 ++
 drivers/i2c/busses/Makefile   |   1 +
 drivers/i2c/busses/i2c-dln2.c | 275 ++
 3 files changed, 286 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-dln2.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2ac87fa..2f3f371 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -858,6 +858,16 @@ config I2C_DIOLAN_U2C
  This driver can also be built as a module.  If so, the module
  will be called i2c-diolan-u2c.
 
+config I2C_DLN2
+   tristate Diolan DLN-2 USB I2C adapter
+   depends on MFD_DLN2
+   help
+ If you say yes to this option, support will be included for Diolan
+ DLN2, a USB to I2C interface.
+
+ This driver can also be built as a module.  If so, the module
+ will be called i2c-dln2.
+
 config I2C_PARPORT
tristate Parallel port adapter
depends on PARPORT
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 49bf07e..4755f79 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_I2C_RCAR)+= i2c-rcar.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_DIOLAN_U2C)   += i2c-diolan-u2c.o
+obj-$(CONFIG_I2C_DLN2) += i2c-dln2.o
 obj-$(CONFIG_I2C_PARPORT)  += i2c-parport.o
 obj-$(CONFIG_I2C_PARPORT_LIGHT)+= i2c-parport-light.o
 obj-$(CONFIG_I2C_ROBOTFUZZ_OSIF)   += i2c-robotfuzz-osif.o
diff --git a/drivers/i2c/busses/i2c-dln2.c b/drivers/i2c/busses/i2c-dln2.c
new file mode 100644
index 000..df8671c
--- /dev/null
+++ b/drivers/i2c/busses/i2c-dln2.c
@@ -0,0 +1,275 @@
+/*
+ * Driver for the Diolan DLN-2 USB-I2C adapter
+ *
+ * Copyright (c) 2014 Intel Corporation
+ *
+ * Derived from:
+ *  i2c-diolan-u2c.c
+ *  Copyright (c) 2010-2011 Ericsson AB
+ *
+ * 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.
+ */
+
+#include linux/kernel.h
+#include linux/module.h
+#include linux/types.h
+#include linux/slab.h
+#include linux/i2c.h
+#include linux/platform_device.h
+#include linux/mfd/dln2.h
+
+#define DLN2_I2C_MODULE_ID 0x03
+#define DLN2_I2C_CMD(cmd)  DLN2_CMD(cmd, DLN2_I2C_MODULE_ID)
+
+/* I2C commands */
+#define DLN2_I2C_GET_PORT_COUNTDLN2_I2C_CMD(0x00)
+#define DLN2_I2C_ENABLEDLN2_I2C_CMD(0x01)
+#define DLN2_I2C_DISABLE   DLN2_I2C_CMD(0x02)
+#define DLN2_I2C_IS_ENABLEDDLN2_I2C_CMD(0x03)
+#define DLN2_I2C_WRITE DLN2_I2C_CMD(0x06)
+#define DLN2_I2C_READ  DLN2_I2C_CMD(0x07)
+#define DLN2_I2C_SCAN_DEVICES  DLN2_I2C_CMD(0x08)
+#define DLN2_I2C_PULLUP_ENABLE DLN2_I2C_CMD(0x09)
+#define DLN2_I2C_PULLUP_DISABLEDLN2_I2C_CMD(0x0A)
+#define DLN2_I2C_PULLUP_IS_ENABLED DLN2_I2C_CMD(0x0B)
+#define DLN2_I2C_TRANSFER  DLN2_I2C_CMD(0x0C)
+#define DLN2_I2C_SET_MAX_REPLY_COUNT   DLN2_I2C_CMD(0x0D)
+#define DLN2_I2C_GET_MAX_REPLY_COUNT   DLN2_I2C_CMD(0x0E)
+
+#define DLN2_I2C_MAX_XFER_SIZE 256
+#define DLN2_I2C_BUF_SIZE  (DLN2_I2C_MAX_XFER_SIZE + 16)
+
+struct dln2_i2c {
+   struct platform_device *pdev;
+   struct i2c_adapter adapter;
+   u8 port;
+   /*
+* Buffer to hold the packet for read or write transfers. One
+* is enough since we can't have multiple transfers in
+* parallel on the i2c adapter.
+*/
+   void *buf;
+};
+
+static int dln2_i2c_enable(struct dln2_i2c *dln2, bool enable)
+{
+   int ret;
+   u16 cmd;
+   struct {
+   u8 port;
+   } tx;
+
+   tx.port = dln2-port;
+
+   if (enable)
+   cmd = DLN2_I2C_ENABLE;
+   else
+   cmd = DLN2_I2C_DISABLE;
+
+   ret = dln2_transfer(dln2-pdev, cmd, tx, sizeof(tx),
+   NULL, NULL);
+   if (ret  0)
+   return ret;
+
+   return 0;
+}
+
+static int dln2_i2c_setup(struct dln2_i2c *dln2)
+{
+   return dln2_i2c_enable(dln2, true);
+}
+
+static int dln2_i2c_write(struct dln2_i2c *dln2, u8 addr,
+ u8 *data, u16 data_len)
+{
+   int ret;
+   struct {
+   u8 port;
+   u8 addr;
+   u8 

Re: [PATCH v7 1/4] mfd: add support for Diolan DLN-2 devices

2014-10-09 Thread Joe Perches
On Thu, 2014-10-09 at 22:22 +0300, Octavian Purdila wrote:
 This patch implements the USB part of the Diolan USB-I2C/SPI/GPIO
 Master Adapter DLN-2. Details about the device can be found here:

trivia:

 diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
[]
 +config MFD_DLN2
 + tristate Diolan DLN2 support
 + select MFD_CORE
 + depends on USB
 + help
 +   This adds support for Diolan USB-I2C/SPI/GPIO Master Adapter DLN-2.
 +   Additional drivers must be enabled in order to use the functionality
 +   of the device.

additional drivers like...

 diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
[]
+struct dln2_mod_rx_slots {
+   /* RX slots bitmap */
+   unsigned long bmap;

Probably better as:
DECLARE_BITMAP(bmap, DLN2_MAX_RX_SLOTS);

Then a lot of ptr-bmap uses can be ptr-bmap

 +struct dln2_dev {
 + struct usb_device *usb_dev;
 + struct usb_interface *interface;
 + u8 ep_in;
 + u8 ep_out;
 +
 + struct urb *rx_urb[DLN2_MAX_URBS];
 + void *rx_buf[DLN2_MAX_URBS];
 +
 + struct dln2_mod_rx_slots mod_rx_slots[DLN2_HANDLES];
 +
 + struct list_head event_cb_list;
 + spinlock_t event_cb_lock;
 +
 + bool disconnect;
 + int active_transfers;
 + wait_queue_head_t disconnect_wq;
 + spinlock_t disconnect_lock;
 +};

Maybe reorder the bools and u8s to pack this a bit better?

 +int dln2_register_event_cb(struct platform_device *pdev, u16 id,
 +dln2_event_cb_t rx_cb)
 +{
 + struct dln2_dev *dln2 = dev_get_drvdata(pdev-dev.parent);
 + struct dln2_event_cb_entry *i, *new;

new isn't a very good name

 +static void dln2_run_event_callbacks(struct dln2_dev *dln2, u16 id, u16 echo,
 +  void *data, int len)
 +{
 + struct dln2_event_cb_entry *i;
 +
 + rcu_read_lock();
 +
 + list_for_each_entry_rcu(i, dln2-event_cb_list, list)
 + if (i-id == id)
 + i-callback(i-pdev, echo, data, len);

probably nicer with braces

 +static int dln2_setup_rx_urbs(struct dln2_dev *dln2,
 +   struct usb_host_interface *hostif)
 +{
 + int i;
 + const int rx_max_size = DLN2_RX_BUF_SIZE;
 +
 + for (i = 0; i  DLN2_MAX_URBS; i++) {
 + int ret;
 + struct device *dev = dln2-interface-dev;
 +
 + dln2-rx_buf[i] = kmalloc(rx_max_size, GFP_KERNEL);
 + if (!dln2-rx_buf[i])
 + return -ENOMEM;

memory leaks on failure?


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


[RFC PATCH 1/3] i2c: document the existing i2c sysfs ABI

2014-10-09 Thread Octavian Purdila
This patch adds Documentation/ABI/testing/sysfs-bus-i2c which
documents the existing i2c sysfs ABI.

Signed-off-by: Octavian Purdila octavian.purd...@intel.com
---
 Documentation/ABI/testing/sysfs-bus-i2c | 45 +
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c

diff --git a/Documentation/ABI/testing/sysfs-bus-i2c 
b/Documentation/ABI/testing/sysfs-bus-i2c
new file mode 100644
index 000..22c621a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-i2c
@@ -0,0 +1,45 @@
+What:  /sys/bus/i2c/devices/i2c-X
+KernelVersion: since at least 2.6.12
+Contact:   linux-i2c@vger.kernel.org
+Description:
+   This entry represents a registered i2c bus. X is the
+   bus number and its format is %d.
+
+What:  /sys/bus/i2c/devices/i2c-X/Y
+What:  /sys/bus/i2c/devices/Y
+KernelVersion: since at least 2.6.12
+Contact:   linux-i2c@vger.kernel.org
+Description:
+   An i2c device attached to bus X. Format of Y is
+   %d-%04x where the first number is the bus number (X)
+   and the second number is the device i2c address.
+
+What:  /sys/bus/i2c/devices/i2c-X/new_device
+KernelVersion: 2.6.31
+Contact:   linux-i2c@vger.kernel.org
+Description:
+   Write only entry that allows the instantiation of a
+   new i2c device to bus X. This is to be used when
+   enumeration mechanism such as ACPI or DT are not
+   present or not used for this device.
+   Format: %s %hi\n where the first argument is the
+   device name (no spaces allowed) and the second is the
+   i2c address of the device.
+
+What:  /sys/bus/i2c/devices/i2c-X/delete_device
+KernelVersion: 2.6.31
+Contact:   linux-i2c@vger.kernel.org
+Description:
+   Write only entry that allows the removal of an i2c
+   device from bus X.
+   Format: %s %hi\n where the first argument is the
+   device name (no spaces allowed) and the second is the
+   i2c address of the device.
+
+What:  /sys/bus/i2c/devices/i2c-X/i2c-Y
+What:  /sys/bus/i2c/devices/i2c-Y
+KernelVersion: 3.13
+Contact:   linux-i2c@vger.kernel.org
+Description:
+   An i2c device attached to bus X that is enumerated via
+   ACPI. Y is the ACPI device name and its format is %s.
-- 
1.9.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


[RFC PATCH 2/3] i2c: document struct i2c_adapter

2014-10-09 Thread Octavian Purdila
Document the i2c_adapter fields that must be initialized before
calling i2c_add_adapter().

Signed-off-by: Octavian Purdila octavian.purd...@intel.com
---
 include/linux/i2c.h | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index a95efeb..36041e2 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -418,9 +418,19 @@ int i2c_recover_bus(struct i2c_adapter *adap);
 int i2c_generic_gpio_recovery(struct i2c_adapter *adap);
 int i2c_generic_scl_recovery(struct i2c_adapter *adap);
 
-/*
- * i2c_adapter is the structure used to identify a physical i2c bus along
- * with the access algorithms necessary to access it.
+/**
+ * struct i2c_adapter - represents an I2C physical bus
+ *
+ * The following members must be set by the adapter driver before
+ * calling i2c_add_adapter():
+ *
+ * @owner: the module owner, usually THIS_MODULE
+ * @class: bitmask of I2C_CLASS_*
+ * @algo: see struct i2c_algorithm
+ * @dev.parent: set this to the struct device of the driver (e.g. pci_dev-dev,
+ * usb-interface-dev, platform_device-dev etc.)
+ * @name: name of this i2c bus
+ * @bus_recovery_info: see struct i2c_bus_recovery_info. Optional.
  */
 struct i2c_adapter {
struct module *owner;
-- 
1.9.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 v7 1/4] mfd: add support for Diolan DLN-2 devices

2014-10-09 Thread Octavian Purdila
On Thu, Oct 9, 2014 at 10:44 PM, Joe Perches j...@perches.com wrote:
 On Thu, 2014-10-09 at 22:22 +0300, Octavian Purdila wrote:
 This patch implements the USB part of the Diolan USB-I2C/SPI/GPIO
 Master Adapter DLN-2. Details about the device can be found here:

 trivia:

 diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
 []
 +config MFD_DLN2
 + tristate Diolan DLN2 support
 + select MFD_CORE
 + depends on USB
 + help
 +   This adds support for Diolan USB-I2C/SPI/GPIO Master Adapter DLN-2.
 +   Additional drivers must be enabled in order to use the functionality
 +   of the device.

 additional drivers like...


I will rephrase.

 diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
 []
 +struct dln2_mod_rx_slots {
 +   /* RX slots bitmap */
 +   unsigned long bmap;

 Probably better as:
 DECLARE_BITMAP(bmap, DLN2_MAX_RX_SLOTS);

 Then a lot of ptr-bmap uses can be ptr-bmap


Originally I was using DECLARE_BITMAP, but during the review process
Johan suggested to use unsigned long. Now that I think about it, it
sounds better to use DECLARE_BITMAP and of couse keep using
find_first_bit, set_bit, etc. Johan do you see any issue with that?

 +struct dln2_dev {
 + struct usb_device *usb_dev;
 + struct usb_interface *interface;
 + u8 ep_in;
 + u8 ep_out;
 +
 + struct urb *rx_urb[DLN2_MAX_URBS];
 + void *rx_buf[DLN2_MAX_URBS];
 +
 + struct dln2_mod_rx_slots mod_rx_slots[DLN2_HANDLES];
 +
 + struct list_head event_cb_list;
 + spinlock_t event_cb_lock;
 +
 + bool disconnect;
 + int active_transfers;
 + wait_queue_head_t disconnect_wq;
 + spinlock_t disconnect_lock;
 +};

 Maybe reorder the bools and u8s to pack this a bit better?


I prefer to keep it this way, it's not wasting a lot since you will
only have a handful of these devices, and it keeps the related data
together.

 +int dln2_register_event_cb(struct platform_device *pdev, u16 id,
 +dln2_event_cb_t rx_cb)
 +{
 + struct dln2_dev *dln2 = dev_get_drvdata(pdev-dev.parent);
 + struct dln2_event_cb_entry *i, *new;

 new isn't a very good name


Yes, new_cb should be better.

 +static void dln2_run_event_callbacks(struct dln2_dev *dln2, u16 id, u16 
 echo,
 +  void *data, int len)
 +{
 + struct dln2_event_cb_entry *i;
 +
 + rcu_read_lock();
 +
 + list_for_each_entry_rcu(i, dln2-event_cb_list, list)
 + if (i-id == id)
 + i-callback(i-pdev, echo, data, len);

 probably nicer with braces

 +static int dln2_setup_rx_urbs(struct dln2_dev *dln2,
 +   struct usb_host_interface *hostif)
 +{
 + int i;
 + const int rx_max_size = DLN2_RX_BUF_SIZE;
 +
 + for (i = 0; i  DLN2_MAX_URBS; i++) {
 + int ret;
 + struct device *dev = dln2-interface-dev;
 +
 + dln2-rx_buf[i] = kmalloc(rx_max_size, GFP_KERNEL);
 + if (!dln2-rx_buf[i])
 + return -ENOMEM;

 memory leaks on failure?


No, dln2_free_rx_urbs will do the cleanup (even in case of failures above).

Thanks for the review Joe.
--
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