linux-m68k.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
@ 2019-08-11  4:32 Max Staudt
  2019-08-11  4:40 ` Max Staudt
  2019-08-12  9:37 ` Geert Uytterhoeven
  0 siblings, 2 replies; 11+ messages in thread
From: Max Staudt @ 2019-08-11  4:32 UTC (permalink / raw)
  To: linux-i2c, Wolfram Sang; +Cc: linux-m68k, linux-kernel, glaubitz, Max Staudt

This is the i2c-icy driver for the ICY board for Amiga computers.
It connects a PCF8584 I2C controller to the Zorro bus, providing I2C
connectivity. The original documentation can be found on Aminet:

https://aminet.net/package/docs/hard/icy

Since the 2019 a1k.org community re-print of these PCBs sports an
LTC2990 hwmon chip as an example use case, this driver autoprobes for
that as well. If it is present, modprobing ltc2990 is sufficient.

IRQ support is currently not implemented, as i2c-algo-pcf is built for
the ISA bus and a straight implementation of the same stack locks up a
Zorro machine.

Tested-by: Max Staudt <max@enpas.org>
Signed-off-by: Max Staudt <max@enpas.org>
---
 MAINTAINERS                  |   6 ++
 drivers/i2c/busses/Kconfig   |  11 +++
 drivers/i2c/busses/Makefile  |   1 +
 drivers/i2c/busses/i2c-icy.c | 224 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 242 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-icy.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1be025959..70336c083 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7705,6 +7705,12 @@ S:	Maintained
 F:	drivers/mfd/lpc_ich.c
 F:	drivers/gpio/gpio-ich.c
 
+ICY I2C DRIVER
+M:	Max Staudt <max@enpas.org>
+L:	linux-i2c@vger.kernel.org
+S:	Maintained
+F:	drivers/i2c/busses/i2c-icy.c
+
 IDE SUBSYSTEM
 M:	"David S. Miller" <davem@davemloft.net>
 L:	linux-ide@vger.kernel.org
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index ee5dfb5ae..e798b8517 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1300,6 +1300,17 @@ config I2C_ELEKTOR
 	  This support is also available as a module.  If so, the module
 	  will be called i2c-elektor.
 
+config I2C_ICY
+	tristate "ICY Zorro card"
+	depends on ZORRO && BROKEN_ON_SMP
+	select I2C_ALGOPCF
+	help
+	  This supports the PCF8584 Zorro bus I2C adapter, known as ICY.
+	  Say Y if you own such an adapter.
+
+	  This support is also available as a module.  If so, the module
+	  will be called i2c-icy.
+
 config I2C_MLXCPLD
 	tristate "Mellanox I2C driver"
 	depends on X86_64
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index a3245231b..d0e1c3d4e 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -139,6 +139,7 @@ obj-$(CONFIG_I2C_BCM_KONA)	+= i2c-bcm-kona.o
 obj-$(CONFIG_I2C_BRCMSTB)	+= i2c-brcmstb.o
 obj-$(CONFIG_I2C_CROS_EC_TUNNEL)	+= i2c-cros-ec-tunnel.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
+obj-$(CONFIG_I2C_ICY)		+= i2c-icy.o
 obj-$(CONFIG_I2C_MLXCPLD)	+= i2c-mlxcpld.o
 obj-$(CONFIG_I2C_OPAL)		+= i2c-opal.o
 obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o
diff --git a/drivers/i2c/busses/i2c-icy.c b/drivers/i2c/busses/i2c-icy.c
new file mode 100644
index 000000000..037fdfe32
--- /dev/null
+++ b/drivers/i2c/busses/i2c-icy.c
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * I2C driver for stand-alone PCF8584 style adapters on Zorro cards
+ *
+ * Original ICY documentation can be found on Aminet:
+ * https://aminet.net/package/docs/hard/icy
+ *
+ * There has been a modern community re-print of this design in 2019:
+ * https://www.a1k.org/forum/index.php?threads/70106/
+ *
+ * The card is basically a Philips PCF8584 connected straight to the
+ * beginning of the AutoConfig'd address space (register S1 on base+2),
+ * with /INT on /INT2 on the Zorro bus.
+ *
+ * Copyright (c) 2019 Max Staudt <max@enpas.org>
+ *
+ * This is heavily based on i2c-elektor.c and thanks go to:
+ *
+ * Simon G. Vogl
+ * Hans Berglund
+ * Kyosti Malkki <kmalkki@cc.hut.fi>
+ * Frodo Looijaard <frodol@dds.nl>
+ * Oleg I. Vdovikin
+ *
+ *
+ * IRQ support is currently not implemented.
+ *
+ * As it turns out, i2c-algo-pcf is really written with i2c-elektor's
+ * edge-triggered ISA interrupts in mind, while the Amiga's Zorro bus has
+ * level-triggered interrupts. This means that once an interrupt occurs, we
+ * have to tell the PCF8584 to shut up immediately, or it will keep the
+ * interrupt line busy and cause an IRQ storm.
+
+ * However, because of the PCF8584's host-side protocol, there is no good
+ * way to just quieten it without side effects. Rather, we have to perform
+ * the next read/write operation straight away, which will reset the /INT
+ * pin. This entails re-designing the core of i2c-algo-pcf in the future.
+ * For now, we never request an IRQ from the PCF8584, and poll it instead.
+ */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-pcf.h>
+#include <linux/io.h>
+
+#include <asm/amigaints.h>
+#include <linux/zorro.h>
+
+#include "../algos/i2c-algo-pcf.h"
+
+
+static int clock = 0x1c;
+module_param(clock, int, 0444);
+
+
+
+struct icy_i2c {
+	struct i2c_adapter adapter;
+
+	void __iomem *reg_s0;
+	void __iomem *reg_s1;
+	struct i2c_client *client_ltc2990;
+};
+
+
+
+/*
+ * Functions called by i2c-algo-pcf
+ */
+static void icy_pcf_setbyte(void *data, int ctl, int val)
+{
+	struct icy_i2c *i2c = (struct icy_i2c *)data;
+
+	u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
+
+	iowrite8(val, address);
+}
+
+static int icy_pcf_getbyte(void *data, int ctl)
+{
+	struct icy_i2c *i2c = (struct icy_i2c *)data;
+
+	u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
+	int val = ioread8(address);
+
+	return val;
+}
+
+static int icy_pcf_getown(void *data)
+{
+	return 0x55;
+}
+
+static int icy_pcf_getclock(void *data)
+{
+	return clock;
+}
+
+static void icy_pcf_waitforpin(void *data)
+{
+	udelay(100);
+}
+
+
+
+/*
+ * Main i2c-icy part
+ */
+static struct i2c_board_info icy_ltc2990_info = {
+	I2C_BOARD_INFO("ltc2990", 0x4c),
+};
+
+static unsigned short const icy_ltc2990_addresses[] = {0x4c, I2C_CLIENT_END};
+
+
+static int icy_probe(struct zorro_dev *z,
+			 const struct zorro_device_id *ent)
+{
+	struct icy_i2c *i2c;
+	struct i2c_algo_pcf_data *algo_data;
+
+
+	i2c = devm_kzalloc(&z->dev, sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
+
+	algo_data = devm_kzalloc(&z->dev, sizeof(*algo_data), GFP_KERNEL);
+	if (!algo_data)
+		return -ENOMEM;
+
+	dev_set_drvdata(&z->dev, i2c);
+	i2c->adapter.dev.parent = &z->dev;
+	i2c->adapter.owner = THIS_MODULE;
+	i2c->adapter.class = I2C_CLASS_DEPRECATED;
+	/* i2c->adapter.algo assigned by i2c_pcf_add_bus() */
+	i2c->adapter.algo_data = algo_data;
+	strlcpy(i2c->adapter.name, "ICY I2C Zorro adapter",
+		sizeof(i2c->adapter.name));
+
+	if (!devm_request_mem_region(&z->dev,
+				     z->resource.start,
+				     4, i2c->adapter.name))
+		return -ENXIO;
+
+	/* Driver private data */
+	i2c->reg_s0 = ZTWO_VADDR(z->resource.start);
+	i2c->reg_s1 = ZTWO_VADDR(z->resource.start + 2);
+
+	algo_data->data = (void *)i2c;
+	algo_data->setpcf     = icy_pcf_setbyte;
+	algo_data->getpcf     = icy_pcf_getbyte;
+	algo_data->getown     = icy_pcf_getown;
+	algo_data->getclock   = icy_pcf_getclock;
+	algo_data->waitforpin = icy_pcf_waitforpin;
+
+	if (i2c_pcf_add_bus(&i2c->adapter)) {
+		dev_err(&z->dev, "i2c_pcf_add_bus() failed\n");
+		return -ENXIO;
+	}
+
+	dev_info(&z->dev, "ICY I2C controller at %#x, IRQ not implemented\n",
+		 z->resource.start);
+
+	/*
+	 * The 2019 a1k.org PCBs have an LTC2990 at 0x4c, so start
+	 * it automatically once ltc2990 is modprobed.
+	 *
+	 * in0 is the voltage of the internal 5V power supply.
+	 * temp1 is the temperature inside the chip.
+	 *
+	 * Configuration 0x18 enables all sensors on this PCB:
+	 *  # modprobe i2c-dev
+	 *  # i2cset 0 0x4c 1 0x18
+	 *  # modprobe ltc2990
+	 * in1 will be the voltage of the 5V rail, divided by 2.
+	 * in2 will be the voltage of the 12V rail, divided by 4.
+	 * temp3 will be measured using a PCB loop next the chip.
+	 */
+	i2c->client_ltc2990 = i2c_new_probed_device(&i2c->adapter,
+						    &icy_ltc2990_info,
+						    icy_ltc2990_addresses,
+						    NULL);
+
+	return 0;
+}
+
+static void icy_remove(struct zorro_dev *z)
+{
+	struct icy_i2c *i2c = dev_get_drvdata(&z->dev);
+
+	i2c_unregister_device(i2c->client_ltc2990);
+
+	i2c_del_adapter(&i2c->adapter);
+}
+
+
+
+static const struct zorro_device_id icy_zorro_tbl[] = {
+	{ ZORRO_ID(VMC, 15, 0), },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(zorro, icy_zorro_tbl);
+
+static struct zorro_driver icy_driver = {
+	.name           = "i2c-icy",
+	.id_table       = icy_zorro_tbl,
+	.probe          = icy_probe,
+	.remove         = icy_remove,
+};
+
+module_driver(icy_driver,
+	      zorro_register_driver,
+	      zorro_unregister_driver);
+
+
+MODULE_AUTHOR("Max Staudt <max@enpas.org>");
+MODULE_DESCRIPTION("I2C bus via PCF8584 on ICY Zorro card");
+MODULE_LICENSE("GPL");
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-11  4:32 [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga Max Staudt
@ 2019-08-11  4:40 ` Max Staudt
  2019-08-12  9:37 ` Geert Uytterhoeven
  1 sibling, 0 replies; 11+ messages in thread
From: Max Staudt @ 2019-08-11  4:40 UTC (permalink / raw)
  To: linux-i2c, Wolfram Sang; +Cc: linux-m68k, linux-kernel, glaubitz

On 08/11/2019 06:32 AM, Max Staudt wrote:
> --- a/drivers/i2c/busses/Kconfig
> +++ b/drivers/i2c/busses/Kconfig
> @@ -1300,6 +1300,17 @@ config I2C_ELEKTOR
>  	  This support is also available as a module.  If so, the module
>  	  will be called i2c-elektor.
>  
> +config I2C_ICY
> +	tristate "ICY Zorro card"
> +	depends on ZORRO && BROKEN_ON_SMP
> +	select I2C_ALGOPCF


I forgot to remove BROKEN_ON_SMP - I see no reason why this would be the case with the polling-only driver as it is now.


Max

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-11  4:32 [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga Max Staudt
  2019-08-11  4:40 ` Max Staudt
@ 2019-08-12  9:37 ` Geert Uytterhoeven
  2019-08-12 10:43   ` Max Staudt
  2019-08-12 22:21   ` Max Staudt
  1 sibling, 2 replies; 11+ messages in thread
From: Geert Uytterhoeven @ 2019-08-12  9:37 UTC (permalink / raw)
  To: Max Staudt
  Cc: Linux I2C, Wolfram Sang, Linux/m68k, Linux Kernel Mailing List,
	John Paul Adrian Glaubitz

Hi Max,

Thanks for your patch!

On Sun, Aug 11, 2019 at 6:33 AM Max Staudt <max@enpas.org> wrote:
> This is the i2c-icy driver for the ICY board for Amiga computers.
> It connects a PCF8584 I2C controller to the Zorro bus, providing I2C
> connectivity. The original documentation can be found on Aminet:
>
> https://aminet.net/package/docs/hard/icy
>
> Since the 2019 a1k.org community re-print of these PCBs sports an
> LTC2990 hwmon chip as an example use case, this driver autoprobes for
> that as well. If it is present, modprobing ltc2990 is sufficient.

What about the RTC? The schematics show both a ds1620 and pcf8583.

> IRQ support is currently not implemented, as i2c-algo-pcf is built for
> the ISA bus and a straight implementation of the same stack locks up a
> Zorro machine.
>
> Tested-by: Max Staudt <max@enpas.org>

This tag is usually implied for a driver author ;-)

> Signed-off-by: Max Staudt <max@enpas.org>

> --- /dev/null
> +++ b/drivers/i2c/busses/i2c-icy.c

> +/*
> + * Functions called by i2c-algo-pcf
> + */
> +static void icy_pcf_setbyte(void *data, int ctl, int val)

icy_pcf_setpcf(), to match the callback name?

> +{
> +       struct icy_i2c *i2c = (struct icy_i2c *)data;
> +
> +       u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
> +
> +       iowrite8(val, address);

As this is on a Zorro bus, z_writeb()?

> +}
> +
> +static int icy_pcf_getbyte(void *data, int ctl)

icy_pcf_getpcf(), to match the callback name?


> +{
> +       struct icy_i2c *i2c = (struct icy_i2c *)data;
> +
> +       u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
> +       int val = ioread8(address);

z_readb()

> +
> +       return val;
> +}

> +static int icy_probe(struct zorro_dev *z,
> +                        const struct zorro_device_id *ent)
> +{
> +       struct icy_i2c *i2c;
> +       struct i2c_algo_pcf_data *algo_data;
> +
> +
> +       i2c = devm_kzalloc(&z->dev, sizeof(*i2c), GFP_KERNEL);
> +       if (!i2c)
> +               return -ENOMEM;
> +
> +       algo_data = devm_kzalloc(&z->dev, sizeof(*algo_data), GFP_KERNEL);
> +       if (!algo_data)
> +               return -ENOMEM;
> +
> +       dev_set_drvdata(&z->dev, i2c);
> +       i2c->adapter.dev.parent = &z->dev;
> +       i2c->adapter.owner = THIS_MODULE;
> +       i2c->adapter.class = I2C_CLASS_DEPRECATED;
> +       /* i2c->adapter.algo assigned by i2c_pcf_add_bus() */
> +       i2c->adapter.algo_data = algo_data;
> +       strlcpy(i2c->adapter.name, "ICY I2C Zorro adapter",
> +               sizeof(i2c->adapter.name));
> +
> +       if (!devm_request_mem_region(&z->dev,
> +                                    z->resource.start,
> +                                    4, i2c->adapter.name))

zorro_request_device()?
Ah, there's no devm_*() variant yet. OK.

> +               return -ENXIO;
> +
> +       /* Driver private data */
> +       i2c->reg_s0 = ZTWO_VADDR(z->resource.start);
> +       i2c->reg_s1 = ZTWO_VADDR(z->resource.start + 2);
> +
> +       algo_data->data = (void *)i2c;
> +       algo_data->setpcf     = icy_pcf_setbyte;
> +       algo_data->getpcf     = icy_pcf_getbyte;
> +       algo_data->getown     = icy_pcf_getown;
> +       algo_data->getclock   = icy_pcf_getclock;
> +       algo_data->waitforpin = icy_pcf_waitforpin;
> +
> +       if (i2c_pcf_add_bus(&i2c->adapter)) {
> +               dev_err(&z->dev, "i2c_pcf_add_bus() failed\n");
> +               return -ENXIO;
> +       }
> +
> +       dev_info(&z->dev, "ICY I2C controller at %#x, IRQ not implemented\n",
> +                z->resource.start);
> +
> +       /*
> +        * The 2019 a1k.org PCBs have an LTC2990 at 0x4c, so start
> +        * it automatically once ltc2990 is modprobed.
> +        *
> +        * in0 is the voltage of the internal 5V power supply.
> +        * temp1 is the temperature inside the chip.
> +        *
> +        * Configuration 0x18 enables all sensors on this PCB:
> +        *  # modprobe i2c-dev
> +        *  # i2cset 0 0x4c 1 0x18

What's the reason for the i2cset command?

> +        *  # modprobe ltc2990
> +        * in1 will be the voltage of the 5V rail, divided by 2.
> +        * in2 will be the voltage of the 12V rail, divided by 4.
> +        * temp3 will be measured using a PCB loop next the chip.
> +        */
> +       i2c->client_ltc2990 = i2c_new_probed_device(&i2c->adapter,
> +                                                   &icy_ltc2990_info,
> +                                                   icy_ltc2990_addresses,
> +                                                   NULL);
> +
> +       return 0;
> +}

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-12  9:37 ` Geert Uytterhoeven
@ 2019-08-12 10:43   ` Max Staudt
  2019-08-12 11:07     ` Geert Uytterhoeven
  2019-08-12 22:21   ` Max Staudt
  1 sibling, 1 reply; 11+ messages in thread
From: Max Staudt @ 2019-08-12 10:43 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Linux I2C, Wolfram Sang, Linux/m68k, Linux Kernel Mailing List,
	John Paul Adrian Glaubitz

Hi Geert,

Thanks for your feedback!
Replies below.

On 08/12/2019 11:37 AM, Geert Uytterhoeven wrote:
> What about the RTC? The schematics show both a ds1620 and pcf8583.

Oh no! I missed those in the original project, in my mind it didn't have any extra hardware at all.

I only own the new board with the LTC2990, and I'm pretty sure there are more of these in circulation than the original board. So if it's okay, I'll skip the DS1620 and PCF8583.


>> +static void icy_pcf_setbyte(void *data, int ctl, int val)
> 
> icy_pcf_setpcf(), to match the callback name?

Fair. I kept the name when I cloned i2c-elektor.c.


> zorro_request_device()?
> Ah, there's no devm_*() variant yet. OK.

Also, I only wanted to reserve the first 4 bytes. Thinking about it now, it makes more sense to reserve the whole AutoConfig'd space, as I don't know whether the bus GAL maps the PCF8584 across the whole 64k repeatedly.


>> +       /*
>> +        * The 2019 a1k.org PCBs have an LTC2990 at 0x4c, so start
>> +        * it automatically once ltc2990 is modprobed.
>> +        *
>> +        * in0 is the voltage of the internal 5V power supply.
>> +        * temp1 is the temperature inside the chip.
>> +        *
>> +        * Configuration 0x18 enables all sensors on this PCB:
>> +        *  # modprobe i2c-dev
>> +        *  # i2cset 0 0x4c 1 0x18
> 
> What's the reason for the i2cset command?

It sets the sensor modes in the LTC2990 and enables the three sensors listed below. I should have clarified this.

I tried to integrate this in the driver, but ltc2990 only allows reading this configuration out of a device tree. Is there a good way to fake a DT entry in the init function?


> 
>> +        *  # modprobe ltc2990
>> +        * in1 will be the voltage of the 5V rail, divided by 2.
>> +        * in2 will be the voltage of the 12V rail, divided by 4.
>> +        * temp3 will be measured using a PCB loop next the chip.
>> +        */
>> +       i2c->client_ltc2990 = i2c_new_probed_device(&i2c->adapter,
>> +                                                   &icy_ltc2990_info,
>> +                                                   icy_ltc2990_addresses,
>> +                                                   NULL);
>> +
>> +       return 0;
>> +}


Thanks for your feedback,
Max

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-12 10:43   ` Max Staudt
@ 2019-08-12 11:07     ` Geert Uytterhoeven
  2019-08-12 11:48       ` Max Staudt
  0 siblings, 1 reply; 11+ messages in thread
From: Geert Uytterhoeven @ 2019-08-12 11:07 UTC (permalink / raw)
  To: Max Staudt
  Cc: Linux I2C, Wolfram Sang, Linux/m68k, Linux Kernel Mailing List,
	John Paul Adrian Glaubitz

Hi Max,

On Mon, Aug 12, 2019 at 12:43 PM Max Staudt <max@enpas.org> wrote:
> On 08/12/2019 11:37 AM, Geert Uytterhoeven wrote:
> >> +       /*
> >> +        * The 2019 a1k.org PCBs have an LTC2990 at 0x4c, so start
> >> +        * it automatically once ltc2990 is modprobed.
> >> +        *
> >> +        * in0 is the voltage of the internal 5V power supply.
> >> +        * temp1 is the temperature inside the chip.
> >> +        *
> >> +        * Configuration 0x18 enables all sensors on this PCB:
> >> +        *  # modprobe i2c-dev
> >> +        *  # i2cset 0 0x4c 1 0x18
> >
> > What's the reason for the i2cset command?
>
> It sets the sensor modes in the LTC2990 and enables the three sensors listed below. I should have clarified this.
>
> I tried to integrate this in the driver, but ltc2990 only allows reading this configuration out of a device tree. Is there a good way to fake a DT entry in the init function?

You can add platform_data support to the ltc2990 driver, and pass it
through i2c_board_info.platform_data.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-12 11:07     ` Geert Uytterhoeven
@ 2019-08-12 11:48       ` Max Staudt
  0 siblings, 0 replies; 11+ messages in thread
From: Max Staudt @ 2019-08-12 11:48 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Linux I2C, Wolfram Sang, Linux/m68k, Linux Kernel Mailing List,
	John Paul Adrian Glaubitz

On 08/12/2019 01:07 PM, Geert Uytterhoeven wrote:
>> It sets the sensor modes in the LTC2990 and enables the three sensors listed below. I should have clarified this.
>>
>> I tried to integrate this in the driver, but ltc2990 only allows reading this configuration out of a device tree. Is there a good way to fake a DT entry in the init function?
> 
> You can add platform_data support to the ltc2990 driver, and pass it
> through i2c_board_info.platform_data.

Thanks, that sounds good and I'll look into it.

Max

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-12  9:37 ` Geert Uytterhoeven
  2019-08-12 10:43   ` Max Staudt
@ 2019-08-12 22:21   ` Max Staudt
  2019-08-13  6:53     ` Geert Uytterhoeven
  1 sibling, 1 reply; 11+ messages in thread
From: Max Staudt @ 2019-08-12 22:21 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Linux I2C, Wolfram Sang, Linux/m68k, Linux Kernel Mailing List,
	John Paul Adrian Glaubitz

On 08/12/2019 11:37 AM, Geert Uytterhoeven wrote:
>> +       iowrite8(val, address);
> 
> As this is on a Zorro bus, z_writeb()?

I forgot to ask about this.

What is the reasoning behind having a separate z_writeb() for Zorro?
As far as I can see in arch/m68k/include/asm this maps 1:1 to a direct memory access, and it prohibits cross-arch code as in i2c-elektor.


Thanks,
Max

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-12 22:21   ` Max Staudt
@ 2019-08-13  6:53     ` Geert Uytterhoeven
  0 siblings, 0 replies; 11+ messages in thread
From: Geert Uytterhoeven @ 2019-08-13  6:53 UTC (permalink / raw)
  To: Max Staudt
  Cc: Linux I2C, Wolfram Sang, Linux/m68k, Linux Kernel Mailing List,
	John Paul Adrian Glaubitz

Hi Max,

On Tue, Aug 13, 2019 at 12:21 AM Max Staudt <max@enpas.org> wrote:
> On 08/12/2019 11:37 AM, Geert Uytterhoeven wrote:
> >> +       iowrite8(val, address);
> >
> > As this is on a Zorro bus, z_writeb()?
>
> I forgot to ask about this.
>
> What is the reasoning behind having a separate z_writeb() for Zorro?
> As far as I can see in arch/m68k/include/asm this maps 1:1 to a direct memory access, and it prohibits cross-arch code as in i2c-elektor.

write*() and friends are intended for PCI, and thus little endian, while
the Zorro bus is big endian. For byte accesses this doesn't matter,
obviously.

Note that this predates iowrite*(), which does have *be variants.
If you want to add compile-testing to your driver, using iowrite*() is fine.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-29 19:00   ` Wolfram Sang
@ 2019-08-29 19:17     ` Max Staudt
  0 siblings, 0 replies; 11+ messages in thread
From: Max Staudt @ 2019-08-29 19:17 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: linux-i2c, linux-hwmon, Wolfram Sang, Jean Delvare,
	Guenter Roeck, linux-m68k, linux-kernel, glaubitz

On 08/29/2019 09:00 PM, Wolfram Sang wrote:
> Thanks for the changelog; it should go below the '---' line, however.

Thanks if you fixed it up!


> Fixed a freshly introduced checkpatch warning for you.

Ditto.


> But most importantly, applied to for-next, thanks!

Thank you too for taking this, and Geert for the extra reviews.



Max

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-20  9:27 ` [PATCH] " Max Staudt
@ 2019-08-29 19:00   ` Wolfram Sang
  2019-08-29 19:17     ` Max Staudt
  0 siblings, 1 reply; 11+ messages in thread
From: Wolfram Sang @ 2019-08-29 19:00 UTC (permalink / raw)
  To: Max Staudt
  Cc: linux-i2c, linux-hwmon, Wolfram Sang, Jean Delvare,
	Guenter Roeck, linux-m68k, linux-kernel, glaubitz

[-- Attachment #1: Type: text/plain, Size: 1088 bytes --]

On Tue, Aug 20, 2019 at 11:27:39AM +0200, Max Staudt wrote:
> This is the i2c-icy driver for the ICY board for Amiga computers.
> It connects a PCF8584 I2C controller to the Zorro bus, providing I2C
> connectivity. The original documentation can be found on Aminet:
> 
> https://aminet.net/package/docs/hard/icy
> 
> IRQ support is currently not implemented, as i2c-algo-pcf is built for
> the ISA bus and a straight implementation of the same stack locks up a
> Zorro machine.
> 
> v5: usleep_range() instead of udelay()
>     Style
> 
> v3: Fixed %pa format string
>     Dropped adapter class.
>     Clarified licence.
>     Removed clock parameter.
> 
> v2: Matched function names to callbacks from i2c-algo-pcf
>     Used z_readb()/z_writeb()
>     Removed BROKEN_ON_SMP in Kconfig
>     Moved LTC2990 to a separate commit

Thanks for the changelog; it should go below the '---' line, however.

> 
> Signed-off-by: Max Staudt <max@enpas.org>

Fixed a freshly introduced checkpatch warning for you.

But most importantly, applied to for-next, thanks!


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga
  2019-08-20  9:23 [PATCH v5 1/3] " Max
@ 2019-08-20  9:27 ` Max Staudt
  2019-08-29 19:00   ` Wolfram Sang
  0 siblings, 1 reply; 11+ messages in thread
From: Max Staudt @ 2019-08-20  9:27 UTC (permalink / raw)
  To: linux-i2c, linux-hwmon, Wolfram Sang, Jean Delvare, Guenter Roeck
  Cc: linux-m68k, linux-kernel, glaubitz, Max Staudt

This is the i2c-icy driver for the ICY board for Amiga computers.
It connects a PCF8584 I2C controller to the Zorro bus, providing I2C
connectivity. The original documentation can be found on Aminet:

https://aminet.net/package/docs/hard/icy

IRQ support is currently not implemented, as i2c-algo-pcf is built for
the ISA bus and a straight implementation of the same stack locks up a
Zorro machine.

v5: usleep_range() instead of udelay()
    Style

v3: Fixed %pa format string
    Dropped adapter class.
    Clarified licence.
    Removed clock parameter.

v2: Matched function names to callbacks from i2c-algo-pcf
    Used z_readb()/z_writeb()
    Removed BROKEN_ON_SMP in Kconfig
    Moved LTC2990 to a separate commit

Signed-off-by: Max Staudt <max@enpas.org>
---
 MAINTAINERS                  |   6 ++
 drivers/i2c/busses/Kconfig   |  11 +++
 drivers/i2c/busses/Makefile  |   1 +
 drivers/i2c/busses/i2c-icy.c | 172 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 190 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-icy.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1be025959..70336c083 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7705,6 +7705,12 @@ S:	Maintained
 F:	drivers/mfd/lpc_ich.c
 F:	drivers/gpio/gpio-ich.c
 
+ICY I2C DRIVER
+M:	Max Staudt <max@enpas.org>
+L:	linux-i2c@vger.kernel.org
+S:	Maintained
+F:	drivers/i2c/busses/i2c-icy.c
+
 IDE SUBSYSTEM
 M:	"David S. Miller" <davem@davemloft.net>
 L:	linux-ide@vger.kernel.org
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index ee5dfb5ae..9e57e1101 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1300,6 +1300,17 @@ config I2C_ELEKTOR
 	  This support is also available as a module.  If so, the module
 	  will be called i2c-elektor.
 
+config I2C_ICY
+	tristate "ICY Zorro card"
+	depends on ZORRO
+	select I2C_ALGOPCF
+	help
+	  This supports the PCF8584 Zorro bus I2C adapter, known as ICY.
+	  Say Y if you own such an adapter.
+
+	  This support is also available as a module.  If so, the module
+	  will be called i2c-icy.
+
 config I2C_MLXCPLD
 	tristate "Mellanox I2C driver"
 	depends on X86_64
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index a3245231b..d0e1c3d4e 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -139,6 +139,7 @@ obj-$(CONFIG_I2C_BCM_KONA)	+= i2c-bcm-kona.o
 obj-$(CONFIG_I2C_BRCMSTB)	+= i2c-brcmstb.o
 obj-$(CONFIG_I2C_CROS_EC_TUNNEL)	+= i2c-cros-ec-tunnel.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
+obj-$(CONFIG_I2C_ICY)		+= i2c-icy.o
 obj-$(CONFIG_I2C_MLXCPLD)	+= i2c-mlxcpld.o
 obj-$(CONFIG_I2C_OPAL)		+= i2c-opal.o
 obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o
diff --git a/drivers/i2c/busses/i2c-icy.c b/drivers/i2c/busses/i2c-icy.c
new file mode 100644
index 000000000..7b7083da8
--- /dev/null
+++ b/drivers/i2c/busses/i2c-icy.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * I2C driver for stand-alone PCF8584 style adapters on Zorro cards
+ *
+ * Original ICY documentation can be found on Aminet:
+ * https://aminet.net/package/docs/hard/icy
+ *
+ * There has been a modern community re-print of this design in 2019:
+ * https://www.a1k.org/forum/index.php?threads/70106/
+ *
+ * The card is basically a Philips PCF8584 connected straight to the
+ * beginning of the AutoConfig'd address space (register S1 on base+2),
+ * with /INT on /INT2 on the Zorro bus.
+ *
+ * Copyright (c) 2019 Max Staudt <max@enpas.org>
+ *
+ * This started as a fork of i2c-elektor.c and has evolved since.
+ * Thanks go to its authors for providing a base to grow on.
+ *
+ *
+ * IRQ support is currently not implemented.
+ *
+ * As it turns out, i2c-algo-pcf is really written with i2c-elektor's
+ * edge-triggered ISA interrupts in mind, while the Amiga's Zorro bus has
+ * level-triggered interrupts. This means that once an interrupt occurs, we
+ * have to tell the PCF8584 to shut up immediately, or it will keep the
+ * interrupt line busy and cause an IRQ storm.
+
+ * However, because of the PCF8584's host-side protocol, there is no good
+ * way to just quieten it without side effects. Rather, we have to perform
+ * the next read/write operation straight away, which will reset the /INT
+ * pin. This entails re-designing the core of i2c-algo-pcf in the future.
+ * For now, we never request an IRQ from the PCF8584, and poll it instead.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-pcf.h>
+
+#include <asm/amigaints.h>
+#include <linux/zorro.h>
+
+#include "../algos/i2c-algo-pcf.h"
+
+struct icy_i2c {
+	struct i2c_adapter adapter;
+
+	void __iomem *reg_s0;
+	void __iomem *reg_s1;
+};
+
+/*
+ * Functions called by i2c-algo-pcf
+ */
+static void icy_pcf_setpcf(void *data, int ctl, int val)
+{
+	struct icy_i2c *i2c = (struct icy_i2c *)data;
+
+	u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
+
+	z_writeb(val, address);
+}
+
+static int icy_pcf_getpcf(void *data, int ctl)
+{
+	struct icy_i2c *i2c = (struct icy_i2c *)data;
+
+	u8 __iomem *address = ctl ? i2c->reg_s1 : i2c->reg_s0;
+	return z_readb(address);
+}
+
+static int icy_pcf_getown(void *data)
+{
+	return 0x55;
+}
+
+static int icy_pcf_getclock(void *data)
+{
+	return 0x1c;
+}
+
+static void icy_pcf_waitforpin(void *data)
+{
+	usleep_range(50, 150);
+}
+
+/*
+ * Main i2c-icy part
+ */
+static int icy_probe(struct zorro_dev *z,
+		     const struct zorro_device_id *ent)
+{
+	struct icy_i2c *i2c;
+	struct i2c_algo_pcf_data *algo_data;
+
+	i2c = devm_kzalloc(&z->dev, sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
+
+	algo_data = devm_kzalloc(&z->dev, sizeof(*algo_data), GFP_KERNEL);
+	if (!algo_data)
+		return -ENOMEM;
+
+	dev_set_drvdata(&z->dev, i2c);
+	i2c->adapter.dev.parent = &z->dev;
+	i2c->adapter.owner = THIS_MODULE;
+	/* i2c->adapter.algo assigned by i2c_pcf_add_bus() */
+	i2c->adapter.algo_data = algo_data;
+	strlcpy(i2c->adapter.name, "ICY I2C Zorro adapter",
+		sizeof(i2c->adapter.name));
+
+	if (!devm_request_mem_region(&z->dev,
+				     z->resource.start,
+				     4, i2c->adapter.name))
+		return -ENXIO;
+
+	/* Driver private data */
+	i2c->reg_s0 = ZTWO_VADDR(z->resource.start);
+	i2c->reg_s1 = ZTWO_VADDR(z->resource.start + 2);
+
+	algo_data->data = i2c;
+	algo_data->setpcf     = icy_pcf_setpcf;
+	algo_data->getpcf     = icy_pcf_getpcf;
+	algo_data->getown     = icy_pcf_getown;
+	algo_data->getclock   = icy_pcf_getclock;
+	algo_data->waitforpin = icy_pcf_waitforpin;
+
+	if (i2c_pcf_add_bus(&i2c->adapter)) {
+		dev_err(&z->dev, "i2c_pcf_add_bus() failed\n");
+		return -ENXIO;
+	}
+
+	dev_info(&z->dev, "ICY I2C controller at %pa, IRQ not implemented\n",
+		 &z->resource.start);
+
+	return 0;
+}
+
+static void icy_remove(struct zorro_dev *z)
+{
+	struct icy_i2c *i2c = dev_get_drvdata(&z->dev);
+
+	i2c_del_adapter(&i2c->adapter);
+}
+
+static const struct zorro_device_id icy_zorro_tbl[] = {
+	{ ZORRO_ID(VMC, 15, 0), },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(zorro, icy_zorro_tbl);
+
+static struct zorro_driver icy_driver = {
+	.name           = "i2c-icy",
+	.id_table       = icy_zorro_tbl,
+	.probe          = icy_probe,
+	.remove         = icy_remove,
+};
+
+module_driver(icy_driver,
+	      zorro_register_driver,
+	      zorro_unregister_driver);
+
+MODULE_AUTHOR("Max Staudt <max@enpas.org>");
+MODULE_DESCRIPTION("I2C bus via PCF8584 on ICY Zorro card");
+MODULE_LICENSE("GPL v2");
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-08-29 19:17 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-11  4:32 [PATCH] i2c/busses: Add i2c-icy for I2C on m68k/Amiga Max Staudt
2019-08-11  4:40 ` Max Staudt
2019-08-12  9:37 ` Geert Uytterhoeven
2019-08-12 10:43   ` Max Staudt
2019-08-12 11:07     ` Geert Uytterhoeven
2019-08-12 11:48       ` Max Staudt
2019-08-12 22:21   ` Max Staudt
2019-08-13  6:53     ` Geert Uytterhoeven
2019-08-20  9:23 [PATCH v5 1/3] " Max
2019-08-20  9:27 ` [PATCH] " Max Staudt
2019-08-29 19:00   ` Wolfram Sang
2019-08-29 19:17     ` Max Staudt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).