[PATCH v4 3/3] i2c-piix4: Add adapter port name support for SB800 chipset

2015-11-15 Thread Christian Fetzer
This patch adds support for port names for the SB800 chipset.
Since the chipset supports a multiplexed main SMBus controller, adding
the channel name to the adapter name is necessary to differentiate the
ports better (for example in sensors output).

Signed-off-by: Christian Fetzer 
Reviewed-by: Mika Westerberg 
---
 drivers/i2c/busses/i2c-piix4.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 780f2b9..cd2b098 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -132,6 +132,12 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
{ },
 };
 
+/* SB800 globals */
+static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = {
+   "SDA0", "SDA2", "SDA3", "SDA4"
+};
+static const char *piix4_aux_port_name_sb800 = "SDA1";
+
 struct i2c_piix4_adapdata {
unsigned short smba;
 
@@ -615,7 +621,7 @@ static struct i2c_adapter 
*piix4_main_adapters[PIIX4_MAX_ADAPTERS];
 static struct i2c_adapter *piix4_aux_adapter;
 
 static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
-struct i2c_adapter **padap)
+const char *name, struct i2c_adapter **padap)
 {
struct i2c_adapter *adap;
struct i2c_piix4_adapdata *adapdata;
@@ -644,7 +650,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned 
short smba,
adap->dev.parent = >dev;
 
snprintf(adap->name, sizeof(adap->name),
-   "SMBus PIIX4 adapter at %04x", smba);
+   "SMBus PIIX4 adapter %s at %04x", name, smba);
 
i2c_set_adapdata(adap, adapdata);
 
@@ -676,6 +682,7 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, 
unsigned short smba)
 
for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
retval = piix4_add_adapter(dev, smba,
+  piix4_main_port_names_sb800[port],
   _main_adapters[port]);
if (retval < 0)
goto error;
@@ -745,7 +752,7 @@ static int piix4_probe(struct pci_dev *dev, const struct 
pci_device_id *id)
return retval;
 
/* Try to register main SMBus adapter, give up if we can't */
-   retval = piix4_add_adapter(dev, retval,
+   retval = piix4_add_adapter(dev, retval, "main",
   _main_adapters[0]);
if (retval < 0)
return retval;
@@ -772,7 +779,8 @@ static int piix4_probe(struct pci_dev *dev, const struct 
pci_device_id *id)
if (retval > 0) {
/* Try to add the aux adapter if it exists,
 * piix4_add_adapter will clean up if this fails */
-   piix4_add_adapter(dev, retval, _aux_adapter);
+   piix4_add_adapter(dev, retval, piix4_aux_port_name_sb800,
+ _aux_adapter);
}
 
return 0;
-- 
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 v4 2/3] i2c-piix4: Add support for multiplexed main adapter in SB800

2015-11-15 Thread Christian Fetzer
The SB800 chipset supports a multiplexed main SMBus controller with
four ports. The multiplexed ports share the same SMBus address and
register set. The port is selected by bits 2:1 of the smb_en register
(0x2C).

Only one port can be active at any point in time therefore a mutex is
needed in order to synchronize access.

Additionally, the commit avoids requesting and releasing the SMBus base
address index region on every multiplexed transfer by moving the
request_region call into piix4_probe.

Tested on HP ProLiant MicroServer G7 N54L (where this patch adds
support to access sensor data from the w83795adg).

Cc: Thomas Brandon 
Cc: Eddi De Pieri 
Signed-off-by: Christian Fetzer 
---
 drivers/i2c/busses/i2c-piix4.c | 165 +++--
 1 file changed, 143 insertions(+), 22 deletions(-)

diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 9c32eb1..780f2b9 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -23,6 +23,9 @@
 
Note: we assume there can only be one device, with one or more
SMBus interfaces.
+   The device can register multiple i2c_adapters (up to PIIX4_MAX_ADAPTERS).
+   For devices supporting multiple ports the i2c_adapter should provide
+   an i2c_algorithm to access them.
 */
 
 #include 
@@ -37,6 +40,7 @@
 #include 
 #include 
 #include 
+#include 
 
 
 /* PIIX4 SMBus address offsets */
@@ -78,6 +82,9 @@
 /* Multi-port constants */
 #define PIIX4_MAX_ADAPTERS 4
 
+/* SB800 constants */
+#define SB800_PIIX4_SMB_IDX 0xcd6
+
 /* insmod parameters */
 
 /* If force is set to anything different from 0, we forcibly enable the
@@ -127,6 +134,11 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
 
 struct i2c_piix4_adapdata {
unsigned short smba;
+
+   /* SB800 */
+   bool sb800_main;
+   unsigned short port;
+   struct mutex *mutex;
 };
 
 static int piix4_setup(struct pci_dev *PIIX4_dev,
@@ -232,7 +244,6 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 const struct pci_device_id *id, u8 aux)
 {
unsigned short piix4_smba;
-   unsigned short smba_idx = 0xcd6;
u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status;
u8 i2ccfg, i2ccfg_offset = 0x10;
 
@@ -254,16 +265,10 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
else
smb_en = (aux) ? 0x28 : 0x2c;
 
-   if (!request_region(smba_idx, 2, "smba_idx")) {
-   dev_err(_dev->dev, "SMBus base address index region "
-   "0x%x already in use!\n", smba_idx);
-   return -EBUSY;
-   }
-   outb_p(smb_en, smba_idx);
-   smba_en_lo = inb_p(smba_idx + 1);
-   outb_p(smb_en + 1, smba_idx);
-   smba_en_hi = inb_p(smba_idx + 1);
-   release_region(smba_idx, 2);
+   outb_p(smb_en, SB800_PIIX4_SMB_IDX);
+   smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
+   outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX);
+   smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1);
 
if (!smb_en) {
smb_en_status = smba_en_lo & 0x10;
@@ -527,6 +532,43 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 
addr,
return 0;
 }
 
+/*
+ * Handles access to multiple SMBus ports on the SB800.
+ * The port is selected by bits 2:1 of the smb_en register (0x2C).
+ * Returns negative errno on error.
+ *
+ * Note: The selected port must be returned to the initial selection to avoid
+ * problems on certain systems.
+ */
+static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
+unsigned short flags, char read_write,
+u8 command, int size, union i2c_smbus_data *data)
+{
+   struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
+   u8 smba_en_lo, smb_en = 0x2c;
+   u8 port;
+   int retval;
+
+   mutex_lock(adapdata->mutex);
+
+   outb_p(smb_en, SB800_PIIX4_SMB_IDX);
+   smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
+
+   port = adapdata->port;
+   if ((smba_en_lo & 6) != (port << 1))
+   outb_p((smba_en_lo & ~6) | (port << 1),
+  SB800_PIIX4_SMB_IDX + 1);
+
+   retval = piix4_access(adap, addr, flags, read_write,
+ command, size, data);
+
+   outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1);
+
+   mutex_unlock(adapdata->mutex);
+
+   return retval;
+}
+
 static u32 piix4_func(struct i2c_adapter *adapter)
 {
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
@@ -539,6 +581,11 @@ static const struct i2c_algorithm smbus_algorithm = {
.functionality  = piix4_func,
 };
 
+static const struct i2c_algorithm piix4_smbus_algorithm_sb800 = {
+   .smbus_xfer = piix4_access_sb800,
+   .functionality  = piix4_func,
+};
+
 static const struct pci_device_id piix4_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },

[PATCH v4 1/3] i2c-piix4: Convert piix4_main_adapter to array

2015-11-15 Thread Christian Fetzer
The SB800 chipset supports a multiplexed main SMBus controller with
four ports. Therefore the static variable piix4_main_adapter is
converted into a piix4_main_adapters array that can hold one
i2c_adapter for each multiplexed port.

The auxiliary adapter remains unchanged since it represents the second
(not multiplexed) SMBus controller on the SB800 chipset.

Signed-off-by: Christian Fetzer 
Reviewed-by: Mika Westerberg 
---
 drivers/i2c/busses/i2c-piix4.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 630bce6..9c32eb1 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -75,6 +75,9 @@
 #define PIIX4_WORD_DATA0x0C
 #define PIIX4_BLOCK_DATA   0x14
 
+/* Multi-port constants */
+#define PIIX4_MAX_ADAPTERS 4
+
 /* insmod parameters */
 
 /* If force is set to anything different from 0, we forcibly enable the
@@ -561,7 +564,7 @@ static const struct pci_device_id piix4_ids[] = {
 
 MODULE_DEVICE_TABLE (pci, piix4_ids);
 
-static struct i2c_adapter *piix4_main_adapter;
+static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
 static struct i2c_adapter *piix4_aux_adapter;
 
 static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
@@ -629,7 +632,7 @@ static int piix4_probe(struct pci_dev *dev, const struct 
pci_device_id *id)
return retval;
 
/* Try to register main SMBus adapter, give up if we can't */
-   retval = piix4_add_adapter(dev, retval, _main_adapter);
+   retval = piix4_add_adapter(dev, retval, _main_adapters[0]);
if (retval < 0)
return retval;
 
@@ -674,9 +677,13 @@ static void piix4_adap_remove(struct i2c_adapter *adap)
 
 static void piix4_remove(struct pci_dev *dev)
 {
-   if (piix4_main_adapter) {
-   piix4_adap_remove(piix4_main_adapter);
-   piix4_main_adapter = NULL;
+   int port = PIIX4_MAX_ADAPTERS;
+
+   while (--port >= 0) {
+   if (piix4_main_adapters[port]) {
+   piix4_adap_remove(piix4_main_adapters[port]);
+   piix4_main_adapters[port] = NULL;
+   }
}
 
if (piix4_aux_adapter) {
-- 
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 v4 0/3] Support multiplexed main SMBus interface on SB800

2015-11-15 Thread Christian Fetzer
This is an attempt to upstream the patches created by Thomas Brandon and
Eddi De Pieri to support the multiplexed main SMBus interface on the SB800
chipset. (https://www.mail-archive.com/linux-i2c@vger.kernel.org/msg06757.html)

I have mainly rebased the latest patch version and tested the driver on a
HP ProLiant MicroServer G7 N54L (where this patch allows to access sensor data
from a w83795adg).

The patched driver is running stable on the machine, given that ic2_piix4 is
loaded before jc42 and w83795. If jc42 is loaded before i2c_piix4 calling
sensors triggers some errors:
ERROR: Can't get value of subfeature temp1_min_alarm: Can't read

While the kernel log shows:
i2c i2c-1: Transaction (pre): CNT=0c, CMD=05, ADD=31, DAT0=03, DAT1=c0
i2c i2c-1: Error: no response!
i2c i2c-1: Transaction (post): CNT=0c, CMD=05, ADD=31, DAT0=ff, DAT1=ff
Unfortunately I don't know how to tackle this specific issue.

Please review and let me know required changes in order to get this upstream
finally.

Eddi, Thomas, it would be great if you could verify the changes on your
machines.

Regards,
Christian

v4:
- Incorporated changes requested by Andy
- added mutex to struct i2c_piix4_adapdata
- added flag for releasing SMBus index region to struct i2c_piix4_adapdata
- this flag now indicates that the adapter is a sb800 main adapter
- together with the port number it simplifies the adapter
  releasing and the first patch in v3 is no more needed
- unfortunately patch 3 and 4 in v3 had to be combined as only
  the patch introducing multiplexing adds a separate add_adapters_sb800
  method that can be used to set the flag.
- fixed releasing the SMBus index region in case setting up the
  adapter fails

v3:
- Incorporated changes requested by Mika and Andy
- main adapter name set to 'main'
- defined constant idx address
- block comment style, joined string literals, reworked for loops
  into while loops

v2:
- Incorporated changes requested by Mika
- remove adapter in reverse order
- ERROR label
- request base address index region only once

Christian Fetzer (3):
  i2c-piix4: Convert piix4_main_adapter to array
  i2c-piix4: Add support for multiplexed main adapter in SB800
  i2c-piix4: Add adapter port name support for SB800 chipset

 drivers/i2c/busses/i2c-piix4.c | 194 +++--
 1 file changed, 165 insertions(+), 29 deletions(-)

-- 
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: i2c slave support für i.mx6

2015-11-15 Thread Michael Bachmeier
Hi,

I'm just going to rewrite your rcar driver for the i.mx6 processor.

thanks to your comments in the rcar driver, I understand the function
of each register. But I'd like a manual of this board. Where is
accurately entered into the individual registers.
The product spectrum from Renesas is very large and actually very
confusing for me.
Had someone for me a manual by the individual registers are explained.
So that I can understand the rcar driver better.


thanks

2015-11-10 9:59 GMT+01:00 Wolfram Sang :
> Hi Michael,
>
>> Do I understand it right, I can set the Master in slave mode and the
>> new slave get his own i2c-adresse?
>
> Yes, you can have your own address then. Note that I recently gave a
> talk about the slave framework. You can find the slides here:
>
> http://elinux.org/ELCE_2015_Presentations
>
> Search for my name there. And if you wait some more, the video will be
> there, too, which will be much more helpful than the slides only. And
> there is the regular documentation:
>
> Documentation/i2c/slave-interface
>
>> Say that, I can connect a Master from the outside, without this
>> leading to problems?
>> If the master switch to slave, then stops SCL? Or how does it work?
>
> I suggest getting the I2C specifications from the web and read about
> "multi master" and "bus arbitration" to understand how it works. Please
> note that true multi-master busses can in practice be tricky. Shall your
> mx6 also be master, or slave only?
>
>> Is the EEPROM simulator only available if I rewrote "i2c-IMX" drivers
>> to the slave support?
>
> Yes.
>
>> Does anyone know if anyone is working on this driver?
>
> I don't know of; but I put some more people on CC who regularly work on
> Freescale SoCs.
>
>> Would it theoretically be enough to write 0x80 in the "I2Cx_I2CR"
>> register to set MSTA Bit to
>> slave mode. "Changing MSTA from 1 to 0 generates a Stop and selects Slave 
>> mode."
>> Or then disturbs the old driver?
>
> You need more to do this. You need to handle slave interrupts. See the
> documentation.
>
> Good luck,
>
>Wolfram
>
--
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