Skip to contentSkip to conversation

ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

PATCH Superseded wu guoxing 3 participants 7 messages Nov 10, 2011 GPIO

v4 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

wu guoxing

author
#0 lore raw

PATCH v4 1/1 ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

we only use the gpio function of mc9s08dz60 mcu chip, so just add the gpio driver, as this mcu will never be used in other board.

---
changes since v3:
1. set i2c client data before gpiochip_add
2. return error value in mc9s08dz60_direction_output
v3 Changes since v1:
1. add can_sleep = 1
2. removed some useless return checks and local variable
3. removed the static variable for i2c client.
4. make init&exit function static

 drivers/gpio/Kconfig           |    6 ++
 drivers/gpio/Makefile          |    1 +
 drivers/gpio/gpio-mc9s08dz60.c |  177 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpio/gpio-mc9s08dz60.c
drivers/gpio/Kconfig +6 -0
index d539efd..7f6beee 100644
@@ -487,4 +487,10 @@ config GPIO_TPS65910
 	help
 	  Select this option to enable GPIO driver for the TPS65910
 	  chip family.
+
+config GPIO_MC9S08DZ60
+	bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions"
+	depends on I2C && MACH_MX35_3DS
+	help
+	  Select this to enable the MC9S08DZ60 GPIO driver
 endif
drivers/gpio/Makefile +1 -0
index 9588948..85b8799 100644
@@ -60,3 +60,4 @@ obj-$(CONFIG_GPIO_WM831X)	+= gpio-wm831x.o
 obj-$(CONFIG_GPIO_WM8350)	+= gpio-wm8350.o
 obj-$(CONFIG_GPIO_WM8994)	+= gpio-wm8994.o
 obj-$(CONFIG_GPIO_XILINX)	+= gpio-xilinx.o
+obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
drivers/gpio/gpio-mc9s08dz60.c new file +177 -0

177 lines not on this page · raw message

Signature · 1 line
1.7.1
#1 lore raw

PATCH v4 1/1 ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

Quoted 7 lines · wu guoxing

we only use the gpio function of mc9s08dz60 mcu chip, so just add the gpio driver, as this mcu will never be used in other board.

---
changes since v3:
1. set i2c client data before gpiochip_add

exchange the two in the remove function, too.
First shut down the gpio chip, then unset set i2c client data.

Marc

Quoted 220 lines

2. return error value in mc9s08dz60_direction_output
v3 Changes since v1:
1. add can_sleep = 1
2. removed some useless return checks and local variable
3. removed the static variable for i2c client.
4. make init&exit function static

 drivers/gpio/Kconfig           |    6 ++
 drivers/gpio/Makefile          |    1 +
 drivers/gpio/gpio-mc9s08dz60.c |  177 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpio/gpio-mc9s08dz60.c
drivers/gpio/Kconfig +6 -0
index d539efd..7f6beee 100644
@@ -487,4 +487,10 @@ config GPIO_TPS65910
 	help
 	  Select this option to enable GPIO driver for the TPS65910
 	  chip family.
+
+config GPIO_MC9S08DZ60
+	bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions"
+	depends on I2C && MACH_MX35_3DS
+	help
+	  Select this to enable the MC9S08DZ60 GPIO driver
 endif
drivers/gpio/Makefile +1 -0
index 9588948..85b8799 100644
@@ -60,3 +60,4 @@ obj-$(CONFIG_GPIO_WM831X)	+= gpio-wm831x.o
 obj-$(CONFIG_GPIO_WM8350)	+= gpio-wm8350.o
 obj-$(CONFIG_GPIO_WM8994)	+= gpio-wm8994.o
 obj-$(CONFIG_GPIO_XILINX)	+= gpio-xilinx.o
+obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
drivers/gpio/gpio-mc9s08dz60.c new file +177 -0
new file mode 100644
index 0000000..0122ef8
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Wu Guoxing <[email protected]>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+
+#define GPIO_GROUP_NUM 2
+#define GPIO_NUM_PER_GROUP 8
+#define GPIO_NUM (GPIO_GROUP_NUM*GPIO_NUM_PER_GROUP)
+
+struct mc9s08dz60 {
+	struct i2c_client *client;
+	struct gpio_chip chip;
+};
+
+static struct mc9s08dz60 *to_mc9s08dz60(struct gpio_chip *gc)
+{
+	return container_of(gc, struct mc9s08dz60, chip);
+}
+
+
+static void gpio_to_reg_and_bit(int offset, u8 *reg, u8 *bit)
+{
+	*reg = 0x20 + offset / GPIO_NUM_PER_GROUP;
+	*bit = offset % GPIO_NUM_PER_GROUP;
+}
+
+static int mc9s08dz60_get_value(struct gpio_chip *gc, unsigned offset)
+{
+	int ret = 0;
+	u8 reg, bit;
+	s32 value;
+	struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
+
+	gpio_to_reg_and_bit(offset, &reg, &bit);
+	value = i2c_smbus_read_byte_data(mc9s->client, reg);
+	if (value >= 0)
+		ret = (value >> bit) & 0x1;
+
+	return ret;
+}
+
+static int _mc9s08dz60_set(struct mc9s08dz60 *mc9s, unsigned offset, int val)
+{
+	u8 reg, bit;
+	s32 value;
+
+	gpio_to_reg_and_bit(offset, &reg, &bit);
+	value = i2c_smbus_read_byte_data(mc9s->client, reg);
+	if (value >= 0) {
+		if (val)
+			value |= 1 << bit;
+		else
+			value &= ~(1 << bit);
+
+		return i2c_smbus_write_byte_data(mc9s->client, reg, value);
+	} else
+		return value;
+
+}
+
+
+static void mc9s08dz60_set_value(struct gpio_chip *gc, unsigned offset, int val)
+{
+	struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
+
+	_mc9s08dz60_set(mc9s, offset, val);
+}
+
+static int mc9s08dz60_direction_output(struct gpio_chip *gc,
+				       unsigned offset, int val)
+{
+	struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
+
+	return _mc9s08dz60_set(mc9s, offset, val);
+}
+
+static int mc9s08dz60_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	int ret = 0;
+	struct mc9s08dz60 *mc9s;
+
+	mc9s = kzalloc(sizeof(*mc9s), GFP_KERNEL);
+	if (!mc9s)
+		return -ENOMEM;
+
+	mc9s->chip.label = client->name;
+	mc9s->chip.base = -1;
+	mc9s->chip.dev = &client->dev;
+	mc9s->chip.owner = THIS_MODULE;
+	mc9s->chip.ngpio = GPIO_NUM;
+	mc9s->chip.can_sleep = 1;
+	mc9s->chip.get = mc9s08dz60_get_value;
+	mc9s->chip.set = mc9s08dz60_set_value;
+	mc9s->chip.direction_output = mc9s08dz60_direction_output;
+	mc9s->client = client;
+	i2c_set_clientdata(client, mc9s);
+
+	ret = gpiochip_add(&mc9s->chip);
+	if (ret)
+		goto error;
+
+	return 0;
+
+error:
+	i2c_set_clientdata(client, NULL);
+	kfree(mc9s);
+	return ret;
+}
+
+static int mc9s08dz60_remove(struct i2c_client *client)
+{
+	struct mc9s08dz60 *mc9s;
+	int ret;
+
+	mc9s = i2c_get_clientdata(client);
+
+	i2c_set_clientdata(client, NULL);
+
+	ret = gpiochip_remove(&mc9s->chip);
+	if (!ret)
+		kfree(mc9s);
+
+	return 0;
+
+}
+
+static const struct i2c_device_id mc9s08dz60_id[] = {
+	{"mc9s08dz60", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, mc9s08dz60_id);
+
+static struct i2c_driver mc9s08dz60_i2c_driver = {
+	.driver = {.owner = THIS_MODULE,
+		   .name = "mc9s08dz60",
+		   },
+	.probe = mc9s08dz60_probe,
+	.remove = mc9s08dz60_remove,
+	.id_table = mc9s08dz60_id,
+};
+
+static int __init mc9s08dz60_init(void)
+{
+	return i2c_add_driver(&mc9s08dz60_i2c_driver);
+}
+
+static void __exit mc9s08dz60_exit(void)
+{
+	i2c_del_driver(&mc9s08dz60_i2c_driver);
+}
+
+module_init(mc9s08dz60_init);
+module_exit(mc9s08dz60_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc."
+		"Wu Guoxing <[email protected]>");
+MODULE_DESCRIPTION("mc9s08dz60 gpio function on mx35 3ds board");
+MODULE_LICENSE("GPL v2");
Signature · 12 lines
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20111110/a384a383/attachment.sig>
#2 lore raw

PATCH v4 1/1 ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

Quoted 11 lines · Marc Kleine-Budde
Quoted 7 lines · wu guoxing

we only use the gpio function of mc9s08dz60 mcu chip, so just add the gpio driver, as this mcu will never be used in other board.

---
changes since v3:
1. set i2c client data before gpiochip_add

exchange the two in the remove function, too.
First shut down the gpio chip, then unset set i2c client data.

and don't set clientdata to NULL.

Signature · 9 lines
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20111110/6c116f76/attachment.sig>
#3 lore raw

PATCH v4 1/1 ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

Hi Wolfram:

I changed the code to unset i2c client data just when gipochip_remove successes,
Otherwise, there will be problems next time the remove function is called.

Please review the v5 patch.

Thanks!

Best Regards
Wu Guoxing

-----Original Message-----
From: Wolfram Sang [mailto:w.sang at pengutronix.de]
Sent: Thursday, November 10, 2011 6:21 PM
To: Marc Kleine-Budde
Cc: Wu Guoxing-B39297; grant.likely at secretlab.ca; s.hauer at pengutronix.de; shawn.guo at linaro.org; linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH v4] ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

Quoted 11 lines · Marc Kleine-Budde
Quoted 7 lines · wu guoxing

we only use the gpio function of mc9s08dz60 mcu chip, so just add the gpio driver, as this mcu will never be used in other board.

---
changes since v3:
1. set i2c client data before gpiochip_add

exchange the two in the remove function, too.
First shut down the gpio chip, then unset set i2c client data.

and don't set clientdata to NULL.

Signature · 2 lines
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
#4 lore raw

PATCH v4 1/1 ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

Quoted 2 lines

I changed the code to unset i2c client data just when gipochip_remove successes,
Otherwise, there will be problems next time the remove function is called.

The i2c-core will do it on probe-failure and on remove. Check e4a7b9b0.

Thanks,

Wolfram

Signature · 9 lines
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20111110/615d0fc8/attachment.sig>
#5 lore raw

PATCH v4 1/1 ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

Hi Wolfram & Marc:
I sent out the v6 patch to remove this from both probe and remove functions
Also, in remove function, changed to return the error code.

Please review the V6 patch.

Thanks for the comments!

Best Regards
Wu Guoxing

-----Original Message-----
From: Wolfram Sang [mailto:w.sang at pengutronix.de]
Sent: Thursday, November 10, 2011 7:09 PM
To: Wu Guoxing-B39297
Cc: Marc Kleine-Budde; grant.likely at secretlab.ca; s.hauer at pengutronix.de; shawn.guo at linaro.org; linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH v4] ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

Quoted 2 lines

I changed the code to unset i2c client data just when
gipochip_remove successes, Otherwise, there will be problems next time the remove function is called.

The i2c-core will do it on probe-failure and on remove. Check e4a7b9b0.

Thanks,

Wolfram

Signature · 2 lines
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
#6 lore raw

PATCH v4 1/1 ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

In reply to Marc Kleine-Budde

Hi Marc:

I changed the code to unset i2c client data just when gipochip_remove successes,
Otherwise, there will be problems next time the remove function is called.

Please review the v5 patch.

Thanks!

Best regards
Wu Guoxing

-----Original Message-----
From: Marc Kleine-Budde [mailto:mkl at pengutronix.de]
Sent: Thursday, November 10, 2011 6:14 PM
To: Wu Guoxing-B39297
Cc: linux-arm-kernel at lists.infradead.org; grant.likely at secretlab.ca; s.hauer at pengutronix.de; shawn.guo at linaro.org
Subject: Re: [PATCH v4] ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function

Quoted 7 lines · wu guoxing

we only use the gpio function of mc9s08dz60 mcu chip, so just add the gpio driver, as this mcu will never be used in other board.

---
changes since v3:
1. set i2c client data before gpiochip_add

exchange the two in the remove function, too.
First shut down the gpio chip, then unset set i2c client data.

Marc

Quoted 215 lines

2. return error value in mc9s08dz60_direction_output
v3 Changes since v1:
1. add can_sleep = 1
2. removed some useless return checks and local variable
3. removed the static variable for i2c client.
4. make init&exit function static

 drivers/gpio/Kconfig           |    6 ++
 drivers/gpio/Makefile          |    1 +
 drivers/gpio/gpio-mc9s08dz60.c |  177 
++++++++++++++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+), 0 deletions(-)  create mode 

100644 drivers/gpio/gpio-mc9s08dz60.c

drivers/gpio/Kconfig index renamed from drivers/gpio/Kconfig +0 -0

d539efd..7f6beee 100644

drivers/gpio/Kconfig +6 -0
@@ -487,4 +487,10 @@ config GPIO_TPS65910
 	help
 	  Select this option to enable GPIO driver for the TPS65910
 	  chip family.
+
+config GPIO_MC9S08DZ60
+	bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions"
+	depends on I2C && MACH_MX35_3DS
+	help
+	  Select this to enable the MC9S08DZ60 GPIO driver
 endif
drivers/gpio/Makefile index renamed from drivers/gpio/Makefile +0 -0

9588948..85b8799 100644

drivers/gpio/Makefile +1 -0
@@ -60,3 +60,4 @@ obj-$(CONFIG_GPIO_WM831X)	+= gpio-wm831x.o
 obj-$(CONFIG_GPIO_WM8350)	+= gpio-wm8350.o
 obj-$(CONFIG_GPIO_WM8994)	+= gpio-wm8994.o
 obj-$(CONFIG_GPIO_XILINX)	+= gpio-xilinx.o
+obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o
(quoted diff) +0 -0

b/drivers/gpio/gpio-mc9s08dz60.c new file mode 100644 index 0000000..0122ef8

drivers/gpio/gpio-mc9s08dz60.c new file +171 -0
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Wu Guoxing <[email protected]>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+
+#define GPIO_GROUP_NUM 2
+#define GPIO_NUM_PER_GROUP 8
+#define GPIO_NUM (GPIO_GROUP_NUM*GPIO_NUM_PER_GROUP)
+
+struct mc9s08dz60 {
+	struct i2c_client *client;
+	struct gpio_chip chip;
+};
+
+static struct mc9s08dz60 *to_mc9s08dz60(struct gpio_chip *gc) {
+	return container_of(gc, struct mc9s08dz60, chip); }
+
+
+static void gpio_to_reg_and_bit(int offset, u8 *reg, u8 *bit) {
+	*reg = 0x20 + offset / GPIO_NUM_PER_GROUP;
+	*bit = offset % GPIO_NUM_PER_GROUP;
+}
+
+static int mc9s08dz60_get_value(struct gpio_chip *gc, unsigned 
+offset) {
+	int ret = 0;
+	u8 reg, bit;
+	s32 value;
+	struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
+
+	gpio_to_reg_and_bit(offset, &reg, &bit);
+	value = i2c_smbus_read_byte_data(mc9s->client, reg);
+	if (value >= 0)
+		ret = (value >> bit) & 0x1;
+
+	return ret;
+}
+
+static int _mc9s08dz60_set(struct mc9s08dz60 *mc9s, unsigned offset, 
+int val) {
+	u8 reg, bit;
+	s32 value;
+
+	gpio_to_reg_and_bit(offset, &reg, &bit);
+	value = i2c_smbus_read_byte_data(mc9s->client, reg);
+	if (value >= 0) {
+		if (val)
+			value |= 1 << bit;
+		else
+			value &= ~(1 << bit);
+
+		return i2c_smbus_write_byte_data(mc9s->client, reg, value);
+	} else
+		return value;
+
+}
+
+
+static void mc9s08dz60_set_value(struct gpio_chip *gc, unsigned 
+offset, int val) {
+	struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
+
+	_mc9s08dz60_set(mc9s, offset, val);
+}
+
+static int mc9s08dz60_direction_output(struct gpio_chip *gc,
+				       unsigned offset, int val)
+{
+	struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
+
+	return _mc9s08dz60_set(mc9s, offset, val); }
+
+static int mc9s08dz60_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id) {
+	int ret = 0;
+	struct mc9s08dz60 *mc9s;
+
+	mc9s = kzalloc(sizeof(*mc9s), GFP_KERNEL);
+	if (!mc9s)
+		return -ENOMEM;
+
+	mc9s->chip.label = client->name;
+	mc9s->chip.base = -1;
+	mc9s->chip.dev = &client->dev;
+	mc9s->chip.owner = THIS_MODULE;
+	mc9s->chip.ngpio = GPIO_NUM;
+	mc9s->chip.can_sleep = 1;
+	mc9s->chip.get = mc9s08dz60_get_value;
+	mc9s->chip.set = mc9s08dz60_set_value;
+	mc9s->chip.direction_output = mc9s08dz60_direction_output;
+	mc9s->client = client;
+	i2c_set_clientdata(client, mc9s);
+
+	ret = gpiochip_add(&mc9s->chip);
+	if (ret)
+		goto error;
+
+	return 0;
+
+error:
+	i2c_set_clientdata(client, NULL);
+	kfree(mc9s);
+	return ret;
+}
+
+static int mc9s08dz60_remove(struct i2c_client *client) {
+	struct mc9s08dz60 *mc9s;
+	int ret;
+
+	mc9s = i2c_get_clientdata(client);
+
+	i2c_set_clientdata(client, NULL);
+
+	ret = gpiochip_remove(&mc9s->chip);
+	if (!ret)
+		kfree(mc9s);
+
+	return 0;
+
+}
+
+static const struct i2c_device_id mc9s08dz60_id[] = {
+	{"mc9s08dz60", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, mc9s08dz60_id);
+
+static struct i2c_driver mc9s08dz60_i2c_driver = {
+	.driver = {.owner = THIS_MODULE,
+		   .name = "mc9s08dz60",
+		   },
+	.probe = mc9s08dz60_probe,
+	.remove = mc9s08dz60_remove,
+	.id_table = mc9s08dz60_id,
+};
+
+static int __init mc9s08dz60_init(void) {
+	return i2c_add_driver(&mc9s08dz60_i2c_driver);
+}
+
+static void __exit mc9s08dz60_exit(void) {
+	i2c_del_driver(&mc9s08dz60_i2c_driver);
+}
+
+module_init(mc9s08dz60_init);
+module_exit(mc9s08dz60_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc."
+		"Wu Guoxing <[email protected]>"); 
+MODULE_DESCRIPTION("mc9s08dz60 gpio function on mx35 3ds board"); 
+MODULE_LICENSE("GPL v2");
Signature · 4 lines
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |