Re: [PATCH 2/8] ASoC: OMAP: RX-51 Machine driver and AIC34b_dummy driver

2009-10-09 Thread Eduardo Valentin
On Fri, Oct 09, 2009 at 07:44:00AM +0200, Jarkko Nikula wrote:
 On Thu, 8 Oct 2009 14:11:16 +0100
 Mark Brown broo...@opensource.wolfsonmicro.com wrote:
 
  What is an AIC34b_dummy (block B)?  You probably want to split it out
  into a separate patch.
  
 I think this is the reason why Eduardo mentioned my name in the commit
 log :-)

Yeah, I mentioned Jarkko because he was the person who initially wrote those 
drivers :-).

But I can split then if you prefer. No problem.

 
 Yep, dummy driver is for block B of AIC34 which is basically dual AIC33
 in a same package.

Yes. This is correct.

 
   + * TODO:
   + * - Get rid of this driver, at least when ASoC v2 is merged and when
   + *   we can support multiple codec instances in tlv320aic3x.c driver.
   + *   This driver is hacked only for Nokia RX51 HW.
  
  Could you please explain what the issue here is?  A description of the
  hardware would go a long way here.
  
 Eduardo, please correct me if I remember wrong  but block B of AIC34 is
 not used as an codec as such but more like an amplifier and analogic
 mixer with digital parts unused. So with this dummy driver the HW
 features were easier to support than to develop multiple intance
 support for codec drivers.


Yes. This is also correct. It is more like an amplifier / mixer.
I think that's why you named it dummy :-).

But I think I should add this info as a comment inside the code.


 
 
 -- 
 Jarkko

-- 
Eduardo Valentin
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [alsa-devel] [PATCH 2/8] ASoC: OMAP: RX-51 Machine driver and AIC34b_dummy driver

2009-10-09 Thread Mark Brown
On Fri, Oct 09, 2009 at 09:37:20AM +0300, Eduardo Valentin wrote:
 On Fri, Oct 09, 2009 at 07:44:00AM +0200, Jarkko Nikula wrote:

  Yep, dummy driver is for block B of AIC34 which is basically dual AIC33
  in a same package.

 Yes. This is correct.

So to software it just looks like two devices at separate I2C addresses
so once multi CODEC support is present there will be no need to have
specific support for it at all?

  Eduardo, please correct me if I remember wrong  but block B of AIC34 is
  not used as an codec as such but more like an amplifier and analogic
  mixer with digital parts unused. So with this dummy driver the HW
  features were easier to support than to develop multiple intance
  support for codec drivers.

 Yes. This is also correct. It is more like an amplifier / mixer.
 I think that's why you named it dummy :-).

 But I think I should add this info as a comment inside the code.

Some words or ASCII art in the machine driver would help a lot, I think.
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/8] ASoC: OMAP: RX-51 Machine driver and AIC34b_dummy driver

2009-10-08 Thread Eduardo Valentin
From: Eduardo Valentin eduardo.valen...@nokia.com

Introduce RX-51 Machine driver for ASoC and AIC34b_dummy (block B) i2c driver.

Also move the request_gpio of speaker_enabled
from board-rx51-peripherals.c to this machine driver.

These drivers were originally written by Jarkko Nikula.

Signed-off-by: Eduardo Valentin eduardo.valen...@nokia.com
---
 arch/arm/mach-omap2/board-rx51-peripherals.c |2 -
 sound/soc/omap/Kconfig   |   10 +
 sound/soc/omap/Makefile  |2 +
 sound/soc/omap/aic34b_dummy.c|  271 +
 sound/soc/omap/aic34b_dummy.h|   32 +
 sound/soc/omap/rx51.c|  793 ++
 sound/soc/omap/rx51.h|   29 +
 7 files changed, 1137 insertions(+), 2 deletions(-)
 create mode 100644 sound/soc/omap/aic34b_dummy.c
 create mode 100644 sound/soc/omap/aic34b_dummy.h
 create mode 100644 sound/soc/omap/rx51.c
 create mode 100644 sound/soc/omap/rx51.h

diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c 
b/arch/arm/mach-omap2/board-rx51-peripherals.c
index c1af532..b227475 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -262,8 +262,6 @@ static int rx51_twlgpio_setup(struct device *dev, unsigned 
gpio, unsigned n)
/* FIXME this gpio setup is just a placeholder for now */
gpio_request(gpio + 6, backlight_pwm);
gpio_direction_output(gpio + 6, 0);
-   gpio_request(gpio + 7, speaker_en);
-   gpio_direction_output(gpio + 7, 1);
 
/* set up MMC adapters, linking their regulators to them */
twl4030_mmc_init(mmc);
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 2dee983..bdcd4be 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -15,6 +15,16 @@ config SND_OMAP_SOC_N810
help
  Say Y if you want to add support for SoC audio on Nokia N810.
 
+config SND_OMAP_SOC_RX51
+   tristate SoC Audio support for Nokia RX51
+   depends on SND_OMAP_SOC  MACH_NOKIA_RX51
+   select OMAP_MCBSP
+   select SND_OMAP_SOC_MCBSP
+   select SND_SOC_TLV320AIC3X
+   select SND_SOC_TPA6130A2
+   help
+ Say Y if you want to add support for SoC audio on Nokia RX51.
+
 config SND_OMAP_SOC_AMS_DELTA
tristate SoC Audio support for Amstrad E3 (Delta) videophone
depends on SND_OMAP_SOC  MACH_AMS_DELTA
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 02d6947..7dec270 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -16,8 +16,10 @@ snd-soc-sdp3430-objs := sdp3430.o
 snd-soc-omap3pandora-objs := omap3pandora.o
 snd-soc-omap3beagle-objs := omap3beagle.o
 snd-soc-zoom2-objs := zoom2.o
+snd-soc-rx51-objs := rx51.o
 
 obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
+obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o aic34b_dummy.o
 obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
 obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
 obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
diff --git a/sound/soc/omap/aic34b_dummy.c b/sound/soc/omap/aic34b_dummy.c
new file mode 100644
index 000..17c4d9c
--- /dev/null
+++ b/sound/soc/omap/aic34b_dummy.c
@@ -0,0 +1,271 @@
+/*
+ * aic34b_dummy.c  --  Dummy driver for AIC34 block B parts used in Nokia RX51
+ *
+ * Purpose for this driver is to cover few audio connections on Nokia RX51 HW
+ * which are connected into block B of TLV320AIC34 dual codec.
+ *
+ * Copyright (C) 2008 - 2009 Nokia Corporation
+ *
+ * Contact: Peter Ujfalusi peter.ujfal...@nokia.com
+ *  Eduardo Valentin eduardo.valen...@nokia.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 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * TODO:
+ * - Get rid of this driver, at least when ASoC v2 is merged and when
+ *   we can support multiple codec instances in tlv320aic3x.c driver.
+ *   This driver is hacked only for Nokia RX51 HW.
+ */
+
+#include linux/module.h
+#include linux/errno.h
+#include linux/device.h
+#include linux/i2c.h
+#include sound/soc.h
+
+#include ../codecs/tlv320aic3x.h
+
+struct i2c_client *aic34b_client;
+static DEFINE_MUTEX(aic34b_mutex);
+static DEFINE_MUTEX(button_press_mutex);
+static ktime_t button_press_denial_start;
+static int aic34b_volume;
+static int button_press_denied;
+static int aic34b_bias;
+
+
+static int 

Re: [PATCH 2/8] ASoC: OMAP: RX-51 Machine driver and AIC34b_dummy driver

2009-10-08 Thread Eero Nurkkala
On Thu, 2009-10-08 at 13:58 +0200, Valentin Eduardo (Nokia-D/Helsinki)
wrote:
 From: Eduardo Valentin eduardo.valen...@nokia.com
 
 Introduce RX-51 Machine driver for ASoC and AIC34b_dummy (block B) i2c driver.
 
 Also move the request_gpio of speaker_enabled
 from board-rx51-peripherals.c to this machine driver.
 
 These drivers were originally written by Jarkko Nikula.
 
 Signed-off-by: Eduardo Valentin eduardo.valen...@nokia.com
 ---
  arch/arm/mach-omap2/board-rx51-peripherals.c |2 -
  sound/soc/omap/Kconfig   |   10 +
  sound/soc/omap/Makefile  |2 +
  sound/soc/omap/aic34b_dummy.c|  271 +
  sound/soc/omap/aic34b_dummy.h|   32 +
  sound/soc/omap/rx51.c|  793 
 ++
  sound/soc/omap/rx51.h|   29 +
  7 files changed, 1137 insertions(+), 2 deletions(-)
  create mode 100644 sound/soc/omap/aic34b_dummy.c
  create mode 100644 sound/soc/omap/aic34b_dummy.h
  create mode 100644 sound/soc/omap/rx51.c
  create mode 100644 sound/soc/omap/rx51.h
 
 diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c 
 b/arch/arm/mach-omap2/board-rx51-peripherals.c
 index c1af532..b227475 100644
 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c
 +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
 @@ -262,8 +262,6 @@ static int rx51_twlgpio_setup(struct device *dev, 
 unsigned gpio, unsigned n)
 /* FIXME this gpio setup is just a placeholder for now */
 gpio_request(gpio + 6, backlight_pwm);
 gpio_direction_output(gpio + 6, 0);
 -   gpio_request(gpio + 7, speaker_en);
 -   gpio_direction_output(gpio + 7, 1);
 
 /* set up MMC adapters, linking their regulators to them */
 twl4030_mmc_init(mmc);
 diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
 index 2dee983..bdcd4be 100644
 --- a/sound/soc/omap/Kconfig
 +++ b/sound/soc/omap/Kconfig
 @@ -15,6 +15,16 @@ config SND_OMAP_SOC_N810
 help
   Say Y if you want to add support for SoC audio on Nokia N810.
 
 +config SND_OMAP_SOC_RX51
 +   tristate SoC Audio support for Nokia RX51
 +   depends on SND_OMAP_SOC  MACH_NOKIA_RX51
 +   select OMAP_MCBSP
 +   select SND_OMAP_SOC_MCBSP
 +   select SND_SOC_TLV320AIC3X
 +   select SND_SOC_TPA6130A2
 +   help
 + Say Y if you want to add support for SoC audio on Nokia RX51.
 +
  config SND_OMAP_SOC_AMS_DELTA
 tristate SoC Audio support for Amstrad E3 (Delta) videophone
 depends on SND_OMAP_SOC  MACH_AMS_DELTA
 diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
 index 02d6947..7dec270 100644
 --- a/sound/soc/omap/Makefile
 +++ b/sound/soc/omap/Makefile
 @@ -16,8 +16,10 @@ snd-soc-sdp3430-objs := sdp3430.o
  snd-soc-omap3pandora-objs := omap3pandora.o
  snd-soc-omap3beagle-objs := omap3beagle.o
  snd-soc-zoom2-objs := zoom2.o
 +snd-soc-rx51-objs := rx51.o
 
  obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
 +obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o aic34b_dummy.o
  obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
  obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
  obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
 diff --git a/sound/soc/omap/aic34b_dummy.c b/sound/soc/omap/aic34b_dummy.c
 new file mode 100644
 index 000..17c4d9c
 --- /dev/null
 +++ b/sound/soc/omap/aic34b_dummy.c
 @@ -0,0 +1,271 @@
 +/*
 + * aic34b_dummy.c  --  Dummy driver for AIC34 block B parts used in Nokia 
 RX51
 + *
 + * Purpose for this driver is to cover few audio connections on Nokia RX51 HW
 + * which are connected into block B of TLV320AIC34 dual codec.
 + *
 + * Copyright (C) 2008 - 2009 Nokia Corporation
 + *
 + * Contact: Peter Ujfalusi peter.ujfal...@nokia.com
 + *  Eduardo Valentin eduardo.valen...@nokia.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 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.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 + * 02110-1301 USA
 + *
 + * TODO:
 + * - Get rid of this driver, at least when ASoC v2 is merged and when
 + *   we can support multiple codec instances in tlv320aic3x.c driver.
 + *   This driver is hacked only for Nokia RX51 HW.
 + */
 +
 +#include linux/module.h
 +#include linux/errno.h
 +#include linux/device.h
 +#include linux/i2c.h
 +#include sound/soc.h
 +
 +#include ../codecs/tlv320aic3x.h
 +
 +struct i2c_client *aic34b_client;
 +static DEFINE_MUTEX(aic34b_mutex);
 

Re: [PATCH 2/8] ASoC: OMAP: RX-51 Machine driver and AIC34b_dummy driver

2009-10-08 Thread Mark Brown
On Thu, Oct 08, 2009 at 02:58:51PM +0300, Eduardo Valentin wrote:
 From: Eduardo Valentin eduardo.valen...@nokia.com

 Introduce RX-51 Machine driver for ASoC and AIC34b_dummy (block B) i2c driver.

What is an AIC34b_dummy (block B)?  You probably want to split it out
into a separate patch.

 + * TODO:
 + * - Get rid of this driver, at least when ASoC v2 is merged and when
 + *   we can support multiple codec instances in tlv320aic3x.c driver.
 + *   This driver is hacked only for Nokia RX51 HW.

Could you please explain what the issue here is?  A description of the
hardware would go a long way here.

 +EXPORT_SYMBOL(aic34b_set_mic_bias);

EXPORT_SYMBOL_GPL().

 +static void rx51_set_eci_switches(int mode)
 +{
 + switch (mode) {
 + case 0: /* Bias off */
 + case 1: /* Bias according to rx51_dapm_jack_bias */
 + case 4: /* Bias on */
 + /* Codec connected to mic/bias line */
 + gpio_set_value(RX51_ECI_SWITCH_1_GPIO, 0);
 + gpio_set_value(RX51_ECI_SWITCH_2_GPIO, 1);
 + break;
 + case 2:
 + /* ECI INT#2 detect connected to mic/bias line */
 + gpio_set_value(RX51_ECI_SWITCH_1_GPIO, 0);
 + gpio_set_value(RX51_ECI_SWITCH_2_GPIO, 0);
 + break;
 + case 3:
 + /* ECI RX/TX connected to mic/bias line */
 + gpio_set_value(RX51_ECI_SWITCH_1_GPIO, 1);
 + gpio_set_value(RX51_ECI_SWITCH_2_GPIO, 0);
 + break;
 + }

Some defines for the mode (instead of magic numbers) would be nice).

 +void rx51_jack_report(int status)
 +{
 + snd_jack_report(rx51_jack, status);
 +}
 +EXPORT_SYMBOL(rx51_jack_report);

Why is this being exported?

 +enum {
 +   RX51_EXT_API_AIC34B,
 +};
 +#define SOC_RX51_EXT_SINGLE_TLV(xname, ext_api, max, tlv_array) \
 +{ \
 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
 + .name = xname, \
 + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
 +   SNDRV_CTL_ELEM_ACCESS_READWRITE, \
 + .tlv.p = (tlv_array), \
 + .info = rx51_ext_info_volsw, \
 + .get = rx51_ext_get_volsw, \
 + .put = rx51_ext_put_volsw, \
 + .private_value = (ext_api)  26 | (max)  16, \
 +}

This looks like it ought to be pushed down into some other driver?
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/8] ASoC: OMAP: RX-51 Machine driver and AIC34b_dummy driver

2009-10-08 Thread Eduardo Valentin
On Thu, Oct 08, 2009 at 02:31:26PM +0200, Nurkkala Eero.An (EXT-Offcode/Oulu) 
wrote:
 On Thu, 2009-10-08 at 13:58 +0200, Valentin Eduardo (Nokia-D/Helsinki)
 wrote:
  From: Eduardo Valentin eduardo.valen...@nokia.com
 
  Introduce RX-51 Machine driver for ASoC and AIC34b_dummy (block B) i2c 
  driver.
 
  Also move the request_gpio of speaker_enabled
  from board-rx51-peripherals.c to this machine driver.
 
  These drivers were originally written by Jarkko Nikula.
 
  Signed-off-by: Eduardo Valentin eduardo.valen...@nokia.com
  ---
   arch/arm/mach-omap2/board-rx51-peripherals.c |2 -
   sound/soc/omap/Kconfig   |   10 +
   sound/soc/omap/Makefile  |2 +
   sound/soc/omap/aic34b_dummy.c|  271 +
   sound/soc/omap/aic34b_dummy.h|   32 +
   sound/soc/omap/rx51.c|  793 
  ++
   sound/soc/omap/rx51.h|   29 +
   7 files changed, 1137 insertions(+), 2 deletions(-)
   create mode 100644 sound/soc/omap/aic34b_dummy.c
   create mode 100644 sound/soc/omap/aic34b_dummy.h
   create mode 100644 sound/soc/omap/rx51.c
   create mode 100644 sound/soc/omap/rx51.h
 

snip

  +static struct platform_device *rx51_snd_device;
  +
  +#define REMAP_OFFSET   2
  +#define DEDICATED_OFFSET   3
  +#define VMMC2_DEV_GRP  0x2B
  +#define VMMC2_285V 0x0a
  +
 
 These defines appear unused?


yeah, will rip then off.

 
  +static int __init rx51_soc_init(void)
  +{
  +   int err;
  +   struct device *dev;
  +
  +   if (!machine_is_nokia_rx51())
  +   return -ENODEV;
  +
  +   if (gpio_request(RX51_CODEC_RESET_GPIO, NULL)  0)
  +   BUG();
  +   if (gpio_request(RX51_TVOUT_SEL_GPIO, tvout_sel)  0)
  +   BUG();
  +   if (gpio_request(RX51_ECI_SWITCH_1_GPIO, ECI switch 1)  0)
  +   BUG();
  +   if (gpio_request(RX51_ECI_SWITCH_2_GPIO, ECI switch 2)  0)
  +   BUG();
  +   gpio_direction_output(RX51_CODEC_RESET_GPIO, 0);
  +   gpio_direction_output(RX51_TVOUT_SEL_GPIO, 0);
  +   gpio_direction_output(RX51_ECI_SWITCH_1_GPIO, 0);
  +   gpio_direction_output(RX51_ECI_SWITCH_2_GPIO, 1);
  +
  +   gpio_set_value(RX51_CODEC_RESET_GPIO, 0);
  +   udelay(1);
  +   gpio_set_value(RX51_CODEC_RESET_GPIO, 1);
  +   msleep(1);
  +
  +   if (gpio_request(RX51_SPEAKER_AMP_TWL_GPIO, NULL)  0)
  +   BUG();
  +   gpio_direction_output(RX51_SPEAKER_AMP_TWL_GPIO, 0);
  +
  +   err = snd_soc_register_dai(btcodec_dai);
  +   if (err)
  +   return err;
  +
  +   rx51_snd_device = platform_device_alloc(soc-audio, -1);
  +   if (!rx51_snd_device) {
  +   err = -ENOMEM;
  +   goto err0;
  +   }
  +
  +   platform_set_drvdata(rx51_snd_device, rx51_snd_devdata);
  +   rx51_snd_devdata.dev = rx51_snd_device-dev;
  +   err = platform_device_add(rx51_snd_device);
  +   if (err)
  +   goto err1;
  +
  +   dev = rx51_snd_device-dev;
  +
  +   *(unsigned int *)rx51_dai[0].cpu_dai-private_data = 1;
  +   *(unsigned int *)rx51_dai[1].cpu_dai-private_data = 2;
  +
  +   err = device_create_file(dev, dev_attr_eci_mode);
  +   if (err)
  +   goto err2;
  +
  +   return err;
  +err2:
  +   platform_device_del(rx51_snd_device);
  +err1:
  +   platform_device_put(rx51_snd_device);
  +err0:
  +   snd_soc_unregister_dai(btcodec_dai);
  +
  +   return err;
  +
  +}
  +
  +static void __exit rx51_soc_exit(void)
  +{
  +   platform_device_unregister(rx51_snd_device);
  +   snd_soc_unregister_dai(btcodec_dai);
  +}
  +
  +module_init(rx51_soc_init);
  +module_exit(rx51_soc_exit);
  +
  +MODULE_AUTHOR(Nokia Corporation);
  +MODULE_DESCRIPTION(ALSA SoC Nokia RX51);
  +MODULE_LICENSE(GPL);
  diff --git a/sound/soc/omap/rx51.h b/sound/soc/omap/rx51.h
  new file mode 100644
  index 000..ee55260
  --- /dev/null
  +++ b/sound/soc/omap/rx51.h
  @@ -0,0 +1,29 @@
  +#ifndef _RX51_H_
  +#define _RX51_H_
  +
  +/*
  + *  rx51.h - SoC audio for Nokia RX51
  + *
  + *  Copyright (C) 2008 - 2009 Nokia Corporation
  + *
  + *  Contact: Peter Ujfalusi peter.ujfal...@nokia.com
  + *   Eduardo Valentin eduardo.valen...@nokia.com
  + *
  + *  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 of the License.
  + *
  + *  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.
  + *
  + *  You should have received a copy of the GNU General Public License
  + *  along with this program; if not, write