i2c: lpc32xx: Factor out i2c_adapter parameter
Subsystems (2)
PATCH 3/7 i2c: lpc32xx: Factor out i2c_adapter parameter
From: Liam Beguin <[email protected]>
This is part of the prep work for the migration to the driver model. It will enable the driver to support DM and non-DM configurations using the same functions.
--- drivers/i2c/lpc32xx_i2c.c | 107 +++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 54 deletions(-)
drivers/i2c/lpc32xx_i2c.c +53 -54
@@ -29,7 +29,7 @@#endif /* i2c register set */ -struct lpc32xx_i2c_registers { +struct lpc32xx_i2c_base {union {u32 rx;u32 tx;
@@ -61,15 +61,15 @@ struct lpc32xx_i2c_registers {#define LPC32XX_I2C_STAT_NAI 0x00000004#define LPC32XX_I2C_STAT_TDI 0x00000001 -static struct lpc32xx_i2c_registers *lpc32xx_i2c[] = { - (struct lpc32xx_i2c_registers *)I2C1_BASE , - (struct lpc32xx_i2c_registers *)I2C2_BASE , - (struct lpc32xx_i2c_registers *)(USB_BASE +0x300 ) +static struct lpc32xx_i2c_base *lpc32xx_i2c[] = { + (struct lpc32xx_i2c_base *)I2C1_BASE , + (struct lpc32xx_i2c_base *)I2C2_BASE , + (struct lpc32xx_i2c_base *)(USB_BASE +0x300 ) };/* Set I2C bus speed */ -static unsigned int __i2c_set_bus_speed (struct i2c_adapter *adap, -unsigned int speed) +static unsigned int __i2c_set_bus_speed (struct lpc32xx_i2c_base *base, +unsigned int speed,unsigned int chip) {int half_period;
@@ -77,7 +77,7 @@ static unsigned int __i2c_set_bus_speed(struct i2c_adapter *adap,return -EINVAL ;/* OTG I2C clock source and CLK registers are different */ -if (adap->hwadapnr ==2 ) { +if (chip ==2 ) { half_period = (get_periph_clk_rate () / speed) /2 ;if (half_period >0xFF )return -EINVAL ;
@@ -87,38 +87,35 @@ static unsigned int __i2c_set_bus_speed(struct i2c_adapter *adap,return -EINVAL ; } -writel (half_period, &lpc32xx_i2c[adap->hwadapnr]->clk_hi); -writel (half_period, &lpc32xx_i2c[adap->hwadapnr]->clk_lo); +writel (half_period, &base->clk_hi); +writel (half_period, &base->clk_lo);return 0 ; }/* I2C init called by cmd_i2c when doing 'i2c reset'. */ -static void __i2c_init (struct i2c_adapter *adap, -int requested_speed,int slaveadd) +static void __i2c_init (struct lpc32xx_i2c_base *base, +int requested_speed,int slaveadd,unsigned int chip) { -struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr]; -/* soft reset (auto-clears) */ -writel (LPC32XX_I2C_SOFT_RESET , &i2c->ctrl); +writel (LPC32XX_I2C_SOFT_RESET , &base->ctrl);/* set HI and LO periods for half of the default speed */ -__i2c_set_bus_speed (adap, requested_speed); +__i2c_set_bus_speed (base, requested_speed, chip); }/* I2C probe called by cmd_i2c when doing 'i2c probe'. */ -static int __i2c_probe_chip (struct i2c_adapter *adap,u8 dev) +static int __i2c_probe_chip (struct lpc32xx_i2c_base *base,u8 dev) { -struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];int stat;/* Soft-reset the controller */ -writel (LPC32XX_I2C_SOFT_RESET , &i2c->ctrl); -while (readl (&i2c->ctrl) &LPC32XX_I2C_SOFT_RESET ) +writel (LPC32XX_I2C_SOFT_RESET , &base->ctrl); +while (readl (&base->ctrl) &LPC32XX_I2C_SOFT_RESET ) ;/* Addre slave for write with start before and stop after */ writel ((dev<<1 ) |LPC32XX_I2C_TX_START |LPC32XX_I2C_TX_STOP , - &i2c->tx); + &base->tx);/* wait for end of transation */ -while (!((stat =readl (&i2c->stat)) &LPC32XX_I2C_STAT_TDI )) +while (!((stat =readl (&base->stat)) &LPC32XX_I2C_STAT_TDI )) ;/* was there no acknowledge? */ return (stat &LPC32XX_I2C_STAT_NAI ) ?-1 :0 ;
@@ -128,20 +125,19 @@ static int __i2c_probe_chip(struct i2c_adapter *adap, u8 dev)* I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c * Begin write, send address byte(s), begin read, receive data bytes, end. */ -static int __i2c_read (struct i2c_adapter *adap,u8 dev,uint addr, -int alen,u8 *data,int length) +static int __i2c_read (struct lpc32xx_i2c_base *base,u8 dev,uint addr, +int alen,u8 *data,int length) { -struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];int stat, wlen;/* Soft-reset the controller */ -writel (LPC32XX_I2C_SOFT_RESET , &i2c->ctrl); -while (readl (&i2c->ctrl) &LPC32XX_I2C_SOFT_RESET ) +writel (LPC32XX_I2C_SOFT_RESET , &base->ctrl); +while (readl (&base->ctrl) &LPC32XX_I2C_SOFT_RESET ) ;/* do we need to write an address at all? */ if (alen) {/* Address slave in write mode */ -writel ((dev<<1 ) |LPC32XX_I2C_TX_START , &i2c->tx); +writel ((dev<<1 ) |LPC32XX_I2C_TX_START , &base->tx);/* write address bytes */ while (alen--) {/* compute address byte + stop for the last one */
@@ -149,44 +145,44 @@ static int __i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,if (!alen) a |=LPC32XX_I2C_TX_STOP ;/* Send address byte */ -writel (a, &i2c->tx); +writel (a, &base->tx); }/* wait for end of transation */ -while (!((stat =readl (&i2c->stat)) &LPC32XX_I2C_STAT_TDI )) +while (!((stat =readl (&base->stat)) &LPC32XX_I2C_STAT_TDI )) ;/* clear end-of-transaction flag */ -writel (1 , &i2c->stat); +writel (1 , &base->stat); }/* do we have to read data at all? */ if (length) {/* Address slave in read mode */ -writel (1 | (dev<<1 ) |LPC32XX_I2C_TX_START , &i2c->tx); +writel (1 | (dev<<1 ) |LPC32XX_I2C_TX_START , &base->tx); wlen = length;/* get data */ while (length | wlen) {/* read status for TFF and RFE */ - stat =readl (&i2c->stat); + stat =readl (&base->stat);/* must we, can we write a trigger byte? */ if ((wlen >0 ) & (!(stat &LPC32XX_I2C_STAT_TFF ))) { wlen--;/* write trigger byte + stop if last */ writel (wlen ?0 : -LPC32XX_I2C_TX_STOP , &i2c->tx); +LPC32XX_I2C_TX_STOP , &base->tx); }/* must we, can we read a data byte? */ if ((length >0 ) & (!(stat &LPC32XX_I2C_STAT_RFE ))) { length--;/* read byte */ - *(data++) =readl (&i2c->rx); + *(data++) =readl (&base->rx); } }/* wait for end of transation */ -while (!((stat =readl (&i2c->stat)) &LPC32XX_I2C_STAT_TDI )) +while (!((stat =readl (&base->stat)) &LPC32XX_I2C_STAT_TDI )) ;/* clear end-of-transaction flag */ -writel (1 , &i2c->stat); +writel (1 , &base->stat); }/* success */ return 0 ;
@@ -196,38 +192,37 @@ static int __i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,* I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c * Begin write, send address byte(s), send data bytes, end. */ -static int __i2c_write (struct i2c_adapter *adap,u8 dev,uint addr, -int alen,u8 *data,int length) +static int __i2c_write (struct lpc32xx_i2c_base *base,u8 dev,uint addr, +int alen,u8 *data,int length) { -struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];int stat;/* Soft-reset the controller */ -writel (LPC32XX_I2C_SOFT_RESET , &i2c->ctrl); -while (readl (&i2c->ctrl) &LPC32XX_I2C_SOFT_RESET ) +writel (LPC32XX_I2C_SOFT_RESET , &base->ctrl); +while (readl (&base->ctrl) &LPC32XX_I2C_SOFT_RESET ) ;/* do we need to write anything at all? */ if (alen | length)/* Address slave in write mode */ -writel ((dev<<1 ) |LPC32XX_I2C_TX_START , &i2c->tx); +writel ((dev<<1 ) |LPC32XX_I2C_TX_START , &base->tx);else return 0 ;/* write address bytes */ while (alen) {/* wait for transmit fifo not full */ - stat =readl (&i2c->stat); + stat =readl (&base->stat);if (!(stat &LPC32XX_I2C_STAT_TFF )) { alen--;int a = (addr >> (8 * alen)) &0xff ;if (!(alen | length)) a |=LPC32XX_I2C_TX_STOP ;/* Send address byte */ -writel (a, &i2c->tx); +writel (a, &base->tx); } }while (length) {/* wait for transmit fifo not full */ - stat =readl (&i2c->stat); + stat =readl (&base->stat);if (!(stat &LPC32XX_I2C_STAT_TFF )) {/* compute data byte, add stop if length==0 */ length--;
@@ -235,44 +230,48 @@ static int __i2c_write(struct i2c_adapter *adap, u8 dev, uint addr,if (!length) d |=LPC32XX_I2C_TX_STOP ;/* Send data byte */ -writel (d, &i2c->tx); +writel (d, &base->tx); } }/* wait for end of transation */ -while (!((stat =readl (&i2c->stat)) &LPC32XX_I2C_STAT_TDI )) +while (!((stat =readl (&base->stat)) &LPC32XX_I2C_STAT_TDI )) ;/* clear end-of-transaction flag */ -writel (1 , &i2c->stat); +writel (1 , &base->stat);return 0 ; }static void lpc32xx_i2c_init (struct i2c_adapter *adap,int requested_speed,int slaveadd) { -__i2c_init (adap, requested_speed, slaveadd); +__i2c_init (lpc32xx_i2c[adap->hwadapnr], requested_speed, slaveadd, + adap->hwadapnr); }static int lpc32xx_i2c_probe_chip (struct i2c_adapter *adap,u8 dev) { -return __i2c_probe_chip (adap, dev); +return __i2c_probe_chip (lpc32xx_i2c[adap->hwadapnr], dev); }static int lpc32xx_i2c_read (struct i2c_adapter *adap,u8 dev,uint addr,int alen,u8 *data,int length) { -return __i2c_read (adap, dev, addr, alen, data, length); +return __i2c_read (lpc32xx_i2c[adap->hwadapnr], dev, addr, + alen, data, length); }static int lpc32xx_i2c_write (struct i2c_adapter *adap,u8 dev,uint addr,int alen,u8 *data,int length) { -return __i2c_write (adap, dev, addr, alen, data, length); +return __i2c_write (lpc32xx_i2c[adap->hwadapnr], dev, addr, + alen, data, length); }static unsigned int lpc32xx_i2c_set_bus_speed (struct i2c_adapter *adap,unsigned int speed) { -return __i2c_set_bus_speed (adap, speed); +return __i2c_set_bus_speed (lpc32xx_i2c[adap->hwadapnr], speed, + adap->hwadapnr); } U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_0, lpc32xx_i2c_init, lpc32xx_i2c_probe_chip,
Signature · 1 line
2.11.0
PATCH 3/7 i2c: lpc32xx: Factor out i2c_adapter parameter
Hello Sylvain,
Am 14.03.2017 um 16:24 schrieb Sylvain Lemieux:
Quoted 11 lines
From: Liam Beguin <[email protected]>
This is part of the prep work for the migration to the driver model. It will enable the driver to support DM and non-DM configurations using the same functions.
Signed-off-by Liam Beguin <[email protected]>Signed-off-by Sylvain Lemieux <[email protected]>--- drivers/i2c/lpc32xx_i2c.c | 107 +++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 54 deletions(-)
I am fine with this patch, but checkpatch says:
CHECK: Alignment should match open parenthesis
#270: FILE: drivers/i2c/lpc32xx_i2c.c:248:
+ __i2c_init(lpc32xx_i2c[adap->hwadapnr], requested_speed, slaveadd,
+ adap->hwadapnr);
Could you fix this please?
bye,
Heiko
Quoted 280 lines
drivers/i2c/lpc32xx_i2c.c +53
-54@@ -29,7 +29,7 @@#endif /* i2c register set */ -struct lpc32xx_i2c_registers { +struct lpc32xx_i2c_base {union {u32 rx;u32 tx;@@ -61,15 +61,15 @@ struct lpc32xx_i2c_registers {#define LPC32XX_I2C_STAT_NAI 0x00000004#define LPC32XX_I2C_STAT_TDI 0x00000001 -static struct lpc32xx_i2c_registers *lpc32xx_i2c[] = { - (struct lpc32xx_i2c_registers *)I2C1_BASE , - (struct lpc32xx_i2c_registers *)I2C2_BASE , - (struct lpc32xx_i2c_registers *)(USB_BASE +0x300 ) +static struct lpc32xx_i2c_base *lpc32xx_i2c[] = { + (struct lpc32xx_i2c_base *)I2C1_BASE , + (struct lpc32xx_i2c_base *)I2C2_BASE , + (struct lpc32xx_i2c_base *)(USB_BASE +0x300 ) };/* Set I2C bus speed */ -static unsigned int __i2c_set_bus_speed (struct i2c_adapter *adap, -unsigned int speed) +static unsigned int __i2c_set_bus_speed (struct lpc32xx_i2c_base *base, +unsigned int speed,unsigned int chip) {int half_period;@@ -77,7 +77,7 @@ static unsigned int __i2c_set_bus_speed(struct i2c_adapter *adap,return -EINVAL ;/* OTG I2C clock source and CLK registers are different */ -if (adap->hwadapnr ==2 ) { +if (chip ==2 ) { half_period = (get_periph_clk_rate () / speed) /2 ;if (half_period >0xFF )return -EINVAL ;@@ -87,38 +87,35 @@ static unsigned int __i2c_set_bus_speed(struct i2c_adapter *adap,return -EINVAL ; } -writel (half_period, &lpc32xx_i2c[adap->hwadapnr]->clk_hi); -writel (half_period, &lpc32xx_i2c[adap->hwadapnr]->clk_lo); +writel (half_period, &base->clk_hi); +writel (half_period, &base->clk_lo);return 0 ; }/* I2C init called by cmd_i2c when doing 'i2c reset'. */ -static void __i2c_init (struct i2c_adapter *adap, -int requested_speed,int slaveadd) +static void __i2c_init (struct lpc32xx_i2c_base *base, +int requested_speed,int slaveadd,unsigned int chip) { -struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr]; -/* soft reset (auto-clears) */ -writel (LPC32XX_I2C_SOFT_RESET , &i2c->ctrl); +writel (LPC32XX_I2C_SOFT_RESET , &base->ctrl);/* set HI and LO periods for half of the default speed */ -__i2c_set_bus_speed (adap, requested_speed); +__i2c_set_bus_speed (base, requested_speed, chip); }/* I2C probe called by cmd_i2c when doing 'i2c probe'. */ -static int __i2c_probe_chip (struct i2c_adapter *adap,u8 dev) +static int __i2c_probe_chip (struct lpc32xx_i2c_base *base,u8 dev) { -struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];int stat;/* Soft-reset the controller */ -writel (LPC32XX_I2C_SOFT_RESET , &i2c->ctrl); -while (readl (&i2c->ctrl) &LPC32XX_I2C_SOFT_RESET ) +writel (LPC32XX_I2C_SOFT_RESET , &base->ctrl); +while (readl (&base->ctrl) &LPC32XX_I2C_SOFT_RESET ) ;/* Addre slave for write with start before and stop after */ writel ((dev<<1 ) |LPC32XX_I2C_TX_START |LPC32XX_I2C_TX_STOP , - &i2c->tx); + &base->tx);/* wait for end of transation */ -while (!((stat =readl (&i2c->stat)) &LPC32XX_I2C_STAT_TDI )) +while (!((stat =readl (&base->stat)) &LPC32XX_I2C_STAT_TDI )) ;/* was there no acknowledge? */ return (stat &LPC32XX_I2C_STAT_NAI ) ?-1 :0 ;@@ -128,20 +125,19 @@ static int __i2c_probe_chip(struct i2c_adapter *adap, u8 dev)* I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c * Begin write, send address byte(s), begin read, receive data bytes, end. */ -static int __i2c_read (struct i2c_adapter *adap,u8 dev,uint addr, -int alen,u8 *data,int length) +static int __i2c_read (struct lpc32xx_i2c_base *base,u8 dev,uint addr, +int alen,u8 *data,int length) { -struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];int stat, wlen;/* Soft-reset the controller */ -writel (LPC32XX_I2C_SOFT_RESET , &i2c->ctrl); -while (readl (&i2c->ctrl) &LPC32XX_I2C_SOFT_RESET ) +writel (LPC32XX_I2C_SOFT_RESET , &base->ctrl); +while (readl (&base->ctrl) &LPC32XX_I2C_SOFT_RESET ) ;/* do we need to write an address at all? */ if (alen) {/* Address slave in write mode */ -writel ((dev<<1 ) |LPC32XX_I2C_TX_START , &i2c->tx); +writel ((dev<<1 ) |LPC32XX_I2C_TX_START , &base->tx);/* write address bytes */ while (alen--) {/* compute address byte + stop for the last one */ @@ -149,44 +145,44 @@ static int __i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,if (!alen) a |=LPC32XX_I2C_TX_STOP ;/* Send address byte */ -writel (a, &i2c->tx); +writel (a, &base->tx); }/* wait for end of transation */ -while (!((stat =readl (&i2c->stat)) &LPC32XX_I2C_STAT_TDI )) +while (!((stat =readl (&base->stat)) &LPC32XX_I2C_STAT_TDI )) ;/* clear end-of-transaction flag */ -writel (1 , &i2c->stat); +writel (1 , &base->stat); }/* do we have to read data at all? */ if (length) {/* Address slave in read mode */ -writel (1 | (dev<<1 ) |LPC32XX_I2C_TX_START , &i2c->tx); +writel (1 | (dev<<1 ) |LPC32XX_I2C_TX_START , &base->tx); wlen = length;/* get data */ while (length | wlen) {/* read status for TFF and RFE */ - stat =readl (&i2c->stat); + stat =readl (&base->stat);/* must we, can we write a trigger byte? */ if ((wlen >0 ) & (!(stat &LPC32XX_I2C_STAT_TFF ))) { wlen--;/* write trigger byte + stop if last */ writel (wlen ?0 : -LPC32XX_I2C_TX_STOP , &i2c->tx); +LPC32XX_I2C_TX_STOP , &base->tx); }/* must we, can we read a data byte? */ if ((length >0 ) & (!(stat &LPC32XX_I2C_STAT_RFE ))) { length--;/* read byte */ - *(data++) =readl (&i2c->rx); + *(data++) =readl (&base->rx); } }/* wait for end of transation */ -while (!((stat =readl (&i2c->stat)) &LPC32XX_I2C_STAT_TDI )) +while (!((stat =readl (&base->stat)) &LPC32XX_I2C_STAT_TDI )) ;/* clear end-of-transaction flag */ -writel (1 , &i2c->stat); +writel (1 , &base->stat); }/* success */ return 0 ;@@ -196,38 +192,37 @@ static int __i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,* I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c * Begin write, send address byte(s), send data bytes, end. */ -static int __i2c_write (struct i2c_adapter *adap,u8 dev,uint addr, -int alen,u8 *data,int length) +static int __i2c_write (struct lpc32xx_i2c_base *base,u8 dev,uint addr, +int alen,u8 *data,int length) { -struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];int stat;/* Soft-reset the controller */ -writel (LPC32XX_I2C_SOFT_RESET , &i2c->ctrl); -while (readl (&i2c->ctrl) &LPC32XX_I2C_SOFT_RESET ) +writel (LPC32XX_I2C_SOFT_RESET , &base->ctrl); +while (readl (&base->ctrl) &LPC32XX_I2C_SOFT_RESET ) ;/* do we need to write anything at all? */ if (alen | length)/* Address slave in write mode */ -writel ((dev<<1 ) |LPC32XX_I2C_TX_START , &i2c->tx); +writel ((dev<<1 ) |LPC32XX_I2C_TX_START , &base->tx);else return 0 ;/* write address bytes */ while (alen) {/* wait for transmit fifo not full */ - stat =readl (&i2c->stat); + stat =readl (&base->stat);if (!(stat &LPC32XX_I2C_STAT_TFF )) { alen--;int a = (addr >> (8 * alen)) &0xff ;if (!(alen | length)) a |=LPC32XX_I2C_TX_STOP ;/* Send address byte */ -writel (a, &i2c->tx); +writel (a, &base->tx); } }while (length) {/* wait for transmit fifo not full */ - stat =readl (&i2c->stat); + stat =readl (&base->stat);if (!(stat &LPC32XX_I2C_STAT_TFF )) {/* compute data byte, add stop if length==0 */ length--;@@ -235,44 +230,48 @@ static int __i2c_write(struct i2c_adapter *adap, u8 dev, uint addr,if (!length) d |=LPC32XX_I2C_TX_STOP ;/* Send data byte */ -writel (d, &i2c->tx); +writel (d, &base->tx); } }/* wait for end of transation */ -while (!((stat =readl (&i2c->stat)) &LPC32XX_I2C_STAT_TDI )) +while (!((stat =readl (&base->stat)) &LPC32XX_I2C_STAT_TDI )) ;/* clear end-of-transaction flag */ -writel (1 , &i2c->stat); +writel (1 , &base->stat);return 0 ; }static void lpc32xx_i2c_init (struct i2c_adapter *adap,int requested_speed,int slaveadd) { -__i2c_init (adap, requested_speed, slaveadd); +__i2c_init (lpc32xx_i2c[adap->hwadapnr], requested_speed, slaveadd, + adap->hwadapnr); }static int lpc32xx_i2c_probe_chip (struct i2c_adapter *adap,u8 dev) { -return __i2c_probe_chip (adap, dev); +return __i2c_probe_chip (lpc32xx_i2c[adap->hwadapnr], dev); }static int lpc32xx_i2c_read (struct i2c_adapter *adap,u8 dev,uint addr,int alen,u8 *data,int length) { -return __i2c_read (adap, dev, addr, alen, data, length); +return __i2c_read (lpc32xx_i2c[adap->hwadapnr], dev, addr, + alen, data, length); }static int lpc32xx_i2c_write (struct i2c_adapter *adap,u8 dev,uint addr,int alen,u8 *data,int length) { -return __i2c_write (adap, dev, addr, alen, data, length); +return __i2c_write (lpc32xx_i2c[adap->hwadapnr], dev, addr, + alen, data, length); }static unsigned int lpc32xx_i2c_set_bus_speed (struct i2c_adapter *adap,unsigned int speed) { -return __i2c_set_bus_speed (adap, speed); +return __i2c_set_bus_speed (lpc32xx_i2c[adap->hwadapnr], speed, + adap->hwadapnr); } U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_0, lpc32xx_i2c_init, lpc32xx_i2c_probe_chip,
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany