[media] siano: break it into common, mmc and usb
authorMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 14 Jun 2012 19:36:01 +0000 (16:36 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 14 Aug 2012 02:52:52 +0000 (23:52 -0300)
siano is, in fact, 2 drivers: one for MMC and one for USB, plus
a common bus-independent code. Break it accordingly.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
32 files changed:
drivers/media/Kconfig
drivers/media/Makefile
drivers/media/common/Kconfig
drivers/media/common/Makefile
drivers/media/common/siano/Kconfig [new file with mode: 0644]
drivers/media/common/siano/Makefile [new file with mode: 0644]
drivers/media/common/siano/sms-cards.c [new file with mode: 0644]
drivers/media/common/siano/sms-cards.h [new file with mode: 0644]
drivers/media/common/siano/smscoreapi.c [new file with mode: 0644]
drivers/media/common/siano/smscoreapi.h [new file with mode: 0644]
drivers/media/common/siano/smsdvb.c [new file with mode: 0644]
drivers/media/common/siano/smsendian.c [new file with mode: 0644]
drivers/media/common/siano/smsendian.h [new file with mode: 0644]
drivers/media/common/siano/smsir.c [new file with mode: 0644]
drivers/media/common/siano/smsir.h [new file with mode: 0644]
drivers/media/mmc/Kconfig [new file with mode: 0644]
drivers/media/mmc/Makefile [new file with mode: 0644]
drivers/media/mmc/siano/Kconfig [new file with mode: 0644]
drivers/media/mmc/siano/Makefile [new file with mode: 0644]
drivers/media/mmc/siano/smssdio.c [new file with mode: 0644]
drivers/media/usb/siano/Kconfig
drivers/media/usb/siano/Makefile
drivers/media/usb/siano/sms-cards.c [deleted file]
drivers/media/usb/siano/sms-cards.h [deleted file]
drivers/media/usb/siano/smscoreapi.c [deleted file]
drivers/media/usb/siano/smscoreapi.h [deleted file]
drivers/media/usb/siano/smsdvb.c [deleted file]
drivers/media/usb/siano/smsendian.c [deleted file]
drivers/media/usb/siano/smsendian.h [deleted file]
drivers/media/usb/siano/smsir.c [deleted file]
drivers/media/usb/siano/smsir.h [deleted file]
drivers/media/usb/siano/smssdio.c [deleted file]

index aae6fec3b9e1760ffd64d1c46fcea8f6cac1cfbf..7970c24512e9f54cca894742cf9a097c275138e0 100644 (file)
@@ -163,6 +163,7 @@ source "drivers/media/radio/Kconfig"
 source "drivers/media/dvb-core/Kconfig"
 source "drivers/media/pci/Kconfig"
 source "drivers/media/usb/Kconfig"
+source "drivers/media/mmc/Kconfig"
 
 comment "Supported FireWire (IEEE 1394) Adapters"
        depends on DVB_CORE && FIREWIRE
index f89ccace746f150051976a11d3764e0ee776b69d..3265a9a216df9d26469d322637780321efb1ed8b 100644 (file)
@@ -11,5 +11,5 @@ endif
 obj-y += v4l2-core/ tuners/ common/ rc/ video/
 
 obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-$(CONFIG_DVB_CORE)  += dvb-core/ pci/ dvb-frontends/ usb/
+obj-$(CONFIG_DVB_CORE)  += dvb-core/ pci/ dvb-frontends/ usb/ mmc/
 obj-$(CONFIG_DVB_FIREDTV) += firewire/
index 157f191ef646b7136d4a6c5b9e9005b6b23b23d3..121b0110af3c525055e426bb7e206c02f2389c04 100644 (file)
@@ -1,2 +1,3 @@
 source "drivers/media/common/b2c2/Kconfig"
 source "drivers/media/common/saa7146/Kconfig"
+source "drivers/media/common/siano/Kconfig"
index f3afd83843e03fbfe4c8c2effb6699cd54f9ee1d..b8e2e3a33a319d408efc812d9bb8109d85deffd5 100644 (file)
@@ -1 +1 @@
-obj-y += b2c2/ saa7146/
+obj-y += b2c2/ saa7146/ siano/
diff --git a/drivers/media/common/siano/Kconfig b/drivers/media/common/siano/Kconfig
new file mode 100644 (file)
index 0000000..425aead
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Siano Mobile Silicon Digital TV device configuration
+#
+
+config SMS_SIANO_MDTV
+       tristate
+       depends on DVB_CORE && RC_CORE && HAS_DMA
+       depends on SMS_USB_DRV || SMS_SDIO_DRV
+       default y
+       ---help---
+         Choose Y or M here if you have MDTV receiver with a Siano chipset.
+
+         To compile this driver as a module, choose M here
+         (The module will be called smsmdtv).
+
+         Further documentation on this driver can be found on the WWW
+         at http://www.siano-ms.com/
diff --git a/drivers/media/common/siano/Makefile b/drivers/media/common/siano/Makefile
new file mode 100644 (file)
index 0000000..2a09279
--- /dev/null
@@ -0,0 +1,7 @@
+smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
+
+obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
+
diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c
new file mode 100644 (file)
index 0000000..680c781
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ *  Card-specific functions for the Siano SMS1xxx USB dongle
+ *
+ *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *  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;
+ *
+ *  Software distributed under the License is distributed on an "AS IS"
+ *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "sms-cards.h"
+#include "smsir.h"
+#include <linux/module.h>
+
+static int sms_dbg;
+module_param_named(cards_dbg, sms_dbg, int, 0644);
+MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
+
+static struct sms_board sms_boards[] = {
+       [SMS_BOARD_UNKNOWN] = {
+               .name   = "Unknown board",
+       },
+       [SMS1XXX_BOARD_SIANO_STELLAR] = {
+               .name   = "Siano Stellar Digital Receiver",
+               .type   = SMS_STELLAR,
+       },
+       [SMS1XXX_BOARD_SIANO_NOVA_A] = {
+               .name   = "Siano Nova A Digital Receiver",
+               .type   = SMS_NOVA_A0,
+       },
+       [SMS1XXX_BOARD_SIANO_NOVA_B] = {
+               .name   = "Siano Nova B Digital Receiver",
+               .type   = SMS_NOVA_B0,
+       },
+       [SMS1XXX_BOARD_SIANO_VEGA] = {
+               .name   = "Siano Vega Digital Receiver",
+               .type   = SMS_VEGA,
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
+               .name   = "Hauppauge Catamount",
+               .type   = SMS_STELLAR,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
+               .name   = "Hauppauge Okemo-A",
+               .type   = SMS_NOVA_A0,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
+               .name   = "Hauppauge Okemo-B",
+               .type   = SMS_NOVA_B0,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
+               .name   = "Hauppauge WinTV MiniStick",
+               .type   = SMS_NOVA_B0,
+               .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
+               .rc_codes = RC_MAP_HAUPPAUGE,
+               .board_cfg.leds_power = 26,
+               .board_cfg.led0 = 27,
+               .board_cfg.led1 = 28,
+               .board_cfg.ir = 9,
+               .led_power = 26,
+               .led_lo    = 27,
+               .led_hi    = 28,
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
+               .name   = "Hauppauge WinTV MiniCard",
+               .type   = SMS_NOVA_B0,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
+               .lna_ctrl  = 29,
+               .board_cfg.foreign_lna0_ctrl = 29,
+               .rf_switch = 17,
+               .board_cfg.rf_switch_uhf = 17,
+       },
+       [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
+               .name   = "Hauppauge WinTV MiniCard",
+               .type   = SMS_NOVA_B0,
+               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
+               .lna_ctrl  = -1,
+       },
+       [SMS1XXX_BOARD_SIANO_NICE] = {
+       /* 11 */
+               .name = "Siano Nice Digital Receiver",
+               .type = SMS_NOVA_B0,
+       },
+       [SMS1XXX_BOARD_SIANO_VENICE] = {
+       /* 12 */
+               .name = "Siano Venice Digital Receiver",
+               .type = SMS_VEGA,
+       },
+};
+
+struct sms_board *sms_get_board(unsigned id)
+{
+       BUG_ON(id >= ARRAY_SIZE(sms_boards));
+
+       return &sms_boards[id];
+}
+EXPORT_SYMBOL_GPL(sms_get_board);
+static inline void sms_gpio_assign_11xx_default_led_config(
+               struct smscore_gpio_config *pGpioConfig) {
+       pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
+       pGpioConfig->InputCharacteristics =
+               SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
+       pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
+       pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
+       pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
+}
+
+int sms_board_event(struct smscore_device_t *coredev,
+               enum SMS_BOARD_EVENTS gevent) {
+       struct smscore_gpio_config MyGpioConfig;
+
+       sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
+
+       switch (gevent) {
+       case BOARD_EVENT_POWER_INIT: /* including hotplug */
+               break; /* BOARD_EVENT_BIND */
+
+       case BOARD_EVENT_POWER_SUSPEND:
+               break; /* BOARD_EVENT_POWER_SUSPEND */
+
+       case BOARD_EVENT_POWER_RESUME:
+               break; /* BOARD_EVENT_POWER_RESUME */
+
+       case BOARD_EVENT_BIND:
+               break; /* BOARD_EVENT_BIND */
+
+       case BOARD_EVENT_SCAN_PROG:
+               break; /* BOARD_EVENT_SCAN_PROG */
+       case BOARD_EVENT_SCAN_COMP:
+               break; /* BOARD_EVENT_SCAN_COMP */
+       case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
+               break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
+       case BOARD_EVENT_FE_LOCK:
+               break; /* BOARD_EVENT_FE_LOCK */
+       case BOARD_EVENT_FE_UNLOCK:
+               break; /* BOARD_EVENT_FE_UNLOCK */
+       case BOARD_EVENT_DEMOD_LOCK:
+               break; /* BOARD_EVENT_DEMOD_LOCK */
+       case BOARD_EVENT_DEMOD_UNLOCK:
+               break; /* BOARD_EVENT_DEMOD_UNLOCK */
+       case BOARD_EVENT_RECEPTION_MAX_4:
+               break; /* BOARD_EVENT_RECEPTION_MAX_4 */
+       case BOARD_EVENT_RECEPTION_3:
+               break; /* BOARD_EVENT_RECEPTION_3 */
+       case BOARD_EVENT_RECEPTION_2:
+               break; /* BOARD_EVENT_RECEPTION_2 */
+       case BOARD_EVENT_RECEPTION_1:
+               break; /* BOARD_EVENT_RECEPTION_1 */
+       case BOARD_EVENT_RECEPTION_LOST_0:
+               break; /* BOARD_EVENT_RECEPTION_LOST_0 */
+       case BOARD_EVENT_MULTIPLEX_OK:
+               break; /* BOARD_EVENT_MULTIPLEX_OK */
+       case BOARD_EVENT_MULTIPLEX_ERRORS:
+               break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
+
+       default:
+               sms_err("Unknown SMS board event");
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_event);
+
+static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
+{
+       int lvl, ret;
+       u32 gpio;
+       struct smscore_config_gpio gpioconfig = {
+               .direction            = SMS_GPIO_DIRECTION_OUTPUT,
+               .pullupdown           = SMS_GPIO_PULLUPDOWN_NONE,
+               .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
+               .outputslewrate       = SMS_GPIO_OUTPUTSLEWRATE_FAST,
+               .outputdriving        = SMS_GPIO_OUTPUTDRIVING_4mA,
+       };
+
+       if (pin == 0)
+               return -EINVAL;
+
+       if (pin < 0) {
+               /* inverted gpio */
+               gpio = pin * -1;
+               lvl = enable ? 0 : 1;
+       } else {
+               gpio = pin;
+               lvl = enable ? 1 : 0;
+       }
+
+       ret = smscore_configure_gpio(coredev, gpio, &gpioconfig);
+       if (ret < 0)
+               return ret;
+
+       return smscore_set_gpio(coredev, gpio, lvl);
+}
+
+int sms_board_setup(struct smscore_device_t *coredev)
+{
+       int board_id = smscore_get_board_id(coredev);
+       struct sms_board *board = sms_get_board(board_id);
+
+       switch (board_id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+               /* turn off all LEDs */
+               sms_set_gpio(coredev, board->led_power, 0);
+               sms_set_gpio(coredev, board->led_hi, 0);
+               sms_set_gpio(coredev, board->led_lo, 0);
+               break;
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+               /* turn off LNA */
+               sms_set_gpio(coredev, board->lna_ctrl, 0);
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_setup);
+
+int sms_board_power(struct smscore_device_t *coredev, int onoff)
+{
+       int board_id = smscore_get_board_id(coredev);
+       struct sms_board *board = sms_get_board(board_id);
+
+       switch (board_id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+               /* power LED */
+               sms_set_gpio(coredev,
+                            board->led_power, onoff ? 1 : 0);
+               break;
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+               /* LNA */
+               if (!onoff)
+                       sms_set_gpio(coredev, board->lna_ctrl, 0);
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_power);
+
+int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
+{
+       int board_id = smscore_get_board_id(coredev);
+       struct sms_board *board = sms_get_board(board_id);
+
+       /* dont touch GPIO if LEDs are already set */
+       if (smscore_led_state(coredev, -1) == led)
+               return 0;
+
+       switch (board_id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+               sms_set_gpio(coredev,
+                            board->led_lo, (led & SMS_LED_LO) ? 1 : 0);
+               sms_set_gpio(coredev,
+                            board->led_hi, (led & SMS_LED_HI) ? 1 : 0);
+
+               smscore_led_state(coredev, led);
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_led_feedback);
+
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
+{
+       int board_id = smscore_get_board_id(coredev);
+       struct sms_board *board = sms_get_board(board_id);
+
+       sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
+
+       switch (board_id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+               sms_set_gpio(coredev,
+                            board->rf_switch, onoff ? 1 : 0);
+               return sms_set_gpio(coredev,
+                                   board->lna_ctrl, onoff ? 1 : 0);
+       }
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(sms_board_lna_control);
+
+int sms_board_load_modules(int id)
+{
+       switch (id) {
+       case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
+       case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
+       case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
+       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+               request_module("smsdvb");
+               break;
+       default:
+               /* do nothing */
+               break;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/common/siano/sms-cards.h b/drivers/media/common/siano/sms-cards.h
new file mode 100644 (file)
index 0000000..d8cdf75
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  Card-specific functions for the Siano SMS1xxx USB dongle
+ *
+ *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *  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;
+ *
+ *  Software distributed under the License is distributed on an "AS IS"
+ *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __SMS_CARDS_H__
+#define __SMS_CARDS_H__
+
+#include <linux/usb.h>
+#include "smscoreapi.h"
+#include "smsir.h"
+
+#define SMS_BOARD_UNKNOWN 0
+#define SMS1XXX_BOARD_SIANO_STELLAR 1
+#define SMS1XXX_BOARD_SIANO_NOVA_A  2
+#define SMS1XXX_BOARD_SIANO_NOVA_B  3
+#define SMS1XXX_BOARD_SIANO_VEGA    4
+#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5
+#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6
+#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7
+#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
+#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9
+#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
+#define SMS1XXX_BOARD_SIANO_NICE       11
+#define SMS1XXX_BOARD_SIANO_VENICE     12
+
+struct sms_board_gpio_cfg {
+       int lna_vhf_exist;
+       int lna_vhf_ctrl;
+       int lna_uhf_exist;
+       int lna_uhf_ctrl;
+       int lna_uhf_d_ctrl;
+       int lna_sband_exist;
+       int lna_sband_ctrl;
+       int lna_sband_d_ctrl;
+       int foreign_lna0_ctrl;
+       int foreign_lna1_ctrl;
+       int foreign_lna2_ctrl;
+       int rf_switch_vhf;
+       int rf_switch_uhf;
+       int rf_switch_sband;
+       int leds_power;
+       int led0;
+       int led1;
+       int led2;
+       int led3;
+       int led4;
+       int ir;
+       int eeprom_wp;
+       int mrc_sense;
+       int mrc_pdn_resetn;
+       int mrc_gp0; /* mrcs spi int */
+       int mrc_gp1;
+       int mrc_gp2;
+       int mrc_gp3;
+       int mrc_gp4;
+       int host_spi_gsp_ts_int;
+};
+
+struct sms_board {
+       enum sms_device_type_st type;
+       char *name, *fw[DEVICE_MODE_MAX];
+       struct sms_board_gpio_cfg board_cfg;
+       char *rc_codes;                         /* Name of IR codes table */
+
+       /* gpios */
+       int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
+};
+
+struct sms_board *sms_get_board(unsigned id);
+
+extern struct smscore_device_t *coredev;
+
+enum SMS_BOARD_EVENTS {
+       BOARD_EVENT_POWER_INIT,
+       BOARD_EVENT_POWER_SUSPEND,
+       BOARD_EVENT_POWER_RESUME,
+       BOARD_EVENT_BIND,
+       BOARD_EVENT_SCAN_PROG,
+       BOARD_EVENT_SCAN_COMP,
+       BOARD_EVENT_EMERGENCY_WARNING_SIGNAL,
+       BOARD_EVENT_FE_LOCK,
+       BOARD_EVENT_FE_UNLOCK,
+       BOARD_EVENT_DEMOD_LOCK,
+       BOARD_EVENT_DEMOD_UNLOCK,
+       BOARD_EVENT_RECEPTION_MAX_4,
+       BOARD_EVENT_RECEPTION_3,
+       BOARD_EVENT_RECEPTION_2,
+       BOARD_EVENT_RECEPTION_1,
+       BOARD_EVENT_RECEPTION_LOST_0,
+       BOARD_EVENT_MULTIPLEX_OK,
+       BOARD_EVENT_MULTIPLEX_ERRORS
+};
+
+int sms_board_event(struct smscore_device_t *coredev,
+               enum SMS_BOARD_EVENTS gevent);
+
+int sms_board_setup(struct smscore_device_t *coredev);
+
+#define SMS_LED_OFF 0
+#define SMS_LED_LO  1
+#define SMS_LED_HI  2
+int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
+int sms_board_power(struct smscore_device_t *coredev, int onoff);
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
+
+extern int sms_board_load_modules(int id);
+
+#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
new file mode 100644 (file)
index 0000000..9cc5554
--- /dev/null
@@ -0,0 +1,1637 @@
+/*
+ *  Siano core API module
+ *
+ *  This file contains implementation for the interface to sms core component
+ *
+ *  author: Uri Shkolnik
+ *
+ *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
+ *
+ *  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;
+ *
+ *  Software distributed under the License is distributed on an "AS IS"
+ *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <linux/firmware.h>
+#include <linux/wait.h>
+#include <asm/byteorder.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+#include "smsir.h"
+#include "smsendian.h"
+
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
+struct smscore_device_notifyee_t {
+       struct list_head entry;
+       hotplug_t hotplug;
+};
+
+struct smscore_idlist_t {
+       struct list_head entry;
+       int             id;
+       int             data_type;
+};
+
+struct smscore_client_t {
+       struct list_head entry;
+       struct smscore_device_t *coredev;
+       void                    *context;
+       struct list_head        idlist;
+       onresponse_t    onresponse_handler;
+       onremove_t              onremove_handler;
+};
+
+void smscore_set_board_id(struct smscore_device_t *core, int id)
+{
+       core->board_id = id;
+}
+
+int smscore_led_state(struct smscore_device_t *core, int led)
+{
+       if (led >= 0)
+               core->led_state = led;
+       return core->led_state;
+}
+EXPORT_SYMBOL_GPL(smscore_set_board_id);
+
+int smscore_get_board_id(struct smscore_device_t *core)
+{
+       return core->board_id;
+}
+EXPORT_SYMBOL_GPL(smscore_get_board_id);
+
+struct smscore_registry_entry_t {
+       struct list_head entry;
+       char                    devpath[32];
+       int                             mode;
+       enum sms_device_type_st type;
+};
+
+static struct list_head g_smscore_notifyees;
+static struct list_head g_smscore_devices;
+static struct mutex g_smscore_deviceslock;
+
+static struct list_head g_smscore_registry;
+static struct mutex g_smscore_registrylock;
+
+static int default_mode = 4;
+
+module_param(default_mode, int, 0644);
+MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
+
+static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
+{
+       struct smscore_registry_entry_t *entry;
+       struct list_head *next;
+
+       kmutex_lock(&g_smscore_registrylock);
+       for (next = g_smscore_registry.next;
+            next != &g_smscore_registry;
+            next = next->next) {
+               entry = (struct smscore_registry_entry_t *) next;
+               if (!strcmp(entry->devpath, devpath)) {
+                       kmutex_unlock(&g_smscore_registrylock);
+                       return entry;
+               }
+       }
+       entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
+       if (entry) {
+               entry->mode = default_mode;
+               strcpy(entry->devpath, devpath);
+               list_add(&entry->entry, &g_smscore_registry);
+       } else
+               sms_err("failed to create smscore_registry.");
+       kmutex_unlock(&g_smscore_registrylock);
+       return entry;
+}
+
+int smscore_registry_getmode(char *devpath)
+{
+       struct smscore_registry_entry_t *entry;
+
+       entry = smscore_find_registry(devpath);
+       if (entry)
+               return entry->mode;
+       else
+               sms_err("No registry found.");
+
+       return default_mode;
+}
+EXPORT_SYMBOL_GPL(smscore_registry_getmode);
+
+static enum sms_device_type_st smscore_registry_gettype(char *devpath)
+{
+       struct smscore_registry_entry_t *entry;
+
+       entry = smscore_find_registry(devpath);
+       if (entry)
+               return entry->type;
+       else
+               sms_err("No registry found.");
+
+       return -1;
+}
+
+void smscore_registry_setmode(char *devpath, int mode)
+{
+       struct smscore_registry_entry_t *entry;
+
+       entry = smscore_find_registry(devpath);
+       if (entry)
+               entry->mode = mode;
+       else
+               sms_err("No registry found.");
+}
+
+static void smscore_registry_settype(char *devpath,
+                                    enum sms_device_type_st type)
+{
+       struct smscore_registry_entry_t *entry;
+
+       entry = smscore_find_registry(devpath);
+       if (entry)
+               entry->type = type;
+       else
+               sms_err("No registry found.");
+}
+
+
+static void list_add_locked(struct list_head *new, struct list_head *head,
+                           spinlock_t *lock)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(lock, flags);
+
+       list_add(new, head);
+
+       spin_unlock_irqrestore(lock, flags);
+}
+
+/**
+ * register a client callback that called when device plugged in/unplugged
+ * NOTE: if devices exist callback is called immediately for each device
+ *
+ * @param hotplug callback
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_hotplug(hotplug_t hotplug)
+{
+       struct smscore_device_notifyee_t *notifyee;
+       struct list_head *next, *first;
+       int rc = 0;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
+                          GFP_KERNEL);
+       if (notifyee) {
+               /* now notify callback about existing devices */
+               first = &g_smscore_devices;
+               for (next = first->next;
+                    next != first && !rc;
+                    next = next->next) {
+                       struct smscore_device_t *coredev =
+                               (struct smscore_device_t *) next;
+                       rc = hotplug(coredev, coredev->device, 1);
+               }
+
+               if (rc >= 0) {
+                       notifyee->hotplug = hotplug;
+                       list_add(&notifyee->entry, &g_smscore_notifyees);
+               } else
+                       kfree(notifyee);
+       } else
+               rc = -ENOMEM;
+
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(smscore_register_hotplug);
+
+/**
+ * unregister a client callback that called when device plugged in/unplugged
+ *
+ * @param hotplug callback
+ *
+ */
+void smscore_unregister_hotplug(hotplug_t hotplug)
+{
+       struct list_head *next, *first;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       first = &g_smscore_notifyees;
+
+       for (next = first->next; next != first;) {
+               struct smscore_device_notifyee_t *notifyee =
+                       (struct smscore_device_notifyee_t *) next;
+               next = next->next;
+
+               if (notifyee->hotplug == hotplug) {
+                       list_del(&notifyee->entry);
+                       kfree(notifyee);
+               }
+       }
+
+       kmutex_unlock(&g_smscore_deviceslock);
+}
+EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
+
+static void smscore_notify_clients(struct smscore_device_t *coredev)
+{
+       struct smscore_client_t *client;
+
+       /* the client must call smscore_unregister_client from remove handler */
+       while (!list_empty(&coredev->clients)) {
+               client = (struct smscore_client_t *) coredev->clients.next;
+               client->onremove_handler(client->context);
+       }
+}
+
+static int smscore_notify_callbacks(struct smscore_device_t *coredev,
+                                   struct device *device, int arrival)
+{
+       struct smscore_device_notifyee_t *elem;
+       int rc = 0;
+
+       /* note: must be called under g_deviceslock */
+
+       list_for_each_entry(elem, &g_smscore_notifyees, entry) {
+               rc = elem->hotplug(coredev, device, arrival);
+               if (rc < 0)
+                       break;
+       }
+
+       return rc;
+}
+
+static struct
+smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
+                                      dma_addr_t common_buffer_phys)
+{
+       struct smscore_buffer_t *cb =
+               kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
+       if (!cb) {
+               sms_info("kmalloc(...) failed");
+               return NULL;
+       }
+
+       cb->p = buffer;
+       cb->offset_in_common = buffer - (u8 *) common_buffer;
+       cb->phys = common_buffer_phys + cb->offset_in_common;
+
+       return cb;
+}
+
+/**
+ * creates coredev object for a device, prepares buffers,
+ * creates buffer mappings, notifies registered hotplugs about new device.
+ *
+ * @param params device pointer to struct with device specific parameters
+ *               and handlers
+ * @param coredev pointer to a value that receives created coredev object
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_device(struct smsdevice_params_t *params,
+                           struct smscore_device_t **coredev)
+{
+       struct smscore_device_t *dev;
+       u8 *buffer;
+
+       dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
+       if (!dev) {
+               sms_info("kzalloc(...) failed");
+               return -ENOMEM;
+       }
+
+       /* init list entry so it could be safe in smscore_unregister_device */
+       INIT_LIST_HEAD(&dev->entry);
+
+       /* init queues */
+       INIT_LIST_HEAD(&dev->clients);
+       INIT_LIST_HEAD(&dev->buffers);
+
+       /* init locks */
+       spin_lock_init(&dev->clientslock);
+       spin_lock_init(&dev->bufferslock);
+
+       /* init completion events */
+       init_completion(&dev->version_ex_done);
+       init_completion(&dev->data_download_done);
+       init_completion(&dev->trigger_done);
+       init_completion(&dev->init_device_done);
+       init_completion(&dev->reload_start_done);
+       init_completion(&dev->resume_done);
+       init_completion(&dev->gpio_configuration_done);
+       init_completion(&dev->gpio_set_level_done);
+       init_completion(&dev->gpio_get_level_done);
+       init_completion(&dev->ir_init_done);
+
+       /* Buffer management */
+       init_waitqueue_head(&dev->buffer_mng_waitq);
+
+       /* alloc common buffer */
+       dev->common_buffer_size = params->buffer_size * params->num_buffers;
+       dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
+                                               &dev->common_buffer_phys,
+                                               GFP_KERNEL | GFP_DMA);
+       if (!dev->common_buffer) {
+               smscore_unregister_device(dev);
+               return -ENOMEM;
+       }
+
+       /* prepare dma buffers */
+       for (buffer = dev->common_buffer;
+            dev->num_buffers < params->num_buffers;
+            dev->num_buffers++, buffer += params->buffer_size) {
+               struct smscore_buffer_t *cb =
+                       smscore_createbuffer(buffer, dev->common_buffer,
+                                            dev->common_buffer_phys);
+               if (!cb) {
+                       smscore_unregister_device(dev);
+                       return -ENOMEM;
+               }
+
+               smscore_putbuffer(dev, cb);
+       }
+
+       sms_info("allocated %d buffers", dev->num_buffers);
+
+       dev->mode = DEVICE_MODE_NONE;
+       dev->context = params->context;
+       dev->device = params->device;
+       dev->setmode_handler = params->setmode_handler;
+       dev->detectmode_handler = params->detectmode_handler;
+       dev->sendrequest_handler = params->sendrequest_handler;
+       dev->preload_handler = params->preload_handler;
+       dev->postload_handler = params->postload_handler;
+
+       dev->device_flags = params->flags;
+       strcpy(dev->devpath, params->devpath);
+
+       smscore_registry_settype(dev->devpath, params->device_type);
+
+       /* add device to devices list */
+       kmutex_lock(&g_smscore_deviceslock);
+       list_add(&dev->entry, &g_smscore_devices);
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       *coredev = dev;
+
+       sms_info("device %p created", dev);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(smscore_register_device);
+
+
+static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
+               void *buffer, size_t size, struct completion *completion) {
+       int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
+       if (rc < 0) {
+               sms_info("sendrequest returned error %d", rc);
+               return rc;
+       }
+
+       return wait_for_completion_timeout(completion,
+                       msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
+                       0 : -ETIME;
+}
+
+/**
+ * Starts & enables IR operations
+ *
+ * @return 0 on success, < 0 on error.
+ */
+static int smscore_init_ir(struct smscore_device_t *coredev)
+{
+       int ir_io;
+       int rc;
+       void *buffer;
+
+       coredev->ir.dev = NULL;
+       ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
+       if (ir_io) {/* only if IR port exist we use IR sub-module */
+               sms_info("IR loading");
+               rc = sms_ir_init(coredev);
+
+               if      (rc != 0)
+                       sms_err("Error initialization DTV IR sub-module");
+               else {
+                       buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
+                                               SMS_DMA_ALIGNMENT,
+                                               GFP_KERNEL | GFP_DMA);
+                       if (buffer) {
+                               struct SmsMsgData_ST2 *msg =
+                               (struct SmsMsgData_ST2 *)
+                               SMS_ALIGN_ADDRESS(buffer);
+
+                               SMS_INIT_MSG(&msg->xMsgHeader,
+                                               MSG_SMS_START_IR_REQ,
+                                               sizeof(struct SmsMsgData_ST2));
+                               msg->msgData[0] = coredev->ir.controller;
+                               msg->msgData[1] = coredev->ir.timeout;
+
+                               smsendian_handle_tx_message(
+                                       (struct SmsMsgHdr_ST2 *)msg);
+                               rc = smscore_sendrequest_and_wait(coredev, msg,
+                                               msg->xMsgHeader. msgLength,
+                                               &coredev->ir_init_done);
+
+                               kfree(buffer);
+                       } else
+                               sms_err
+                               ("Sending IR initialization message failed");
+               }
+       } else
+               sms_info("IR port has not been detected");
+
+       return 0;
+}
+
+/**
+ * sets initial device mode and notifies client hotplugs that device is ready
+ *
+ * @param coredev pointer to a coredev object returned by
+ *               smscore_register_device
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_start_device(struct smscore_device_t *coredev)
+{
+       int rc = smscore_set_device_mode(
+                       coredev, smscore_registry_getmode(coredev->devpath));
+       if (rc < 0) {
+               sms_info("set device mode faile , rc %d", rc);
+               return rc;
+       }
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       rc = smscore_notify_callbacks(coredev, coredev->device, 1);
+       smscore_init_ir(coredev);
+
+       sms_info("device %p started, rc %d", coredev, rc);
+
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(smscore_start_device);
+
+
+static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
+                                        void *buffer, size_t size)
+{
+       struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
+       struct SmsMsgHdr_ST *msg;
+       u32 mem_address;
+       u8 *payload = firmware->Payload;
+       int rc = 0;
+       firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
+       firmware->Length = le32_to_cpu(firmware->Length);
+
+       mem_address = firmware->StartAddress;
+
+       sms_info("loading FW to addr 0x%x size %d",
+                mem_address, firmware->Length);
+       if (coredev->preload_handler) {
+               rc = coredev->preload_handler(coredev->context);
+               if (rc < 0)
+                       return rc;
+       }
+
+       /* PAGE_SIZE buffer shall be enough and dma aligned */
+       msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
+       if (!msg)
+               return -ENOMEM;
+
+       if (coredev->mode != DEVICE_MODE_NONE) {
+               sms_debug("sending reload command.");
+               SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
+                            sizeof(struct SmsMsgHdr_ST));
+               rc = smscore_sendrequest_and_wait(coredev, msg,
+                                                 msg->msgLength,
+                                                 &coredev->reload_start_done);
+               mem_address = *(u32 *) &payload[20];
+       }
+
+       while (size && rc >= 0) {
+               struct SmsDataDownload_ST *DataMsg =
+                       (struct SmsDataDownload_ST *) msg;
+               int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
+
+               SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
+                            (u16)(sizeof(struct SmsMsgHdr_ST) +
+                                     sizeof(u32) + payload_size));
+
+               DataMsg->MemAddr = mem_address;
+               memcpy(DataMsg->Payload, payload, payload_size);
+
+               if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
+                   (coredev->mode == DEVICE_MODE_NONE))
+                       rc = coredev->sendrequest_handler(
+                               coredev->context, DataMsg,
+                               DataMsg->xMsgHeader.msgLength);
+               else
+                       rc = smscore_sendrequest_and_wait(
+                               coredev, DataMsg,
+                               DataMsg->xMsgHeader.msgLength,
+                               &coredev->data_download_done);
+
+               payload += payload_size;
+               size -= payload_size;
+               mem_address += payload_size;
+       }
+
+       if (rc >= 0) {
+               if (coredev->mode == DEVICE_MODE_NONE) {
+                       struct SmsMsgData_ST *TriggerMsg =
+                               (struct SmsMsgData_ST *) msg;
+
+                       SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
+                                    sizeof(struct SmsMsgHdr_ST) +
+                                    sizeof(u32) * 5);
+
+                       TriggerMsg->msgData[0] = firmware->StartAddress;
+                                               /* Entry point */
+                       TriggerMsg->msgData[1] = 5; /* Priority */
+                       TriggerMsg->msgData[2] = 0x200; /* Stack size */
+                       TriggerMsg->msgData[3] = 0; /* Parameter */
+                       TriggerMsg->msgData[4] = 4; /* Task ID */
+
+                       if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
+                               rc = coredev->sendrequest_handler(
+                                       coredev->context, TriggerMsg,
+                                       TriggerMsg->xMsgHeader.msgLength);
+                               msleep(100);
+                       } else
+                               rc = smscore_sendrequest_and_wait(
+                                       coredev, TriggerMsg,
+                                       TriggerMsg->xMsgHeader.msgLength,
+                                       &coredev->trigger_done);
+               } else {
+                       SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
+                                    sizeof(struct SmsMsgHdr_ST));
+
+                       rc = coredev->sendrequest_handler(coredev->context,
+                                                         msg, msg->msgLength);
+               }
+               msleep(500);
+       }
+
+       sms_debug("rc=%d, postload=%p ", rc,
+                 coredev->postload_handler);
+
+       kfree(msg);
+
+       return ((rc >= 0) && coredev->postload_handler) ?
+               coredev->postload_handler(coredev->context) :
+               rc;
+}
+
+/**
+ * loads specified firmware into a buffer and calls device loadfirmware_handler
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param filename null-terminated string specifies firmware file name
+ * @param loadfirmware_handler device handler that loads firmware
+ *
+ * @return 0 on success, <0 on error.
+ */
+static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
+                                          char *filename,
+                                          loadfirmware_t loadfirmware_handler)
+{
+       int rc = -ENOENT;
+       const struct firmware *fw;
+       u8 *fw_buffer;
+
+       if (loadfirmware_handler == NULL && !(coredev->device_flags &
+                                             SMS_DEVICE_FAMILY2))
+               return -EINVAL;
+
+       rc = request_firmware(&fw, filename, coredev->device);
+       if (rc < 0) {
+               sms_info("failed to open \"%s\"", filename);
+               return rc;
+       }
+       sms_info("read FW %s, size=%zd", filename, fw->size);
+       fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
+                           GFP_KERNEL | GFP_DMA);
+       if (fw_buffer) {
+               memcpy(fw_buffer, fw->data, fw->size);
+
+               rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
+                     smscore_load_firmware_family2(coredev,
+                                                   fw_buffer,
+                                                   fw->size) :
+                     loadfirmware_handler(coredev->context,
+                                          fw_buffer, fw->size);
+
+               kfree(fw_buffer);
+       } else {
+               sms_info("failed to allocate firmware buffer");
+               rc = -ENOMEM;
+       }
+
+       release_firmware(fw);
+
+       return rc;
+}
+
+/**
+ * notifies all clients registered with the device, notifies hotplugs,
+ * frees all buffers and coredev object
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ *
+ * @return 0 on success, <0 on error.
+ */
+void smscore_unregister_device(struct smscore_device_t *coredev)
+{
+       struct smscore_buffer_t *cb;
+       int num_buffers = 0;
+       int retry = 0;
+
+       kmutex_lock(&g_smscore_deviceslock);
+
+       /* Release input device (IR) resources */
+       sms_ir_exit(coredev);
+
+       smscore_notify_clients(coredev);
+       smscore_notify_callbacks(coredev, NULL, 0);
+
+       /* at this point all buffers should be back
+        * onresponse must no longer be called */
+
+       while (1) {
+               while (!list_empty(&coredev->buffers)) {
+                       cb = (struct smscore_buffer_t *) coredev->buffers.next;
+                       list_del(&cb->entry);
+                       kfree(cb);
+                       num_buffers++;
+               }
+               if (num_buffers == coredev->num_buffers)
+                       break;
+               if (++retry > 10) {
+                       sms_info("exiting although "
+                                "not all buffers released.");
+                       break;
+               }
+
+               sms_info("waiting for %d buffer(s)",
+                        coredev->num_buffers - num_buffers);
+               msleep(100);
+       }
+
+       sms_info("freed %d buffers", num_buffers);
+
+       if (coredev->common_buffer)
+               dma_free_coherent(NULL, coredev->common_buffer_size,
+                       coredev->common_buffer, coredev->common_buffer_phys);
+
+       if (coredev->fw_buf != NULL)
+               kfree(coredev->fw_buf);
+
+       list_del(&coredev->entry);
+       kfree(coredev);
+
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       sms_info("device %p destroyed", coredev);
+}
+EXPORT_SYMBOL_GPL(smscore_unregister_device);
+
+static int smscore_detect_mode(struct smscore_device_t *coredev)
+{
+       void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
+                              GFP_KERNEL | GFP_DMA);
+       struct SmsMsgHdr_ST *msg =
+               (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
+       int rc;
+
+       if (!buffer)
+               return -ENOMEM;
+
+       SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
+                    sizeof(struct SmsMsgHdr_ST));
+
+       rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
+                                         &coredev->version_ex_done);
+       if (rc == -ETIME) {
+               sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
+
+               if (wait_for_completion_timeout(&coredev->resume_done,
+                                               msecs_to_jiffies(5000))) {
+                       rc = smscore_sendrequest_and_wait(
+                               coredev, msg, msg->msgLength,
+                               &coredev->version_ex_done);
+                       if (rc < 0)
+                               sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
+                                       "second try, rc %d", rc);
+               } else
+                       rc = -ETIME;
+       }
+
+       kfree(buffer);
+
+       return rc;
+}
+
+static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
+       /*Stellar               NOVA A0         Nova B0         VEGA*/
+       /*DVBT*/
+       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
+       /*DVBH*/
+       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
+       /*TDMB*/
+       {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
+       /*DABIP*/
+       {"none", "none", "none", "none"},
+       /*BDA*/
+       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
+       /*ISDBT*/
+       {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
+       /*ISDBTBDA*/
+       {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
+       /*CMMB*/
+       {"none", "none", "none", "cmmb_vega_12mhz.inp"}
+};
+
+static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
+                                   int mode, enum sms_device_type_st type)
+{
+       char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
+       return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
+}
+
+/**
+ * calls device handler to change mode of operation
+ * NOTE: stellar/usb may disconnect when changing mode
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param mode requested mode of operation
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
+{
+       void *buffer;
+       int rc = 0;
+       enum sms_device_type_st type;
+
+       sms_debug("set device mode to %d", mode);
+       if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
+               if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
+                       sms_err("invalid mode specified %d", mode);
+                       return -EINVAL;
+               }
+
+               smscore_registry_setmode(coredev->devpath, mode);
+
+               if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
+                       rc = smscore_detect_mode(coredev);
+                       if (rc < 0) {
+                               sms_err("mode detect failed %d", rc);
+                               return rc;
+                       }
+               }
+
+               if (coredev->mode == mode) {
+                       sms_info("device mode %d already set", mode);
+                       return 0;
+               }
+
+               if (!(coredev->modes_supported & (1 << mode))) {
+                       char *fw_filename;
+
+                       type = smscore_registry_gettype(coredev->devpath);
+                       fw_filename = sms_get_fw_name(coredev, mode, type);
+
+                       rc = smscore_load_firmware_from_file(coredev,
+                                                            fw_filename, NULL);
+                       if (rc < 0) {
+                               sms_warn("error %d loading firmware: %s, "
+                                        "trying again with default firmware",
+                                        rc, fw_filename);
+
+                               /* try again with the default firmware */
+                               fw_filename = smscore_fw_lkup[mode][type];
+                               rc = smscore_load_firmware_from_file(coredev,
+                                                            fw_filename, NULL);
+
+                               if (rc < 0) {
+                                       sms_warn("error %d loading "
+                                                "firmware: %s", rc,
+                                                fw_filename);
+                                       return rc;
+                               }
+                       }
+                       sms_log("firmware download success: %s", fw_filename);
+               } else
+                       sms_info("mode %d supported by running "
+                                "firmware", mode);
+
+               buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
+                                SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
+               if (buffer) {
+                       struct SmsMsgData_ST *msg =
+                               (struct SmsMsgData_ST *)
+                                       SMS_ALIGN_ADDRESS(buffer);
+
+                       SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
+                                    sizeof(struct SmsMsgData_ST));
+                       msg->msgData[0] = mode;
+
+                       rc = smscore_sendrequest_and_wait(
+                               coredev, msg, msg->xMsgHeader.msgLength,
+                               &coredev->init_device_done);
+
+                       kfree(buffer);
+               } else {
+                       sms_err("Could not allocate buffer for "
+                               "init device message.");
+                       rc = -ENOMEM;
+               }
+       } else {
+               if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
+                       sms_err("invalid mode specified %d", mode);
+                       return -EINVAL;
+               }
+
+               smscore_registry_setmode(coredev->devpath, mode);
+
+               if (coredev->detectmode_handler)
+                       coredev->detectmode_handler(coredev->context,
+                                                   &coredev->mode);
+
+               if (coredev->mode != mode && coredev->setmode_handler)
+                       rc = coredev->setmode_handler(coredev->context, mode);
+       }
+
+       if (rc >= 0) {
+               coredev->mode = mode;
+               coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
+       }
+
+       if (rc < 0)
+               sms_err("return error code %d.", rc);
+       return rc;
+}
+
+/**
+ * calls device handler to get current mode of operation
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ *
+ * @return current mode
+ */
+int smscore_get_device_mode(struct smscore_device_t *coredev)
+{
+       return coredev->mode;
+}
+EXPORT_SYMBOL_GPL(smscore_get_device_mode);
+
+/**
+ * find client by response id & type within the clients list.
+ * return client handle or NULL.
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param data_type client data type (SMS_DONT_CARE for all types)
+ * @param id client id (SMS_DONT_CARE for all id)
+ *
+ */
+static struct
+smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
+                                     int data_type, int id)
+{
+       struct list_head *first;
+       struct smscore_client_t *client;
+       unsigned long flags;
+       struct list_head *firstid;
+       struct smscore_idlist_t *client_id;
+
+       spin_lock_irqsave(&coredev->clientslock, flags);
+       first = &coredev->clients;
+       list_for_each_entry(client, first, entry) {
+               firstid = &client->idlist;
+               list_for_each_entry(client_id, firstid, entry) {
+                       if ((client_id->id == id) &&
+                           (client_id->data_type == data_type ||
+                           (client_id->data_type == 0)))
+                               goto found;
+               }
+       }
+       client = NULL;
+found:
+       spin_unlock_irqrestore(&coredev->clientslock, flags);
+       return client;
+}
+
+/**
+ * find client by response id/type, call clients onresponse handler
+ * return buffer to pool on error
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param cb pointer to response buffer descriptor
+ *
+ */
+void smscore_onresponse(struct smscore_device_t *coredev,
+               struct smscore_buffer_t *cb) {
+       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
+                       + cb->offset);
+       struct smscore_client_t *client;
+       int rc = -EBUSY;
+       static unsigned long last_sample_time; /* = 0; */
+       static int data_total; /* = 0; */
+       unsigned long time_now = jiffies_to_msecs(jiffies);
+
+       if (!last_sample_time)
+               last_sample_time = time_now;
+
+       if (time_now - last_sample_time > 10000) {
+               sms_debug("\ndata rate %d bytes/secs",
+                         (int)((data_total * 1000) /
+                               (time_now - last_sample_time)));
+
+               last_sample_time = time_now;
+               data_total = 0;
+       }
+
+       data_total += cb->size;
+       /* Do we need to re-route? */
+       if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
+                       (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
+               if (coredev->mode == DEVICE_MODE_DVBT_BDA)
+                       phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
+       }
+
+
+       client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
+
+       /* If no client registered for type & id,
+        * check for control client where type is not registered */
+       if (client)
+               rc = client->onresponse_handler(client->context, cb);
+
+       if (rc < 0) {
+               switch (phdr->msgType) {
+               case MSG_SMS_GET_VERSION_EX_RES:
+               {
+                       struct SmsVersionRes_ST *ver =
+                               (struct SmsVersionRes_ST *) phdr;
+                       sms_debug("MSG_SMS_GET_VERSION_EX_RES "
+                                 "id %d prots 0x%x ver %d.%d",
+                                 ver->FirmwareId, ver->SupportedProtocols,
+                                 ver->RomVersionMajor, ver->RomVersionMinor);
+
+                       coredev->mode = ver->FirmwareId == 255 ?
+                               DEVICE_MODE_NONE : ver->FirmwareId;
+                       coredev->modes_supported = ver->SupportedProtocols;
+
+                       complete(&coredev->version_ex_done);
+                       break;
+               }
+               case MSG_SMS_INIT_DEVICE_RES:
+                       sms_debug("MSG_SMS_INIT_DEVICE_RES");
+                       complete(&coredev->init_device_done);
+                       break;
+               case MSG_SW_RELOAD_START_RES:
+                       sms_debug("MSG_SW_RELOAD_START_RES");
+                       complete(&coredev->reload_start_done);
+                       break;
+               case MSG_SMS_DATA_DOWNLOAD_RES:
+                       complete(&coredev->data_download_done);
+                       break;
+               case MSG_SW_RELOAD_EXEC_RES:
+                       sms_debug("MSG_SW_RELOAD_EXEC_RES");
+                       break;
+               case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
+                       sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
+                       complete(&coredev->trigger_done);
+                       break;
+               case MSG_SMS_SLEEP_RESUME_COMP_IND:
+                       complete(&coredev->resume_done);
+                       break;
+               case MSG_SMS_GPIO_CONFIG_EX_RES:
+                       sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
+                       complete(&coredev->gpio_configuration_done);
+                       break;
+               case MSG_SMS_GPIO_SET_LEVEL_RES:
+                       sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
+                       complete(&coredev->gpio_set_level_done);
+                       break;
+               case MSG_SMS_GPIO_GET_LEVEL_RES:
+               {
+                       u32 *msgdata = (u32 *) phdr;
+                       coredev->gpio_get_res = msgdata[1];
+                       sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
+                                       coredev->gpio_get_res);
+                       complete(&coredev->gpio_get_level_done);
+                       break;
+               }
+               case MSG_SMS_START_IR_RES:
+                       complete(&coredev->ir_init_done);
+                       break;
+               case MSG_SMS_IR_SAMPLES_IND:
+                       sms_ir_event(coredev,
+                               (const char *)
+                               ((char *)phdr
+                               + sizeof(struct SmsMsgHdr_ST)),
+                               (int)phdr->msgLength
+                               - sizeof(struct SmsMsgHdr_ST));
+                       break;
+
+               default:
+                       break;
+               }
+               smscore_putbuffer(coredev, cb);
+       }
+}
+EXPORT_SYMBOL_GPL(smscore_onresponse);
+
+/**
+ * return pointer to next free buffer descriptor from core pool
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ *
+ * @return pointer to descriptor on success, NULL on error.
+ */
+
+struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
+{
+       struct smscore_buffer_t *cb = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&coredev->bufferslock, flags);
+       if (!list_empty(&coredev->buffers)) {
+               cb = (struct smscore_buffer_t *) coredev->buffers.next;
+               list_del(&cb->entry);
+       }
+       spin_unlock_irqrestore(&coredev->bufferslock, flags);
+       return cb;
+}
+
+struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
+{
+       struct smscore_buffer_t *cb = NULL;
+
+       wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
+
+       return cb;
+}
+EXPORT_SYMBOL_GPL(smscore_getbuffer);
+
+/**
+ * return buffer descriptor to a pool
+ *
+ * @param coredev pointer to a coredev object returned by
+ *                smscore_register_device
+ * @param cb pointer buffer descriptor
+ *
+ */
+void smscore_putbuffer(struct smscore_device_t *coredev,
+               struct smscore_buffer_t *cb) {
+       wake_up_interruptible(&coredev->buffer_mng_waitq);
+       list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
+}
+EXPORT_SYMBOL_GPL(smscore_putbuffer);
+
+static int smscore_validate_client(struct smscore_device_t *coredev,
+                                  struct smscore_client_t *client,
+                                  int data_type, int id)
+{
+       struct smscore_idlist_t *listentry;
+       struct smscore_client_t *registered_client;
+
+       if (!client) {
+               sms_err("bad parameter.");
+               return -EINVAL;
+       }
+       registered_client = smscore_find_client(coredev, data_type, id);
+       if (registered_client == client)
+               return 0;
+
+       if (registered_client) {
+               sms_err("The msg ID already registered to another client.");
+               return -EEXIST;
+       }
+       listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
+       if (!listentry) {
+               sms_err("Can't allocate memory for client id.");
+               return -ENOMEM;
+       }
+       listentry->id = id;
+       listentry->data_type = data_type;
+       list_add_locked(&listentry->entry, &client->idlist,
+                       &coredev->clientslock);
+       return 0;
+}
+
+/**
+ * creates smsclient object, check that id is taken by another client
+ *
+ * @param coredev pointer to a coredev object from clients hotplug
+ * @param initial_id all messages with this id would be sent to this client
+ * @param data_type all messages of this type would be sent to this client
+ * @param onresponse_handler client handler that is called to
+ *                           process incoming messages
+ * @param onremove_handler client handler that is called when device is removed
+ * @param context client-specific context
+ * @param client pointer to a value that receives created smsclient object
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_client(struct smscore_device_t *coredev,
+                           struct smsclient_params_t *params,
+                           struct smscore_client_t **client)
+{
+       struct smscore_client_t *newclient;
+       /* check that no other channel with same parameters exists */
+       if (smscore_find_client(coredev, params->data_type,
+                               params->initial_id)) {
+               sms_err("Client already exist.");
+               return -EEXIST;
+       }
+
+       newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
+       if (!newclient) {
+               sms_err("Failed to allocate memory for client.");
+               return -ENOMEM;
+       }
+
+       INIT_LIST_HEAD(&newclient->idlist);
+       newclient->coredev = coredev;
+       newclient->onresponse_handler = params->onresponse_handler;
+       newclient->onremove_handler = params->onremove_handler;
+       newclient->context = params->context;
+       list_add_locked(&newclient->entry, &coredev->clients,
+                       &coredev->clientslock);
+       smscore_validate_client(coredev, newclient, params->data_type,
+                               params->initial_id);
+       *client = newclient;
+       sms_debug("%p %d %d", params->context, params->data_type,
+                 params->initial_id);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(smscore_register_client);
+
+/**
+ * frees smsclient object and all subclients associated with it
+ *
+ * @param client pointer to smsclient object returned by
+ *               smscore_register_client
+ *
+ */
+void smscore_unregister_client(struct smscore_client_t *client)
+{
+       struct smscore_device_t *coredev = client->coredev;
+       unsigned long flags;
+
+       spin_lock_irqsave(&coredev->clientslock, flags);
+
+
+       while (!list_empty(&client->idlist)) {
+               struct smscore_idlist_t *identry =
+                       (struct smscore_idlist_t *) client->idlist.next;
+               list_del(&identry->entry);
+               kfree(identry);
+       }
+
+       sms_info("%p", client->context);
+
+       list_del(&client->entry);
+       kfree(client);
+
+       spin_unlock_irqrestore(&coredev->clientslock, flags);
+}
+EXPORT_SYMBOL_GPL(smscore_unregister_client);
+
+/**
+ * verifies that source id is not taken by another client,
+ * calls device handler to send requests to the device
+ *
+ * @param client pointer to smsclient object returned by
+ *               smscore_register_client
+ * @param buffer pointer to a request buffer
+ * @param size size (in bytes) of request buffer
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smsclient_sendrequest(struct smscore_client_t *client,
+                         void *buffer, size_t size)
+{
+       struct smscore_device_t *coredev;
+       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
+       int rc;
+
+       if (client == NULL) {
+               sms_err("Got NULL client");
+               return -EINVAL;
+       }
+
+       coredev = client->coredev;
+
+       /* check that no other channel with same id exists */
+       if (coredev == NULL) {
+               sms_err("Got NULL coredev");
+               return -EINVAL;
+       }
+
+       rc = smscore_validate_client(client->coredev, client, 0,
+                                    phdr->msgSrcId);
+       if (rc < 0)
+               return rc;
+
+       return coredev->sendrequest_handler(coredev->context, buffer, size);
+}
+EXPORT_SYMBOL_GPL(smsclient_sendrequest);
+
+
+/* old GPIO managements implementation */
+int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
+                          struct smscore_config_gpio *pinconfig)
+{
+       struct {
+               struct SmsMsgHdr_ST hdr;
+               u32 data[6];
+       } msg;
+
+       if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
+               msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+               msg.hdr.msgDstId = HIF_TASK;
+               msg.hdr.msgFlags = 0;
+               msg.hdr.msgType  = MSG_SMS_GPIO_CONFIG_EX_REQ;
+               msg.hdr.msgLength = sizeof(msg);
+
+               msg.data[0] = pin;
+               msg.data[1] = pinconfig->pullupdown;
+
+               /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
+               msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
+
+               switch (pinconfig->outputdriving) {
+               case SMS_GPIO_OUTPUTDRIVING_16mA:
+                       msg.data[3] = 7; /* Nova - 16mA */
+                       break;
+               case SMS_GPIO_OUTPUTDRIVING_12mA:
+                       msg.data[3] = 5; /* Nova - 11mA */
+                       break;
+               case SMS_GPIO_OUTPUTDRIVING_8mA:
+                       msg.data[3] = 3; /* Nova - 7mA */
+                       break;
+               case SMS_GPIO_OUTPUTDRIVING_4mA:
+               default:
+                       msg.data[3] = 2; /* Nova - 4mA */
+                       break;
+               }
+
+               msg.data[4] = pinconfig->direction;
+               msg.data[5] = 0;
+       } else /* TODO: SMS_DEVICE_FAMILY1 */
+               return -EINVAL;
+
+       return coredev->sendrequest_handler(coredev->context,
+                                           &msg, sizeof(msg));
+}
+
+int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
+{
+       struct {
+               struct SmsMsgHdr_ST hdr;
+               u32 data[3];
+       } msg;
+
+       if (pin > MAX_GPIO_PIN_NUMBER)
+               return -EINVAL;
+
+       msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       msg.hdr.msgDstId = HIF_TASK;
+       msg.hdr.msgFlags = 0;
+       msg.hdr.msgType  = MSG_SMS_GPIO_SET_LEVEL_REQ;
+       msg.hdr.msgLength = sizeof(msg);
+
+       msg.data[0] = pin;
+       msg.data[1] = level ? 1 : 0;
+       msg.data[2] = 0;
+
+       return coredev->sendrequest_handler(coredev->context,
+                                           &msg, sizeof(msg));
+}
+
+/* new GPIO management implementation */
+static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
+               u32 *pGroupNum, u32 *pGroupCfg) {
+
+       *pGroupCfg = 1;
+
+       if (PinNum <= 1)        {
+               *pTranslatedPinNum = 0;
+               *pGroupNum = 9;
+               *pGroupCfg = 2;
+       } else if (PinNum >= 2 && PinNum <= 6) {
+               *pTranslatedPinNum = 2;
+               *pGroupNum = 0;
+               *pGroupCfg = 2;
+       } else if (PinNum >= 7 && PinNum <= 11) {
+               *pTranslatedPinNum = 7;
+               *pGroupNum = 1;
+       } else if (PinNum >= 12 && PinNum <= 15) {
+               *pTranslatedPinNum = 12;
+               *pGroupNum = 2;
+               *pGroupCfg = 3;
+       } else if (PinNum == 16) {
+               *pTranslatedPinNum = 16;
+               *pGroupNum = 23;
+       } else if (PinNum >= 17 && PinNum <= 24) {
+               *pTranslatedPinNum = 17;
+               *pGroupNum = 3;
+       } else if (PinNum == 25) {
+               *pTranslatedPinNum = 25;
+               *pGroupNum = 6;
+       } else if (PinNum >= 26 && PinNum <= 28) {
+               *pTranslatedPinNum = 26;
+               *pGroupNum = 4;
+       } else if (PinNum == 29) {
+               *pTranslatedPinNum = 29;
+               *pGroupNum = 5;
+               *pGroupCfg = 2;
+       } else if (PinNum == 30) {
+               *pTranslatedPinNum = 30;
+               *pGroupNum = 8;
+       } else if (PinNum == 31) {
+               *pTranslatedPinNum = 31;
+               *pGroupNum = 17;
+       } else
+               return -1;
+
+       *pGroupCfg <<= 24;
+
+       return 0;
+}
+
+int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
+               struct smscore_gpio_config *pGpioConfig) {
+
+       u32 totalLen;
+       u32 TranslatedPinNum = 0;
+       u32 GroupNum = 0;
+       u32 ElectricChar;
+       u32 groupCfg;
+       void *buffer;
+       int rc;
+
+       struct SetGpioMsg {
+               struct SmsMsgHdr_ST xMsgHeader;
+               u32 msgData[6];
+       } *pMsg;
+
+
+       if (PinNum > MAX_GPIO_PIN_NUMBER)
+               return -EINVAL;
+
+       if (pGpioConfig == NULL)
+               return -EINVAL;
+
+       totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
+
+       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+                       GFP_KERNEL | GFP_DMA);
+       if (!buffer)
+               return -ENOMEM;
+
+       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+
+       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       pMsg->xMsgHeader.msgDstId = HIF_TASK;
+       pMsg->xMsgHeader.msgFlags = 0;
+       pMsg->xMsgHeader.msgLength = (u16) totalLen;
+       pMsg->msgData[0] = PinNum;
+
+       if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
+               pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
+               if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
+                               &groupCfg) != 0) {
+                       rc = -EINVAL;
+                       goto free;
+               }
+
+               pMsg->msgData[1] = TranslatedPinNum;
+               pMsg->msgData[2] = GroupNum;
+               ElectricChar = (pGpioConfig->PullUpDown)
+                               | (pGpioConfig->InputCharacteristics << 2)
+                               | (pGpioConfig->OutputSlewRate << 3)
+                               | (pGpioConfig->OutputDriving << 4);
+               pMsg->msgData[3] = ElectricChar;
+               pMsg->msgData[4] = pGpioConfig->Direction;
+               pMsg->msgData[5] = groupCfg;
+       } else {
+               pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
+               pMsg->msgData[1] = pGpioConfig->PullUpDown;
+               pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
+               pMsg->msgData[3] = pGpioConfig->OutputDriving;
+               pMsg->msgData[4] = pGpioConfig->Direction;
+               pMsg->msgData[5] = 0;
+       }
+
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
+       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+                       &coredev->gpio_configuration_done);
+
+       if (rc != 0) {
+               if (rc == -ETIME)
+                       sms_err("smscore_gpio_configure timeout");
+               else
+                       sms_err("smscore_gpio_configure error");
+       }
+free:
+       kfree(buffer);
+
+       return rc;
+}
+
+int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
+               u8 NewLevel) {
+
+       u32 totalLen;
+       int rc;
+       void *buffer;
+
+       struct SetGpioMsg {
+               struct SmsMsgHdr_ST xMsgHeader;
+               u32 msgData[3]; /* keep it 3 ! */
+       } *pMsg;
+
+       if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER))
+               return -EINVAL;
+
+       totalLen = sizeof(struct SmsMsgHdr_ST) +
+                       (3 * sizeof(u32)); /* keep it 3 ! */
+
+       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+                       GFP_KERNEL | GFP_DMA);
+       if (!buffer)
+               return -ENOMEM;
+
+       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+
+       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       pMsg->xMsgHeader.msgDstId = HIF_TASK;
+       pMsg->xMsgHeader.msgFlags = 0;
+       pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
+       pMsg->xMsgHeader.msgLength = (u16) totalLen;
+       pMsg->msgData[0] = PinNum;
+       pMsg->msgData[1] = NewLevel;
+
+       /* Send message to SMS */
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
+       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+                       &coredev->gpio_set_level_done);
+
+       if (rc != 0) {
+               if (rc == -ETIME)
+                       sms_err("smscore_gpio_set_level timeout");
+               else
+                       sms_err("smscore_gpio_set_level error");
+       }
+       kfree(buffer);
+
+       return rc;
+}
+
+int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
+               u8 *level) {
+
+       u32 totalLen;
+       int rc;
+       void *buffer;
+
+       struct SetGpioMsg {
+               struct SmsMsgHdr_ST xMsgHeader;
+               u32 msgData[2];
+       } *pMsg;
+
+
+       if (PinNum > MAX_GPIO_PIN_NUMBER)
+               return -EINVAL;
+
+       totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
+
+       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+                       GFP_KERNEL | GFP_DMA);
+       if (!buffer)
+               return -ENOMEM;
+
+       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+
+       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       pMsg->xMsgHeader.msgDstId = HIF_TASK;
+       pMsg->xMsgHeader.msgFlags = 0;
+       pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
+       pMsg->xMsgHeader.msgLength = (u16) totalLen;
+       pMsg->msgData[0] = PinNum;
+       pMsg->msgData[1] = 0;
+
+       /* Send message to SMS */
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
+       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+                       &coredev->gpio_get_level_done);
+
+       if (rc != 0) {
+               if (rc == -ETIME)
+                       sms_err("smscore_gpio_get_level timeout");
+               else
+                       sms_err("smscore_gpio_get_level error");
+       }
+       kfree(buffer);
+
+       /* Its a race between other gpio_get_level() and the copy of the single
+        * global 'coredev->gpio_get_res' to  the function's variable 'level'
+        */
+       *level = coredev->gpio_get_res;
+
+       return rc;
+}
+
+static int __init smscore_module_init(void)
+{
+       int rc = 0;
+
+       INIT_LIST_HEAD(&g_smscore_notifyees);
+       INIT_LIST_HEAD(&g_smscore_devices);
+       kmutex_init(&g_smscore_deviceslock);
+
+       INIT_LIST_HEAD(&g_smscore_registry);
+       kmutex_init(&g_smscore_registrylock);
+
+       return rc;
+}
+
+static void __exit smscore_module_exit(void)
+{
+       kmutex_lock(&g_smscore_deviceslock);
+       while (!list_empty(&g_smscore_notifyees)) {
+               struct smscore_device_notifyee_t *notifyee =
+                       (struct smscore_device_notifyee_t *)
+                               g_smscore_notifyees.next;
+
+               list_del(&notifyee->entry);
+               kfree(notifyee);
+       }
+       kmutex_unlock(&g_smscore_deviceslock);
+
+       kmutex_lock(&g_smscore_registrylock);
+       while (!list_empty(&g_smscore_registry)) {
+               struct smscore_registry_entry_t *entry =
+                       (struct smscore_registry_entry_t *)
+                               g_smscore_registry.next;
+
+               list_del(&entry->entry);
+               kfree(entry);
+       }
+       kmutex_unlock(&g_smscore_registrylock);
+
+       sms_debug("");
+}
+
+module_init(smscore_module_init);
+module_exit(smscore_module_exit);
+
+MODULE_DESCRIPTION("Siano MDTV Core module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h
new file mode 100644 (file)
index 0000000..c592ae0
--- /dev/null
@@ -0,0 +1,775 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#ifndef __SMS_CORE_API_H__
+#define __SMS_CORE_API_H__
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/timer.h>
+
+#include <asm/page.h>
+
+#include "smsir.h"
+
+#define kmutex_init(_p_) mutex_init(_p_)
+#define kmutex_lock(_p_) mutex_lock(_p_)
+#define kmutex_trylock(_p_) mutex_trylock(_p_)
+#define kmutex_unlock(_p_) mutex_unlock(_p_)
+
+#ifndef min
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS                 (10000)
+#define SMS_ALLOC_ALIGNMENT                            128
+#define SMS_DMA_ALIGNMENT                              16
+#define SMS_ALIGN_ADDRESS(addr) \
+       ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
+
+#define SMS_DEVICE_FAMILY2                             1
+#define SMS_ROM_NO_RESPONSE                            2
+#define SMS_DEVICE_NOT_READY                           0x8000000
+
+enum sms_device_type_st {
+       SMS_STELLAR = 0,
+       SMS_NOVA_A0,
+       SMS_NOVA_B0,
+       SMS_VEGA,
+       SMS_NUM_OF_DEVICE_TYPES
+};
+
+struct smscore_device_t;
+struct smscore_client_t;
+struct smscore_buffer_t;
+
+typedef int (*hotplug_t)(struct smscore_device_t *coredev,
+                        struct device *device, int arrival);
+
+typedef int (*setmode_t)(void *context, int mode);
+typedef void (*detectmode_t)(void *context, int *mode);
+typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
+typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
+typedef int (*preload_t)(void *context);
+typedef int (*postload_t)(void *context);
+
+typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
+typedef void (*onremove_t)(void *context);
+
+struct smscore_buffer_t {
+       /* public members, once passed to clients can be changed freely */
+       struct list_head entry;
+       int size;
+       int offset;
+
+       /* private members, read-only for clients */
+       void *p;
+       dma_addr_t phys;
+       unsigned long offset_in_common;
+};
+
+struct smsdevice_params_t {
+       struct device   *device;
+
+       int                             buffer_size;
+       int                             num_buffers;
+
+       char                    devpath[32];
+       unsigned long   flags;
+
+       setmode_t               setmode_handler;
+       detectmode_t    detectmode_handler;
+       sendrequest_t   sendrequest_handler;
+       preload_t               preload_handler;
+       postload_t              postload_handler;
+
+       void                    *context;
+       enum sms_device_type_st device_type;
+};
+
+struct smsclient_params_t {
+       int                             initial_id;
+       int                             data_type;
+       onresponse_t    onresponse_handler;
+       onremove_t              onremove_handler;
+       void                    *context;
+};
+
+struct smscore_device_t {
+       struct list_head entry;
+
+       struct list_head clients;
+       struct list_head subclients;
+       spinlock_t clientslock;
+
+       struct list_head buffers;
+       spinlock_t bufferslock;
+       int num_buffers;
+
+       void *common_buffer;
+       int common_buffer_size;
+       dma_addr_t common_buffer_phys;
+
+       void *context;
+       struct device *device;
+
+       char devpath[32];
+       unsigned long device_flags;
+
+       setmode_t setmode_handler;
+       detectmode_t detectmode_handler;
+       sendrequest_t sendrequest_handler;
+       preload_t preload_handler;
+       postload_t postload_handler;
+
+       int mode, modes_supported;
+
+       /* host <--> device messages */
+       struct completion version_ex_done, data_download_done, trigger_done;
+       struct completion init_device_done, reload_start_done, resume_done;
+       struct completion gpio_configuration_done, gpio_set_level_done;
+       struct completion gpio_get_level_done, ir_init_done;
+
+       /* Buffer management */
+       wait_queue_head_t buffer_mng_waitq;
+
+       /* GPIO */
+       int gpio_get_res;
+
+       /* Target hardware board */
+       int board_id;
+
+       /* Firmware */
+       u8 *fw_buf;
+       u32 fw_buf_size;
+
+       /* Infrared (IR) */
+       struct ir_t ir;
+
+       int led_state;
+};
+
+/* GPIO definitions for antenna frequency domain control (SMS8021) */
+#define SMS_ANTENNA_GPIO_0                                     1
+#define SMS_ANTENNA_GPIO_1                                     0
+
+#define BW_8_MHZ                                                       0
+#define BW_7_MHZ                                                       1
+#define BW_6_MHZ                                                       2
+#define BW_5_MHZ                                                       3
+#define BW_ISDBT_1SEG                                          4
+#define BW_ISDBT_3SEG                                          5
+
+#define MSG_HDR_FLAG_SPLIT_MSG                         4
+
+#define MAX_GPIO_PIN_NUMBER                                    31
+
+#define HIF_TASK                                                       11
+#define SMS_HOST_LIB                                           150
+#define DVBT_BDA_CONTROL_MSG_ID                                201
+
+#define SMS_MAX_PAYLOAD_SIZE                           240
+#define SMS_TUNE_TIMEOUT                                       500
+
+#define MSG_SMS_GPIO_CONFIG_REQ                                507
+#define MSG_SMS_GPIO_CONFIG_RES                                508
+#define MSG_SMS_GPIO_SET_LEVEL_REQ                     509
+#define MSG_SMS_GPIO_SET_LEVEL_RES                     510
+#define MSG_SMS_GPIO_GET_LEVEL_REQ                     511
+#define MSG_SMS_GPIO_GET_LEVEL_RES                     512
+#define MSG_SMS_RF_TUNE_REQ                                    561
+#define MSG_SMS_RF_TUNE_RES                                    562
+#define MSG_SMS_INIT_DEVICE_REQ                                578
+#define MSG_SMS_INIT_DEVICE_RES                                579
+#define MSG_SMS_ADD_PID_FILTER_REQ                     601
+#define MSG_SMS_ADD_PID_FILTER_RES                     602
+#define MSG_SMS_REMOVE_PID_FILTER_REQ                  603
+#define MSG_SMS_REMOVE_PID_FILTER_RES                  604
+#define MSG_SMS_DAB_CHANNEL                            607
+#define MSG_SMS_GET_PID_FILTER_LIST_REQ                        608
+#define MSG_SMS_GET_PID_FILTER_LIST_RES                        609
+#define MSG_SMS_GET_STATISTICS_RES                     616
+#define MSG_SMS_GET_STATISTICS_REQ                     615
+#define MSG_SMS_HO_PER_SLICES_IND                      630
+#define MSG_SMS_SET_ANTENNA_CONFIG_REQ                 651
+#define MSG_SMS_SET_ANTENNA_CONFIG_RES                 652
+#define MSG_SMS_SLEEP_RESUME_COMP_IND                  655
+#define MSG_SMS_DATA_DOWNLOAD_REQ                      660
+#define MSG_SMS_DATA_DOWNLOAD_RES                      661
+#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ         664
+#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES         665
+#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ                666
+#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES                667
+#define MSG_SMS_GET_VERSION_EX_REQ                     668
+#define MSG_SMS_GET_VERSION_EX_RES                     669
+#define MSG_SMS_SET_CLOCK_OUTPUT_REQ           670
+#define MSG_SMS_I2C_SET_FREQ_REQ                       685
+#define MSG_SMS_GENERIC_I2C_REQ                                687
+#define MSG_SMS_GENERIC_I2C_RES                                688
+#define MSG_SMS_DVBT_BDA_DATA                          693
+#define MSG_SW_RELOAD_REQ                                      697
+#define MSG_SMS_DATA_MSG                                       699
+#define MSG_SW_RELOAD_START_REQ                                702
+#define MSG_SW_RELOAD_START_RES                                703
+#define MSG_SW_RELOAD_EXEC_REQ                         704
+#define MSG_SW_RELOAD_EXEC_RES                         705
+#define MSG_SMS_SPI_INT_LINE_SET_REQ           710
+#define MSG_SMS_GPIO_CONFIG_EX_REQ                     712
+#define MSG_SMS_GPIO_CONFIG_EX_RES                     713
+#define MSG_SMS_ISDBT_TUNE_REQ                         776
+#define MSG_SMS_ISDBT_TUNE_RES                         777
+#define MSG_SMS_TRANSMISSION_IND                       782
+#define MSG_SMS_START_IR_REQ                           800
+#define MSG_SMS_START_IR_RES                           801
+#define MSG_SMS_IR_SAMPLES_IND                         802
+#define MSG_SMS_SIGNAL_DETECTED_IND                    827
+#define MSG_SMS_NO_SIGNAL_IND                          828
+
+#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
+       (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
+       (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
+} while (0)
+
+#define SMS_INIT_MSG(ptr, type, len) \
+       SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
+
+enum SMS_DVB3_EVENTS {
+       DVB3_EVENT_INIT = 0,
+       DVB3_EVENT_SLEEP,
+       DVB3_EVENT_HOTPLUG,
+       DVB3_EVENT_FE_LOCK,
+       DVB3_EVENT_FE_UNLOCK,
+       DVB3_EVENT_UNC_OK,
+       DVB3_EVENT_UNC_ERR
+};
+
+enum SMS_DEVICE_MODE {
+       DEVICE_MODE_NONE = -1,
+       DEVICE_MODE_DVBT = 0,
+       DEVICE_MODE_DVBH,
+       DEVICE_MODE_DAB_TDMB,
+       DEVICE_MODE_DAB_TDMB_DABIP,
+       DEVICE_MODE_DVBT_BDA,
+       DEVICE_MODE_ISDBT,
+       DEVICE_MODE_ISDBT_BDA,
+       DEVICE_MODE_CMMB,
+       DEVICE_MODE_RAW_TUNER,
+       DEVICE_MODE_MAX,
+};
+
+struct SmsMsgHdr_ST {
+       u16     msgType;
+       u8      msgSrcId;
+       u8      msgDstId;
+       u16     msgLength; /* Length of entire message, including header */
+       u16     msgFlags;
+};
+
+struct SmsMsgData_ST {
+       struct SmsMsgHdr_ST xMsgHeader;
+       u32 msgData[1];
+};
+
+struct SmsMsgData_ST2 {
+       struct SmsMsgHdr_ST xMsgHeader;
+       u32 msgData[2];
+};
+
+struct SmsDataDownload_ST {
+       struct SmsMsgHdr_ST     xMsgHeader;
+       u32                     MemAddr;
+       u8                      Payload[SMS_MAX_PAYLOAD_SIZE];
+};
+
+struct SmsVersionRes_ST {
+       struct SmsMsgHdr_ST     xMsgHeader;
+
+       u16             ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
+       u8              Step; /* 0 - Step A */
+       u8              MetalFix; /* 0 - Metal 0 */
+
+       /* FirmwareId 0xFF if ROM, otherwise the
+        * value indicated by SMSHOSTLIB_DEVICE_MODES_E */
+       u8 FirmwareId;
+       /* SupportedProtocols Bitwise OR combination of
+                                            * supported protocols */
+       u8 SupportedProtocols;
+
+       u8              VersionMajor;
+       u8              VersionMinor;
+       u8              VersionPatch;
+       u8              VersionFieldPatch;
+
+       u8              RomVersionMajor;
+       u8              RomVersionMinor;
+       u8              RomVersionPatch;
+       u8              RomVersionFieldPatch;
+
+       u8              TextLabel[34];
+};
+
+struct SmsFirmware_ST {
+       u32                     CheckSum;
+       u32                     Length;
+       u32                     StartAddress;
+       u8                      Payload[1];
+};
+
+/* Statistics information returned as response for
+ * SmsHostApiGetStatistics_Req */
+struct SMSHOSTLIB_STATISTICS_ST {
+       u32 Reserved;           /* Reserved */
+
+       /* Common parameters */
+       u32 IsRfLocked;         /* 0 - not locked, 1 - locked */
+       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
+       u32 IsExternalLNAOn;    /* 0 - external LNA off, 1 - external LNA on */
+
+       /* Reception quality */
+       s32 SNR;                /* dB */
+       u32 BER;                /* Post Viterbi BER [1E-5] */
+       u32 FIB_CRC;            /* CRC errors percentage, valid only for DAB */
+       u32 TS_PER;             /* Transport stream PER,
+       0xFFFFFFFF indicate N/A, valid only for DVB-T/H */
+       u32 MFER;               /* DVB-H frame error rate in percentage,
+       0xFFFFFFFF indicate N/A, valid only for DVB-H */
+       s32 RSSI;               /* dBm */
+       s32 InBandPwr;          /* In band power in dBM */
+       s32 CarrierOffset;      /* Carrier Offset in bin/1024 */
+
+       /* Transmission parameters */
+       u32 Frequency;          /* Frequency in Hz */
+       u32 Bandwidth;          /* Bandwidth in MHz, valid only for DVB-T/H */
+       u32 TransmissionMode;   /* Transmission Mode, for DAB modes 1-4,
+       for DVB-T/H FFT mode carriers in Kilos */
+       u32 ModemState;         /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
+       valid only for DVB-T/H */
+       u32 GuardInterval;      /* Guard Interval from
+       SMSHOSTLIB_GUARD_INTERVALS_ET,  valid only for DVB-T/H */
+       u32 CodeRate;           /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
+       valid only for DVB-T/H */
+       u32 LPCodeRate;         /* Low Priority Code Rate from
+       SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */
+       u32 Hierarchy;          /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET,
+       valid only for DVB-T/H */
+       u32 Constellation;      /* Constellation from
+       SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */
+
+       /* Burst parameters, valid only for DVB-H */
+       u32 BurstSize;          /* Current burst size in bytes,
+       valid only for DVB-H */
+       u32 BurstDuration;      /* Current burst duration in mSec,
+       valid only for DVB-H */
+       u32 BurstCycleTime;     /* Current burst cycle time in mSec,
+       valid only for DVB-H */
+       u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec,
+       as calculated by demodulator, valid only for DVB-H */
+       u32 NumOfRows;          /* Number of rows in MPE table,
+       valid only for DVB-H */
+       u32 NumOfPaddCols;      /* Number of padding columns in MPE table,
+       valid only for DVB-H */
+       u32 NumOfPunctCols;     /* Number of puncturing columns in MPE table,
+       valid only for DVB-H */
+       u32 ErrorTSPackets;     /* Number of erroneous
+       transport-stream packets */
+       u32 TotalTSPackets;     /* Total number of transport-stream packets */
+       u32 NumOfValidMpeTlbs;  /* Number of MPE tables which do not include
+       errors after MPE RS decoding */
+       u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
+       after MPE RS decoding */
+       u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were
+       corrected by MPE RS decoding */
+       /* Common params */
+       u32 BERErrorCount;      /* Number of errornous SYNC bits. */
+       u32 BERBitCount;        /* Total number of SYNC bits. */
+
+       /* Interface information */
+       u32 SmsToHostTxErrors;  /* Total number of transmission errors. */
+
+       /* DAB/T-DMB */
+       u32 PreBER;             /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
+
+       /* DVB-H TPS parameters */
+       u32 CellId;             /* TPS Cell ID in bits 15..0, bits 31..16 zero;
+        if set to 0xFFFFFFFF cell_id not yet recovered */
+       u32 DvbhSrvIndHP;       /* DVB-H service indication info, bit 1 -
+       Time Slicing indicator, bit 0 - MPE-FEC indicator */
+       u32 DvbhSrvIndLP;       /* DVB-H service indication info, bit 1 -
+       Time Slicing indicator, bit 0 - MPE-FEC indicator */
+
+       u32 NumMPEReceived;     /* DVB-H, Num MPE section received */
+
+       u32 ReservedFields[10]; /* Reserved */
+};
+
+struct SmsMsgStatisticsInfo_ST {
+       u32 RequestResult;
+
+       struct SMSHOSTLIB_STATISTICS_ST Stat;
+
+       /* Split the calc of the SNR in DAB */
+       u32 Signal; /* dB */
+       u32 Noise; /* dB */
+
+};
+
+struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
+       /* Per-layer information */
+       u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
+                      * 255 means layer does not exist */
+       u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
+                           * 255 means layer does not exist */
+       u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
+       u32 BERErrorCount; /* Post Viterbi Error Bits Count */
+       u32 BERBitCount; /* Post Viterbi Total Bits Count */
+       u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
+       u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
+       u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
+       u32 TotalTSPackets; /* Total number of transport-stream packets */
+       u32 TILdepthI; /* Time interleaver depth I parameter,
+                       * 255 means layer does not exist */
+       u32 NumberOfSegments; /* Number of segments in layer A,
+                              * 255 means layer does not exist */
+       u32 TMCCErrors; /* TMCC errors */
+};
+
+struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
+       u32 StatisticsType; /* Enumerator identifying the type of the
+                               * structure.  Values are the same as
+                               * SMSHOSTLIB_DEVICE_MODES_E
+                               *
+                               * This field MUST always be first in any
+                               * statistics structure */
+
+       u32 FullSize; /* Total size of the structure returned by the modem.
+                      * If the size requested by the host is smaller than
+                      * FullSize, the struct will be truncated */
+
+       /* Common parameters */
+       u32 IsRfLocked; /* 0 - not locked, 1 - locked */
+       u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
+       u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
+
+       /* Reception quality */
+       s32  SNR; /* dB */
+       s32  RSSI; /* dBm */
+       s32  InBandPwr; /* In band power in dBM */
+       s32  CarrierOffset; /* Carrier Offset in Hz */
+
+       /* Transmission parameters */
+       u32 Frequency; /* Frequency in Hz */
+       u32 Bandwidth; /* Bandwidth in MHz */
+       u32 TransmissionMode; /* ISDB-T transmission mode */
+       u32 ModemState; /* 0 - Acquisition, 1 - Locked */
+       u32 GuardInterval; /* Guard Interval, 1 divided by value */
+       u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
+       u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
+       u32 NumOfLayers; /* Number of ISDB-T layers in the network */
+
+       /* Per-layer information */
+       /* Layers A, B and C */
+       struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST   LayerInfo[3];
+       /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
+
+       /* Interface information */
+       u32 SmsToHostTxErrors; /* Total number of transmission errors. */
+};
+
+struct PID_STATISTICS_DATA_S {
+       struct PID_BURST_S {
+               u32 size;
+               u32 padding_cols;
+               u32 punct_cols;
+               u32 duration;
+               u32 cycle;
+               u32 calc_cycle;
+       } burst;
+
+       u32 tot_tbl_cnt;
+       u32 invalid_tbl_cnt;
+       u32 tot_cor_tbl;
+};
+
+struct PID_DATA_S {
+       u32 pid;
+       u32 num_rows;
+       struct PID_STATISTICS_DATA_S pid_statistics;
+};
+
+#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1)
+#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth)
+#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \
+       if (_stat.TransmissionMode == 0) \
+               _stat.TransmissionMode = 2; \
+       else if (_stat.TransmissionMode == 1) \
+               _stat.TransmissionMode = 8; \
+               else \
+                       _stat.TransmissionMode = 4;
+
+struct TRANSMISSION_STATISTICS_S {
+       u32 Frequency;          /* Frequency in Hz */
+       u32 Bandwidth;          /* Bandwidth in MHz */
+       u32 TransmissionMode;   /* FFT mode carriers in Kilos */
+       u32 GuardInterval;      /* Guard Interval from
+       SMSHOSTLIB_GUARD_INTERVALS_ET */
+       u32 CodeRate;           /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
+       u32 LPCodeRate;         /* Low Priority Code Rate from
+       SMSHOSTLIB_CODE_RATE_ET */
+       u32 Hierarchy;          /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
+       u32 Constellation;      /* Constellation from
+       SMSHOSTLIB_CONSTELLATION_ET */
+
+       /* DVB-H TPS parameters */
+       u32 CellId;             /* TPS Cell ID in bits 15..0, bits 31..16 zero;
+        if set to 0xFFFFFFFF cell_id not yet recovered */
+       u32 DvbhSrvIndHP;       /* DVB-H service indication info, bit 1 -
+        Time Slicing indicator, bit 0 - MPE-FEC indicator */
+       u32 DvbhSrvIndLP;       /* DVB-H service indication info, bit 1 -
+        Time Slicing indicator, bit 0 - MPE-FEC indicator */
+       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
+};
+
+struct RECEPTION_STATISTICS_S {
+       u32 IsRfLocked;         /* 0 - not locked, 1 - locked */
+       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
+       u32 IsExternalLNAOn;    /* 0 - external LNA off, 1 - external LNA on */
+
+       u32 ModemState;         /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
+       s32 SNR;                /* dB */
+       u32 BER;                /* Post Viterbi BER [1E-5] */
+       u32 BERErrorCount;      /* Number of erronous SYNC bits. */
+       u32 BERBitCount;        /* Total number of SYNC bits. */
+       u32 TS_PER;             /* Transport stream PER,
+       0xFFFFFFFF indicate N/A */
+       u32 MFER;               /* DVB-H frame error rate in percentage,
+       0xFFFFFFFF indicate N/A, valid only for DVB-H */
+       s32 RSSI;               /* dBm */
+       s32 InBandPwr;          /* In band power in dBM */
+       s32 CarrierOffset;      /* Carrier Offset in bin/1024 */
+       u32 ErrorTSPackets;     /* Number of erroneous
+       transport-stream packets */
+       u32 TotalTSPackets;     /* Total number of transport-stream packets */
+
+       s32 MRC_SNR;            /* dB */
+       s32 MRC_RSSI;           /* dBm */
+       s32 MRC_InBandPwr;      /* In band power in dBM */
+};
+
+
+/* Statistics information returned as response for
+ * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */
+struct SMSHOSTLIB_STATISTICS_DVB_S {
+       /* Reception */
+       struct RECEPTION_STATISTICS_S ReceptionData;
+
+       /* Transmission parameters */
+       struct TRANSMISSION_STATISTICS_S TransmissionData;
+
+       /* Burst parameters, valid only for DVB-H */
+#define        SRVM_MAX_PID_FILTERS 8
+       struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS];
+};
+
+struct SRVM_SIGNAL_STATUS_S {
+       u32 result;
+       u32 snr;
+       u32 tsPackets;
+       u32 etsPackets;
+       u32 constellation;
+       u32 hpCode;
+       u32 tpsSrvIndLP;
+       u32 tpsSrvIndHP;
+       u32 cellId;
+       u32 reason;
+
+       s32 inBandPower;
+       u32 requestId;
+};
+
+struct SMSHOSTLIB_I2C_REQ_ST {
+       u32     DeviceAddress; /* I2c device address */
+       u32     WriteCount; /* number of bytes to write */
+       u32     ReadCount; /* number of bytes to read */
+       u8      Data[1];
+};
+
+struct SMSHOSTLIB_I2C_RES_ST {
+       u32     Status; /* non-zero value in case of failure */
+       u32     ReadCount; /* number of bytes read */
+       u8      Data[1];
+};
+
+
+struct smscore_config_gpio {
+#define SMS_GPIO_DIRECTION_INPUT  0
+#define SMS_GPIO_DIRECTION_OUTPUT 1
+       u8 direction;
+
+#define SMS_GPIO_PULLUPDOWN_NONE     0
+#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
+#define SMS_GPIO_PULLUPDOWN_PULLUP   2
+#define SMS_GPIO_PULLUPDOWN_KEEPER   3
+       u8 pullupdown;
+
+#define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL  0
+#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
+       u8 inputcharacteristics;
+
+#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
+#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
+       u8 outputslewrate;
+
+#define SMS_GPIO_OUTPUTDRIVING_4mA  0
+#define SMS_GPIO_OUTPUTDRIVING_8mA  1
+#define SMS_GPIO_OUTPUTDRIVING_12mA 2
+#define SMS_GPIO_OUTPUTDRIVING_16mA 3
+       u8 outputdriving;
+};
+
+struct smscore_gpio_config {
+#define SMS_GPIO_DIRECTION_INPUT  0
+#define SMS_GPIO_DIRECTION_OUTPUT 1
+       u8 Direction;
+
+#define SMS_GPIO_PULL_UP_DOWN_NONE     0
+#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1
+#define SMS_GPIO_PULL_UP_DOWN_PULLUP   2
+#define SMS_GPIO_PULL_UP_DOWN_KEEPER   3
+       u8 PullUpDown;
+
+#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL  0
+#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
+       u8 InputCharacteristics;
+
+#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW         1 /* 10xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST         0 /* 10xx */
+
+
+#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS    0 /* 11xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS     1 /* 11xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS     2 /* 11xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS     3 /* 11xx */
+       u8 OutputSlewRate;
+
+#define SMS_GPIO_OUTPUT_DRIVING_S_4mA          0 /* 10xx */
+#define SMS_GPIO_OUTPUT_DRIVING_S_8mA          1 /* 10xx */
+#define SMS_GPIO_OUTPUT_DRIVING_S_12mA         2 /* 10xx */
+#define SMS_GPIO_OUTPUT_DRIVING_S_16mA         3 /* 10xx */
+
+#define SMS_GPIO_OUTPUT_DRIVING_1_5mA          0 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_2_8mA          1 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_4mA            2 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_7mA            3 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_10mA           4 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_11mA           5 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_14mA           6 /* 11xx */
+#define SMS_GPIO_OUTPUT_DRIVING_16mA           7 /* 11xx */
+       u8 OutputDriving;
+};
+
+extern void smscore_registry_setmode(char *devpath, int mode);
+extern int smscore_registry_getmode(char *devpath);
+
+extern int smscore_register_hotplug(hotplug_t hotplug);
+extern void smscore_unregister_hotplug(hotplug_t hotplug);
+
+extern int smscore_register_device(struct smsdevice_params_t *params,
+                                  struct smscore_device_t **coredev);
+extern void smscore_unregister_device(struct smscore_device_t *coredev);
+
+extern int smscore_start_device(struct smscore_device_t *coredev);
+extern int smscore_load_firmware(struct smscore_device_t *coredev,
+                                char *filename,
+                                loadfirmware_t loadfirmware_handler);
+
+extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
+extern int smscore_get_device_mode(struct smscore_device_t *coredev);
+
+extern int smscore_register_client(struct smscore_device_t *coredev,
+                                   struct smsclient_params_t *params,
+                                   struct smscore_client_t **client);
+extern void smscore_unregister_client(struct smscore_client_t *client);
+
+extern int smsclient_sendrequest(struct smscore_client_t *client,
+                                void *buffer, size_t size);
+extern void smscore_onresponse(struct smscore_device_t *coredev,
+                              struct smscore_buffer_t *cb);
+
+extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
+extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
+                                     struct vm_area_struct *vma);
+extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
+                                  int mode, char *filename);
+extern int smscore_send_fw_file(struct smscore_device_t *coredev,
+                               u8 *ufwbuf, int size);
+
+extern
+struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
+extern void smscore_putbuffer(struct smscore_device_t *coredev,
+                             struct smscore_buffer_t *cb);
+
+/* old GPIO management */
+int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
+                          struct smscore_config_gpio *pinconfig);
+int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
+
+/* new GPIO management */
+extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
+               struct smscore_gpio_config *pGpioConfig);
+extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
+               u8 NewLevel);
+extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
+               u8 *level);
+
+void smscore_set_board_id(struct smscore_device_t *core, int id);
+int smscore_get_board_id(struct smscore_device_t *core);
+
+int smscore_led_state(struct smscore_device_t *core, int led);
+
+
+/* ------------------------------------------------------------------------ */
+
+#define DBG_INFO 1
+#define DBG_ADV  2
+
+#define sms_printk(kern, fmt, arg...) \
+       printk(kern "%s: " fmt "\n", __func__, ##arg)
+
+#define dprintk(kern, lvl, fmt, arg...) do {\
+       if (sms_dbg & lvl) \
+               sms_printk(kern, fmt, ##arg); } while (0)
+
+#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
+#define sms_err(fmt, arg...) \
+       sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
+#define sms_warn(fmt, arg...)  sms_printk(KERN_WARNING, fmt, ##arg)
+#define sms_info(fmt, arg...) \
+       dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
+#define sms_debug(fmt, arg...) \
+       dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
+
+
+#endif /* __SMS_CORE_API_H__ */
diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c
new file mode 100644 (file)
index 0000000..aa77e54
--- /dev/null
@@ -0,0 +1,1078 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2008, Uri Shkolnik
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+
+#include "smscoreapi.h"
+#include "smsendian.h"
+#include "sms-cards.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct smsdvb_client_t {
+       struct list_head entry;
+
+       struct smscore_device_t *coredev;
+       struct smscore_client_t *smsclient;
+
+       struct dvb_adapter      adapter;
+       struct dvb_demux        demux;
+       struct dmxdev           dmxdev;
+       struct dvb_frontend     frontend;
+
+       fe_status_t             fe_status;
+
+       struct completion       tune_done;
+
+       struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb;
+       int event_fe_state;
+       int event_unc_state;
+};
+
+static struct list_head g_smsdvb_clients;
+static struct mutex g_smsdvb_clientslock;
+
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
+/* Events that may come from DVB v3 adapter */
+static void sms_board_dvb3_event(struct smsdvb_client_t *client,
+               enum SMS_DVB3_EVENTS event) {
+
+       struct smscore_device_t *coredev = client->coredev;
+       switch (event) {
+       case DVB3_EVENT_INIT:
+               sms_debug("DVB3_EVENT_INIT");
+               sms_board_event(coredev, BOARD_EVENT_BIND);
+               break;
+       case DVB3_EVENT_SLEEP:
+               sms_debug("DVB3_EVENT_SLEEP");
+               sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
+               break;
+       case DVB3_EVENT_HOTPLUG:
+               sms_debug("DVB3_EVENT_HOTPLUG");
+               sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
+               break;
+       case DVB3_EVENT_FE_LOCK:
+               if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
+                       client->event_fe_state = DVB3_EVENT_FE_LOCK;
+                       sms_debug("DVB3_EVENT_FE_LOCK");
+                       sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
+               }
+               break;
+       case DVB3_EVENT_FE_UNLOCK:
+               if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
+                       client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
+                       sms_debug("DVB3_EVENT_FE_UNLOCK");
+                       sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
+               }
+               break;
+       case DVB3_EVENT_UNC_OK:
+               if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
+                       client->event_unc_state = DVB3_EVENT_UNC_OK;
+                       sms_debug("DVB3_EVENT_UNC_OK");
+                       sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
+               }
+               break;
+       case DVB3_EVENT_UNC_ERR:
+               if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
+                       client->event_unc_state = DVB3_EVENT_UNC_ERR;
+                       sms_debug("DVB3_EVENT_UNC_ERR");
+                       sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
+               }
+               break;
+
+       default:
+               sms_err("Unknown dvb3 api event");
+               break;
+       }
+}
+
+
+static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
+                                  struct SMSHOSTLIB_STATISTICS_ST *p)
+{
+       if (sms_dbg & 2) {
+               printk(KERN_DEBUG "Reserved = %d", p->Reserved);
+               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
+               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
+               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
+               printk(KERN_DEBUG "SNR = %d", p->SNR);
+               printk(KERN_DEBUG "BER = %d", p->BER);
+               printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
+               printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
+               printk(KERN_DEBUG "MFER = %d", p->MFER);
+               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
+               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
+               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
+               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
+               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
+               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
+               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
+               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
+               printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
+               printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
+               printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
+               printk(KERN_DEBUG "Constellation = %d", p->Constellation);
+               printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
+               printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
+               printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
+               printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
+               printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
+               printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
+               printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
+               printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
+               printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
+               printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
+               printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
+               printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
+               printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
+               printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
+               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
+               printk(KERN_DEBUG "PreBER = %d", p->PreBER);
+               printk(KERN_DEBUG "CellId = %d", p->CellId);
+               printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
+               printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
+               printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
+       }
+
+       pReceptionData->IsDemodLocked = p->IsDemodLocked;
+
+       pReceptionData->SNR = p->SNR;
+       pReceptionData->BER = p->BER;
+       pReceptionData->BERErrorCount = p->BERErrorCount;
+       pReceptionData->InBandPwr = p->InBandPwr;
+       pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
+};
+
+
+static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
+                                   struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
+{
+       int i;
+
+       if (sms_dbg & 2) {
+               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
+               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
+               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
+               printk(KERN_DEBUG "SNR = %d", p->SNR);
+               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
+               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
+               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
+               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
+               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
+               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
+               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
+               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
+               printk(KERN_DEBUG "SystemType = %d", p->SystemType);
+               printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
+               printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
+               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
+
+               for (i = 0; i < 3; i++) {
+                       printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
+                       printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
+                       printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
+                       printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
+                       printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
+                       printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
+                       printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
+                       printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
+                       printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
+                       printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
+                       printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
+                       printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
+               }
+       }
+
+       pReceptionData->IsDemodLocked = p->IsDemodLocked;
+
+       pReceptionData->SNR = p->SNR;
+       pReceptionData->InBandPwr = p->InBandPwr;
+
+       pReceptionData->ErrorTSPackets = 0;
+       pReceptionData->BER = 0;
+       pReceptionData->BERErrorCount = 0;
+       for (i = 0; i < 3; i++) {
+               pReceptionData->BER += p->LayerInfo[i].BER;
+               pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
+               pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
+       }
+}
+
+static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
+{
+       struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
+       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
+                       + cb->offset);
+       u32 *pMsgData = (u32 *) phdr + 1;
+       /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
+       bool is_status_update = false;
+
+       smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);
+
+       switch (phdr->msgType) {
+       case MSG_SMS_DVBT_BDA_DATA:
+               dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1),
+                                cb->size - sizeof(struct SmsMsgHdr_ST));
+               break;
+
+       case MSG_SMS_RF_TUNE_RES:
+       case MSG_SMS_ISDBT_TUNE_RES:
+               complete(&client->tune_done);
+               break;
+
+       case MSG_SMS_SIGNAL_DETECTED_IND:
+               sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
+               client->sms_stat_dvb.TransmissionData.IsDemodLocked = true;
+               is_status_update = true;
+               break;
+
+       case MSG_SMS_NO_SIGNAL_IND:
+               sms_info("MSG_SMS_NO_SIGNAL_IND");
+               client->sms_stat_dvb.TransmissionData.IsDemodLocked = false;
+               is_status_update = true;
+               break;
+
+       case MSG_SMS_TRANSMISSION_IND: {
+               sms_info("MSG_SMS_TRANSMISSION_IND");
+
+               pMsgData++;
+               memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
+                               sizeof(struct TRANSMISSION_STATISTICS_S));
+
+               /* Mo need to correct guard interval
+                * (as opposed to old statistics message).
+                */
+               CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
+               CORRECT_STAT_TRANSMISSON_MODE(
+                               client->sms_stat_dvb.TransmissionData);
+               is_status_update = true;
+               break;
+       }
+       case MSG_SMS_HO_PER_SLICES_IND: {
+               struct RECEPTION_STATISTICS_S *pReceptionData =
+                               &client->sms_stat_dvb.ReceptionData;
+               struct SRVM_SIGNAL_STATUS_S SignalStatusData;
+
+               /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
+               pMsgData++;
+               SignalStatusData.result = pMsgData[0];
+               SignalStatusData.snr = pMsgData[1];
+               SignalStatusData.inBandPower = (s32) pMsgData[2];
+               SignalStatusData.tsPackets = pMsgData[3];
+               SignalStatusData.etsPackets = pMsgData[4];
+               SignalStatusData.constellation = pMsgData[5];
+               SignalStatusData.hpCode = pMsgData[6];
+               SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
+               SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
+               SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
+               SignalStatusData.reason = pMsgData[10];
+               SignalStatusData.requestId = pMsgData[11];
+               pReceptionData->IsRfLocked = pMsgData[16];
+               pReceptionData->IsDemodLocked = pMsgData[17];
+               pReceptionData->ModemState = pMsgData[12];
+               pReceptionData->SNR = pMsgData[1];
+               pReceptionData->BER = pMsgData[13];
+               pReceptionData->RSSI = pMsgData[14];
+               CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
+
+               pReceptionData->InBandPwr = (s32) pMsgData[2];
+               pReceptionData->CarrierOffset = (s32) pMsgData[15];
+               pReceptionData->TotalTSPackets = pMsgData[3];
+               pReceptionData->ErrorTSPackets = pMsgData[4];
+
+               /* TS PER */
+               if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
+                               > 0) {
+                       pReceptionData->TS_PER = (SignalStatusData.etsPackets
+                                       * 100) / (SignalStatusData.tsPackets
+                                       + SignalStatusData.etsPackets);
+               } else {
+                       pReceptionData->TS_PER = 0;
+               }
+
+               pReceptionData->BERBitCount = pMsgData[18];
+               pReceptionData->BERErrorCount = pMsgData[19];
+
+               pReceptionData->MRC_SNR = pMsgData[20];
+               pReceptionData->MRC_InBandPwr = pMsgData[21];
+               pReceptionData->MRC_RSSI = pMsgData[22];
+
+               is_status_update = true;
+               break;
+       }
+       case MSG_SMS_GET_STATISTICS_RES: {
+               union {
+                       struct SMSHOSTLIB_STATISTICS_ISDBT_ST  isdbt;
+                       struct SmsMsgStatisticsInfo_ST         dvb;
+               } *p = (void *) (phdr + 1);
+               struct RECEPTION_STATISTICS_S *pReceptionData =
+                               &client->sms_stat_dvb.ReceptionData;
+
+               sms_info("MSG_SMS_GET_STATISTICS_RES");
+
+               is_status_update = true;
+
+               switch (smscore_get_device_mode(client->coredev)) {
+               case DEVICE_MODE_ISDBT:
+               case DEVICE_MODE_ISDBT_BDA:
+                       smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
+                       break;
+               default:
+                       smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
+               }
+               if (!pReceptionData->IsDemodLocked) {
+                       pReceptionData->SNR = 0;
+                       pReceptionData->BER = 0;
+                       pReceptionData->BERErrorCount = 0;
+                       pReceptionData->InBandPwr = 0;
+                       pReceptionData->ErrorTSPackets = 0;
+               }
+
+               complete(&client->tune_done);
+               break;
+       }
+       default:
+               sms_info("Unhandled message %d", phdr->msgType);
+
+       }
+       smscore_putbuffer(client->coredev, cb);
+
+       if (is_status_update) {
+               if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
+                       client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
+                               | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+                       sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
+                       if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets
+                                       == 0)
+                               sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
+                       else
+                               sms_board_dvb3_event(client,
+                                               DVB3_EVENT_UNC_ERR);
+
+               } else {
+                       if (client->sms_stat_dvb.ReceptionData.IsRfLocked)
+                               client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+                       else
+                               client->fe_status = 0;
+                       sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
+               }
+       }
+
+       return 0;
+}
+
+static void smsdvb_unregister_client(struct smsdvb_client_t *client)
+{
+       /* must be called under clientslock */
+
+       list_del(&client->entry);
+
+       smscore_unregister_client(client->smsclient);
+       dvb_unregister_frontend(&client->frontend);
+       dvb_dmxdev_release(&client->dmxdev);
+       dvb_dmx_release(&client->demux);
+       dvb_unregister_adapter(&client->adapter);
+       kfree(client);
+}
+
+static void smsdvb_onremove(void *context)
+{
+       kmutex_lock(&g_smsdvb_clientslock);
+
+       smsdvb_unregister_client((struct smsdvb_client_t *) context);
+
+       kmutex_unlock(&g_smsdvb_clientslock);
+}
+
+static int smsdvb_start_feed(struct dvb_demux_feed *feed)
+{
+       struct smsdvb_client_t *client =
+               container_of(feed->demux, struct smsdvb_client_t, demux);
+       struct SmsMsgData_ST PidMsg;
+
+       sms_debug("add pid %d(%x)",
+                 feed->pid, feed->pid);
+
+       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
+       PidMsg.xMsgHeader.msgFlags = 0;
+       PidMsg.xMsgHeader.msgType  = MSG_SMS_ADD_PID_FILTER_REQ;
+       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
+       PidMsg.msgData[0] = feed->pid;
+
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
+       return smsclient_sendrequest(client->smsclient,
+                                    &PidMsg, sizeof(PidMsg));
+}
+
+static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
+{
+       struct smsdvb_client_t *client =
+               container_of(feed->demux, struct smsdvb_client_t, demux);
+       struct SmsMsgData_ST PidMsg;
+
+       sms_debug("remove pid %d(%x)",
+                 feed->pid, feed->pid);
+
+       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
+       PidMsg.xMsgHeader.msgFlags = 0;
+       PidMsg.xMsgHeader.msgType  = MSG_SMS_REMOVE_PID_FILTER_REQ;
+       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
+       PidMsg.msgData[0] = feed->pid;
+
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
+       return smsclient_sendrequest(client->smsclient,
+                                    &PidMsg, sizeof(PidMsg));
+}
+
+static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
+                                       void *buffer, size_t size,
+                                       struct completion *completion)
+{
+       int rc;
+
+       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer);
+       rc = smsclient_sendrequest(client->smsclient, buffer, size);
+       if (rc < 0)
+               return rc;
+
+       return wait_for_completion_timeout(completion,
+                                          msecs_to_jiffies(2000)) ?
+                                               0 : -ETIME;
+}
+
+static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
+{
+       int rc;
+       struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
+                                   DVBT_BDA_CONTROL_MSG_ID,
+                                   HIF_TASK,
+                                   sizeof(struct SmsMsgHdr_ST), 0 };
+
+       rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                         &client->tune_done);
+
+       return rc;
+}
+
+static inline int led_feedback(struct smsdvb_client_t *client)
+{
+       if (client->fe_status & FE_HAS_LOCK)
+               return sms_board_led_feedback(client->coredev,
+                       (client->sms_stat_dvb.ReceptionData.BER
+                       == 0) ? SMS_LED_HI : SMS_LED_LO);
+       else
+               return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
+}
+
+static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
+{
+       int rc;
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       *stat = client->fe_status;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       int rc;
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       *ber = client->sms_stat_dvb.ReceptionData.BER;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       int rc;
+
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
+               *strength = 0;
+               else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
+                       *strength = 100;
+               else
+                       *strength =
+                               (client->sms_stat_dvb.ReceptionData.InBandPwr
+                               + 95) * 3 / 2;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       int rc;
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       *snr = client->sms_stat_dvb.ReceptionData.SNR;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       int rc;
+       struct smsdvb_client_t *client;
+       client = container_of(fe, struct smsdvb_client_t, frontend);
+
+       rc = smsdvb_send_statistics_request(client);
+
+       *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
+
+       led_feedback(client);
+
+       return rc;
+}
+
+static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
+                                   struct dvb_frontend_tune_settings *tune)
+{
+       sms_debug("");
+
+       tune->min_delay_ms = 400;
+       tune->step_size = 250000;
+       tune->max_drift = 0;
+       return 0;
+}
+
+static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+
+       struct {
+               struct SmsMsgHdr_ST     Msg;
+               u32             Data[3];
+       } Msg;
+
+       int ret;
+
+       client->fe_status = FE_HAS_SIGNAL;
+       client->event_fe_state = -1;
+       client->event_unc_state = -1;
+       fe->dtv_property_cache.delivery_system = SYS_DVBT;
+
+       Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+       Msg.Msg.msgDstId = HIF_TASK;
+       Msg.Msg.msgFlags = 0;
+       Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
+       Msg.Msg.msgLength = sizeof(Msg);
+       Msg.Data[0] = c->frequency;
+       Msg.Data[2] = 12000000;
+
+       sms_info("%s: freq %d band %d", __func__, c->frequency,
+                c->bandwidth_hz);
+
+       switch (c->bandwidth_hz / 1000000) {
+       case 8:
+               Msg.Data[1] = BW_8_MHZ;
+               break;
+       case 7:
+               Msg.Data[1] = BW_7_MHZ;
+               break;
+       case 6:
+               Msg.Data[1] = BW_6_MHZ;
+               break;
+       case 0:
+               return -EOPNOTSUPP;
+       default:
+               return -EINVAL;
+       }
+       /* Disable LNA, if any. An error is returned if no LNA is present */
+       ret = sms_board_lna_control(client->coredev, 0);
+       if (ret == 0) {
+               fe_status_t status;
+
+               /* tune with LNA off at first */
+               ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                                 &client->tune_done);
+
+               smsdvb_read_status(fe, &status);
+
+               if (status & FE_HAS_LOCK)
+                       return ret;
+
+               /* previous tune didn't lock - enable LNA and tune again */
+               sms_board_lna_control(client->coredev, 1);
+       }
+
+       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                          &client->tune_done);
+}
+
+static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+
+       struct {
+               struct SmsMsgHdr_ST     Msg;
+               u32             Data[4];
+       } Msg;
+
+       fe->dtv_property_cache.delivery_system = SYS_ISDBT;
+
+       Msg.Msg.msgSrcId  = DVBT_BDA_CONTROL_MSG_ID;
+       Msg.Msg.msgDstId  = HIF_TASK;
+       Msg.Msg.msgFlags  = 0;
+       Msg.Msg.msgType   = MSG_SMS_ISDBT_TUNE_REQ;
+       Msg.Msg.msgLength = sizeof(Msg);
+
+       if (c->isdbt_sb_segment_idx == -1)
+               c->isdbt_sb_segment_idx = 0;
+
+       switch (c->isdbt_sb_segment_count) {
+       case 3:
+               Msg.Data[1] = BW_ISDBT_3SEG;
+               break;
+       case 1:
+               Msg.Data[1] = BW_ISDBT_1SEG;
+               break;
+       case 0: /* AUTO */
+               switch (c->bandwidth_hz / 1000000) {
+               case 8:
+               case 7:
+                       c->isdbt_sb_segment_count = 3;
+                       Msg.Data[1] = BW_ISDBT_3SEG;
+                       break;
+               case 6:
+                       c->isdbt_sb_segment_count = 1;
+                       Msg.Data[1] = BW_ISDBT_1SEG;
+                       break;
+               default: /* Assumes 6 MHZ bw */
+                       c->isdbt_sb_segment_count = 1;
+                       c->bandwidth_hz = 6000;
+                       Msg.Data[1] = BW_ISDBT_1SEG;
+                       break;
+               }
+               break;
+       default:
+               sms_info("Segment count %d not supported", c->isdbt_sb_segment_count);
+               return -EINVAL;
+       }
+
+       Msg.Data[0] = c->frequency;
+       Msg.Data[2] = 12000000;
+       Msg.Data[3] = c->isdbt_sb_segment_idx;
+
+       sms_info("%s: freq %d segwidth %d segindex %d\n", __func__,
+                c->frequency, c->isdbt_sb_segment_count,
+                c->isdbt_sb_segment_idx);
+
+       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                          &client->tune_done);
+}
+
+static int smsdvb_set_frontend(struct dvb_frontend *fe)
+{
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+       struct smscore_device_t *coredev = client->coredev;
+
+       switch (smscore_get_device_mode(coredev)) {
+       case DEVICE_MODE_DVBT:
+       case DEVICE_MODE_DVBT_BDA:
+               return smsdvb_dvbt_set_frontend(fe);
+       case DEVICE_MODE_ISDBT:
+       case DEVICE_MODE_ISDBT_BDA:
+               return smsdvb_isdbt_set_frontend(fe);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int smsdvb_get_frontend(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+       struct smscore_device_t *coredev = client->coredev;
+       struct TRANSMISSION_STATISTICS_S *td =
+               &client->sms_stat_dvb.TransmissionData;
+
+       switch (smscore_get_device_mode(coredev)) {
+       case DEVICE_MODE_DVBT:
+       case DEVICE_MODE_DVBT_BDA:
+               fep->frequency = td->Frequency;
+
+               switch (td->Bandwidth) {
+               case 6:
+                       fep->bandwidth_hz = 6000000;
+                       break;
+               case 7:
+                       fep->bandwidth_hz = 7000000;
+                       break;
+               case 8:
+                       fep->bandwidth_hz = 8000000;
+                       break;
+               }
+
+               switch (td->TransmissionMode) {
+               case 2:
+                       fep->transmission_mode = TRANSMISSION_MODE_2K;
+                       break;
+               case 8:
+                       fep->transmission_mode = TRANSMISSION_MODE_8K;
+               }
+
+               switch (td->GuardInterval) {
+               case 0:
+                       fep->guard_interval = GUARD_INTERVAL_1_32;
+                       break;
+               case 1:
+                       fep->guard_interval = GUARD_INTERVAL_1_16;
+                       break;
+               case 2:
+                       fep->guard_interval = GUARD_INTERVAL_1_8;
+                       break;
+               case 3:
+                       fep->guard_interval = GUARD_INTERVAL_1_4;
+                       break;
+               }
+
+               switch (td->CodeRate) {
+               case 0:
+                       fep->code_rate_HP = FEC_1_2;
+                       break;
+               case 1:
+                       fep->code_rate_HP = FEC_2_3;
+                       break;
+               case 2:
+                       fep->code_rate_HP = FEC_3_4;
+                       break;
+               case 3:
+                       fep->code_rate_HP = FEC_5_6;
+                       break;
+               case 4:
+                       fep->code_rate_HP = FEC_7_8;
+                       break;
+               }
+
+               switch (td->LPCodeRate) {
+               case 0:
+                       fep->code_rate_LP = FEC_1_2;
+                       break;
+               case 1:
+                       fep->code_rate_LP = FEC_2_3;
+                       break;
+               case 2:
+                       fep->code_rate_LP = FEC_3_4;
+                       break;
+               case 3:
+                       fep->code_rate_LP = FEC_5_6;
+                       break;
+               case 4:
+                       fep->code_rate_LP = FEC_7_8;
+                       break;
+               }
+
+               switch (td->Constellation) {
+               case 0:
+                       fep->modulation = QPSK;
+                       break;
+               case 1:
+                       fep->modulation = QAM_16;
+                       break;
+               case 2:
+                       fep->modulation = QAM_64;
+                       break;
+               }
+
+               switch (td->Hierarchy) {
+               case 0:
+                       fep->hierarchy = HIERARCHY_NONE;
+                       break;
+               case 1:
+                       fep->hierarchy = HIERARCHY_1;
+                       break;
+               case 2:
+                       fep->hierarchy = HIERARCHY_2;
+                       break;
+               case 3:
+                       fep->hierarchy = HIERARCHY_4;
+                       break;
+               }
+
+               fep->inversion = INVERSION_AUTO;
+               break;
+       case DEVICE_MODE_ISDBT:
+       case DEVICE_MODE_ISDBT_BDA:
+               fep->frequency = td->Frequency;
+               fep->bandwidth_hz = 6000000;
+               /* todo: retrive the other parameters */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int smsdvb_init(struct dvb_frontend *fe)
+{
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+
+       sms_board_power(client->coredev, 1);
+
+       sms_board_dvb3_event(client, DVB3_EVENT_INIT);
+       return 0;
+}
+
+static int smsdvb_sleep(struct dvb_frontend *fe)
+{
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+
+       sms_board_led_feedback(client->coredev, SMS_LED_OFF);
+       sms_board_power(client->coredev, 0);
+
+       sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
+
+       return 0;
+}
+
+static void smsdvb_release(struct dvb_frontend *fe)
+{
+       /* do nothing */
+}
+
+static struct dvb_frontend_ops smsdvb_fe_ops = {
+       .info = {
+               .name                   = "Siano Mobile Digital MDTV Receiver",
+               .frequency_min          = 44250000,
+               .frequency_max          = 867250000,
+               .frequency_stepsize     = 250000,
+               .caps = FE_CAN_INVERSION_AUTO |
+                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+                       FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_RECOVER |
+                       FE_CAN_HIERARCHY_AUTO,
+       },
+
+       .release = smsdvb_release,
+
+       .set_frontend = smsdvb_set_frontend,
+       .get_frontend = smsdvb_get_frontend,
+       .get_tune_settings = smsdvb_get_tune_settings,
+
+       .read_status = smsdvb_read_status,
+       .read_ber = smsdvb_read_ber,
+       .read_signal_strength = smsdvb_read_signal_strength,
+       .read_snr = smsdvb_read_snr,
+       .read_ucblocks = smsdvb_read_ucblocks,
+
+       .init = smsdvb_init,
+       .sleep = smsdvb_sleep,
+};
+
+static int smsdvb_hotplug(struct smscore_device_t *coredev,
+                         struct device *device, int arrival)
+{
+       struct smsclient_params_t params;
+       struct smsdvb_client_t *client;
+       int rc;
+
+       /* device removal handled by onremove callback */
+       if (!arrival)
+               return 0;
+       client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
+       if (!client) {
+               sms_err("kmalloc() failed");
+               return -ENOMEM;
+       }
+
+       /* register dvb adapter */
+       rc = dvb_register_adapter(&client->adapter,
+                                 sms_get_board(
+                                       smscore_get_board_id(coredev))->name,
+                                 THIS_MODULE, device, adapter_nr);
+       if (rc < 0) {
+               sms_err("dvb_register_adapter() failed %d", rc);
+               goto adapter_error;
+       }
+
+       /* init dvb demux */
+       client->demux.dmx.capabilities = DMX_TS_FILTERING;
+       client->demux.filternum = 32; /* todo: nova ??? */
+       client->demux.feednum = 32;
+       client->demux.start_feed = smsdvb_start_feed;
+       client->demux.stop_feed = smsdvb_stop_feed;
+
+       rc = dvb_dmx_init(&client->demux);
+       if (rc < 0) {
+               sms_err("dvb_dmx_init failed %d", rc);
+               goto dvbdmx_error;
+       }
+
+       /* init dmxdev */
+       client->dmxdev.filternum = 32;
+       client->dmxdev.demux = &client->demux.dmx;
+       client->dmxdev.capabilities = 0;
+
+       rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
+       if (rc < 0) {
+               sms_err("dvb_dmxdev_init failed %d", rc);
+               goto dmxdev_error;
+       }
+
+       /* init and register frontend */
+       memcpy(&client->frontend.ops, &smsdvb_fe_ops,
+              sizeof(struct dvb_frontend_ops));
+
+       switch (smscore_get_device_mode(coredev)) {
+       case DEVICE_MODE_DVBT:
+       case DEVICE_MODE_DVBT_BDA:
+               client->frontend.ops.delsys[0] = SYS_DVBT;
+               break;
+       case DEVICE_MODE_ISDBT:
+       case DEVICE_MODE_ISDBT_BDA:
+               client->frontend.ops.delsys[0] = SYS_ISDBT;
+               break;
+       }
+
+       rc = dvb_register_frontend(&client->adapter, &client->frontend);
+       if (rc < 0) {
+               sms_err("frontend registration failed %d", rc);
+               goto frontend_error;
+       }
+
+       params.initial_id = 1;
+       params.data_type = MSG_SMS_DVBT_BDA_DATA;
+       params.onresponse_handler = smsdvb_onresponse;
+       params.onremove_handler = smsdvb_onremove;
+       params.context = client;
+
+       rc = smscore_register_client(coredev, &params, &client->smsclient);
+       if (rc < 0) {
+               sms_err("smscore_register_client() failed %d", rc);
+               goto client_error;
+       }
+
+       client->coredev = coredev;
+
+       init_completion(&client->tune_done);
+
+       kmutex_lock(&g_smsdvb_clientslock);
+
+       list_add(&client->entry, &g_smsdvb_clients);
+
+       kmutex_unlock(&g_smsdvb_clientslock);
+
+       client->event_fe_state = -1;
+       client->event_unc_state = -1;
+       sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
+
+       sms_info("success");
+       sms_board_setup(coredev);
+
+       return 0;
+
+client_error:
+       dvb_unregister_frontend(&client->frontend);
+
+frontend_error:
+       dvb_dmxdev_release(&client->dmxdev);
+
+dmxdev_error:
+       dvb_dmx_release(&client->demux);
+
+dvbdmx_error:
+       dvb_unregister_adapter(&client->adapter);
+
+adapter_error:
+       kfree(client);
+       return rc;
+}
+
+static int __init smsdvb_module_init(void)
+{
+       int rc;
+
+       INIT_LIST_HEAD(&g_smsdvb_clients);
+       kmutex_init(&g_smsdvb_clientslock);
+
+       rc = smscore_register_hotplug(smsdvb_hotplug);
+
+       sms_debug("");
+
+       return rc;
+}
+
+static void __exit smsdvb_module_exit(void)
+{
+       smscore_unregister_hotplug(smsdvb_hotplug);
+
+       kmutex_lock(&g_smsdvb_clientslock);
+
+       while (!list_empty(&g_smsdvb_clients))
+              smsdvb_unregister_client(
+                       (struct smsdvb_client_t *) g_smsdvb_clients.next);
+
+       kmutex_unlock(&g_smsdvb_clientslock);
+}
+
+module_init(smsdvb_module_init);
+module_exit(smsdvb_module_exit);
+
+MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/siano/smsendian.c b/drivers/media/common/siano/smsendian.c
new file mode 100644 (file)
index 0000000..e2657c2
--- /dev/null
@@ -0,0 +1,103 @@
+/****************************************************************
+
+ Siano Mobile Silicon, Inc.
+ MDTV receiver kernel modules.
+ Copyright (C) 2006-2009, Uri Shkolnik
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+ ****************************************************************/
+
+#include <linux/export.h>
+#include <asm/byteorder.h>
+
+#include "smsendian.h"
+#include "smscoreapi.h"
+
+void smsendian_handle_tx_message(void *buffer)
+{
+#ifdef __BIG_ENDIAN
+       struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
+       int i;
+       int msgWords;
+
+       switch (msg->xMsgHeader.msgType) {
+       case MSG_SMS_DATA_DOWNLOAD_REQ:
+       {
+               msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
+               break;
+       }
+
+       default:
+               msgWords = (msg->xMsgHeader.msgLength -
+                               sizeof(struct SmsMsgHdr_ST))/4;
+
+               for (i = 0; i < msgWords; i++)
+                       msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
+
+               break;
+       }
+#endif /* __BIG_ENDIAN */
+}
+EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
+
+void smsendian_handle_rx_message(void *buffer)
+{
+#ifdef __BIG_ENDIAN
+       struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
+       int i;
+       int msgWords;
+
+       switch (msg->xMsgHeader.msgType) {
+       case MSG_SMS_GET_VERSION_EX_RES:
+       {
+               struct SmsVersionRes_ST *ver =
+                       (struct SmsVersionRes_ST *) msg;
+               ver->ChipModel = le16_to_cpu(ver->ChipModel);
+               break;
+       }
+
+       case MSG_SMS_DVBT_BDA_DATA:
+       case MSG_SMS_DAB_CHANNEL:
+       case MSG_SMS_DATA_MSG:
+       {
+               break;
+       }
+
+       default:
+       {
+               msgWords = (msg->xMsgHeader.msgLength -
+                               sizeof(struct SmsMsgHdr_ST))/4;
+
+               for (i = 0; i < msgWords; i++)
+                       msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
+
+               break;
+       }
+       }
+#endif /* __BIG_ENDIAN */
+}
+EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
+
+void smsendian_handle_message_header(void *msg)
+{
+#ifdef __BIG_ENDIAN
+       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
+
+       phdr->msgType = le16_to_cpu(phdr->msgType);
+       phdr->msgLength = le16_to_cpu(phdr->msgLength);
+       phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
+#endif /* __BIG_ENDIAN */
+}
+EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/common/siano/smsendian.h b/drivers/media/common/siano/smsendian.h
new file mode 100644 (file)
index 0000000..1624d6f
--- /dev/null
@@ -0,0 +1,32 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2009, Uri Shkolnik
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#ifndef __SMS_ENDIAN_H__
+#define __SMS_ENDIAN_H__
+
+#include <asm/byteorder.h>
+
+extern void smsendian_handle_tx_message(void *buffer);
+extern void smsendian_handle_rx_message(void *buffer);
+extern void smsendian_handle_message_header(void *msg);
+
+#endif /* __SMS_ENDIAN_H__ */
+
diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c
new file mode 100644 (file)
index 0000000..37bc5c4
--- /dev/null
@@ -0,0 +1,114 @@
+/****************************************************************
+
+ Siano Mobile Silicon, Inc.
+ MDTV receiver kernel modules.
+ Copyright (C) 2006-2009, Uri Shkolnik
+
+ Copyright (c) 2010 - Mauro Carvalho Chehab
+       - Ported the driver to use rc-core
+       - IR raw event decoding is now done at rc-core
+       - Code almost re-written
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+ ****************************************************************/
+
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+#include "smscoreapi.h"
+#include "smsir.h"
+#include "sms-cards.h"
+
+#define MODULE_NAME "smsmdtv"
+
+void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
+{
+       int i;
+       const s32 *samples = (const void *)buf;
+
+       for (i = 0; i < len >> 2; i++) {
+               DEFINE_IR_RAW_EVENT(ev);
+
+               ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
+               ev.pulse = (samples[i] > 0) ? false : true;
+
+               ir_raw_event_store(coredev->ir.dev, &ev);
+       }
+       ir_raw_event_handle(coredev->ir.dev);
+}
+
+int sms_ir_init(struct smscore_device_t *coredev)
+{
+       int err;
+       int board_id = smscore_get_board_id(coredev);
+       struct rc_dev *dev;
+
+       sms_log("Allocating rc device");
+       dev = rc_allocate_device();
+       if (!dev) {
+               sms_err("Not enough memory");
+               return -ENOMEM;
+       }
+
+       coredev->ir.controller = 0;     /* Todo: vega/nova SPI number */
+       coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
+       sms_log("IR port %d, timeout %d ms",
+                       coredev->ir.controller, coredev->ir.timeout);
+
+       snprintf(coredev->ir.name, sizeof(coredev->ir.name),
+                "SMS IR (%s)", sms_get_board(board_id)->name);
+
+       strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
+       strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
+
+       dev->input_name = coredev->ir.name;
+       dev->input_phys = coredev->ir.phys;
+       dev->dev.parent = coredev->device;
+
+#if 0
+       /* TODO: properly initialize the parameters bellow */
+       dev->input_id.bustype = BUS_USB;
+       dev->input_id.version = 1;
+       dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+       dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+#endif
+
+       dev->priv = coredev;
+       dev->driver_type = RC_DRIVER_IR_RAW;
+       dev->allowed_protos = RC_TYPE_ALL;
+       dev->map_name = sms_get_board(board_id)->rc_codes;
+       dev->driver_name = MODULE_NAME;
+
+       sms_log("Input device (IR) %s is set for key events", dev->input_name);
+
+       err = rc_register_device(dev);
+       if (err < 0) {
+               sms_err("Failed to register device");
+               rc_free_device(dev);
+               return err;
+       }
+
+       coredev->ir.dev = dev;
+       return 0;
+}
+
+void sms_ir_exit(struct smscore_device_t *coredev)
+{
+       if (coredev->ir.dev)
+               rc_unregister_device(coredev->ir.dev);
+
+       sms_log("");
+}
diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h
new file mode 100644 (file)
index 0000000..ae92b3a
--- /dev/null
@@ -0,0 +1,55 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2009, Uri Shkolnik
+
+ Copyright (c) 2010 - Mauro Carvalho Chehab
+       - Ported the driver to use rc-core
+       - IR raw event decoding is now done at rc-core
+       - Code almost re-written
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#ifndef __SMS_IR_H__
+#define __SMS_IR_H__
+
+#include <linux/input.h>
+#include <media/rc-core.h>
+
+#define IR_DEFAULT_TIMEOUT             100
+
+struct smscore_device_t;
+
+struct ir_t {
+       struct rc_dev *dev;
+       char name[40];
+       char phys[32];
+
+       char *rc_codes;
+       u64 protocol;
+
+       u32 timeout;
+       u32 controller;
+};
+
+int sms_ir_init(struct smscore_device_t *coredev);
+void sms_ir_exit(struct smscore_device_t *coredev);
+void sms_ir_event(struct smscore_device_t *coredev,
+                       const char *buf, int len);
+
+#endif /* __SMS_IR_H__ */
+
diff --git a/drivers/media/mmc/Kconfig b/drivers/media/mmc/Kconfig
new file mode 100644 (file)
index 0000000..0f2a957
--- /dev/null
@@ -0,0 +1 @@
+source "drivers/media/mmc/siano/Kconfig"
diff --git a/drivers/media/mmc/Makefile b/drivers/media/mmc/Makefile
new file mode 100644 (file)
index 0000000..dacd3cb
--- /dev/null
@@ -0,0 +1 @@
+obj-y := siano/
diff --git a/drivers/media/mmc/siano/Kconfig b/drivers/media/mmc/siano/Kconfig
new file mode 100644 (file)
index 0000000..fa62475
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Siano Mobile Silicon Digital TV device configuration
+#
+
+config SMS_SDIO_DRV
+       tristate "Siano SMS1xxx based MDTV via SDIO interface"
+       depends on DVB_CORE && RC_CORE && HAS_DMA
+       depends on MMC
+       ---help---
+         Choose if you would like to have Siano's support for SDIO interface
diff --git a/drivers/media/mmc/siano/Makefile b/drivers/media/mmc/siano/Makefile
new file mode 100644 (file)
index 0000000..0e01f97
--- /dev/null
@@ -0,0 +1,6 @@
+obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/common/siano
+ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
+
diff --git a/drivers/media/mmc/siano/smssdio.c b/drivers/media/mmc/siano/smssdio.c
new file mode 100644 (file)
index 0000000..d6f3f10
--- /dev/null
@@ -0,0 +1,365 @@
+/*
+ *  smssdio.c - Siano 1xxx SDIO interface driver
+ *
+ *  Copyright 2008 Pierre Ossman
+ *
+ * Based on code by Siano Mobile Silicon, Inc.,
+ * Copyright (C) 2006-2008, Uri Shkolnik
+ *
+ * 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 hardware is a bit odd in that all transfers should be done
+ * to/from the SMSSDIO_DATA register, yet the "increase address" bit
+ * always needs to be set.
+ *
+ * Also, buffers from the card are always aligned to 128 byte
+ * boundaries.
+ */
+
+/*
+ * General cleanup notes:
+ *
+ * - only typedefs should be name *_t
+ *
+ * - use ERR_PTR and friends for smscore_register_device()
+ *
+ * - smscore_getbuffer should zero fields
+ *
+ * Fix stop command
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/module.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+
+/* Registers */
+
+#define SMSSDIO_DATA           0x00
+#define SMSSDIO_INT            0x04
+#define SMSSDIO_BLOCK_SIZE     128
+
+static const struct sdio_device_id smssdio_ids[] __devinitconst = {
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
+        .driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
+        .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A},
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0),
+        .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B},
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0),
+        .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
+       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE),
+        .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
+       { /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(sdio, smssdio_ids);
+
+struct smssdio_device {
+       struct sdio_func *func;
+
+       struct smscore_device_t *coredev;
+
+       struct smscore_buffer_t *split_cb;
+};
+
+/*******************************************************************/
+/* Siano core callbacks                                            */
+/*******************************************************************/
+
+static int smssdio_sendrequest(void *context, void *buffer, size_t size)
+{
+       int ret = 0;
+       struct smssdio_device *smsdev;
+
+       smsdev = context;
+
+       sdio_claim_host(smsdev->func);
+
+       while (size >= smsdev->func->cur_blksize) {
+               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
+                                       buffer, smsdev->func->cur_blksize);
+               if (ret)
+                       goto out;
+
+               buffer += smsdev->func->cur_blksize;
+               size -= smsdev->func->cur_blksize;
+       }
+
+       if (size) {
+               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
+                                       buffer, size);
+       }
+
+out:
+       sdio_release_host(smsdev->func);
+
+       return ret;
+}
+
+/*******************************************************************/
+/* SDIO callbacks                                                  */
+/*******************************************************************/
+
+static void smssdio_interrupt(struct sdio_func *func)
+{
+       int ret;
+
+       struct smssdio_device *smsdev;
+       struct smscore_buffer_t *cb;
+       struct SmsMsgHdr_ST *hdr;
+       size_t size;
+
+       smsdev = sdio_get_drvdata(func);
+
+       /*
+        * The interrupt register has no defined meaning. It is just
+        * a way of turning of the level triggered interrupt.
+        */
+       (void)sdio_readb(func, SMSSDIO_INT, &ret);
+       if (ret) {
+               sms_err("Unable to read interrupt register!\n");
+               return;
+       }
+
+       if (smsdev->split_cb == NULL) {
+               cb = smscore_getbuffer(smsdev->coredev);
+               if (!cb) {
+                       sms_err("Unable to allocate data buffer!\n");
+                       return;
+               }
+
+               ret = sdio_memcpy_fromio(smsdev->func,
+                                        cb->p,
+                                        SMSSDIO_DATA,
+                                        SMSSDIO_BLOCK_SIZE);
+               if (ret) {
+                       sms_err("Error %d reading initial block!\n", ret);
+                       return;
+               }
+
+               hdr = cb->p;
+
+               if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) {
+                       smsdev->split_cb = cb;
+                       return;
+               }
+
+               if (hdr->msgLength > smsdev->func->cur_blksize)
+                       size = hdr->msgLength - smsdev->func->cur_blksize;
+               else
+                       size = 0;
+       } else {
+               cb = smsdev->split_cb;
+               hdr = cb->p;
+
+               size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST);
+
+               smsdev->split_cb = NULL;
+       }
+
+       if (size) {
+               void *buffer;
+
+               buffer = cb->p + (hdr->msgLength - size);
+               size = ALIGN(size, SMSSDIO_BLOCK_SIZE);
+
+               BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE);
+
+               /*
+                * First attempt to transfer all of it in one go...
+                */
+               ret = sdio_memcpy_fromio(smsdev->func,
+                                        buffer,
+                                        SMSSDIO_DATA,
+                                        size);
+               if (ret && ret != -EINVAL) {
+                       smscore_putbuffer(smsdev->coredev, cb);
+                       sms_err("Error %d reading data from card!\n", ret);
+                       return;
+               }
+
+               /*
+                * ..then fall back to one block at a time if that is
+                * not possible...
+                *
+                * (we have to do this manually because of the
+                * problem with the "increase address" bit)
+                */
+               if (ret == -EINVAL) {
+                       while (size) {
+                               ret = sdio_memcpy_fromio(smsdev->func,
+                                                 buffer, SMSSDIO_DATA,
+                                                 smsdev->func->cur_blksize);
+                               if (ret) {
+                                       smscore_putbuffer(smsdev->coredev, cb);
+                                       sms_err("Error %d reading "
+                                               "data from card!\n", ret);
+                                       return;
+                               }
+
+                               buffer += smsdev->func->cur_blksize;
+                               if (size > smsdev->func->cur_blksize)
+                                       size -= smsdev->func->cur_blksize;
+                               else
+                                       size = 0;
+                       }
+               }
+       }
+
+       cb->size = hdr->msgLength;
+       cb->offset = 0;
+
+       smscore_onresponse(smsdev->coredev, cb);
+}
+
+static int __devinit smssdio_probe(struct sdio_func *func,
+                        const struct sdio_device_id *id)
+{
+       int ret;
+
+       int board_id;
+       struct smssdio_device *smsdev;
+       struct smsdevice_params_t params;
+
+       board_id = id->driver_data;
+
+       smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL);
+       if (!smsdev)
+               return -ENOMEM;
+
+       smsdev->func = func;
+
+       memset(&params, 0, sizeof(struct smsdevice_params_t));
+
+       params.device = &func->dev;
+       params.buffer_size = 0x5000;    /* ?? */
+       params.num_buffers = 22;        /* ?? */
+       params.context = smsdev;
+
+       snprintf(params.devpath, sizeof(params.devpath),
+                "sdio\\%s", sdio_func_id(func));
+
+       params.sendrequest_handler = smssdio_sendrequest;
+
+       params.device_type = sms_get_board(board_id)->type;
+
+       if (params.device_type != SMS_STELLAR)
+               params.flags |= SMS_DEVICE_FAMILY2;
+       else {
+               /*
+                * FIXME: Stellar needs special handling...
+                */
+               ret = -ENODEV;
+               goto free;
+       }
+
+       ret = smscore_register_device(&params, &smsdev->coredev);
+       if (ret < 0)
+               goto free;
+
+       smscore_set_board_id(smsdev->coredev, board_id);
+
+       sdio_claim_host(func);
+
+       ret = sdio_enable_func(func);
+       if (ret)
+               goto release;
+
+       ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE);
+       if (ret)
+               goto disable;
+
+       ret = sdio_claim_irq(func, smssdio_interrupt);
+       if (ret)
+               goto disable;
+
+       sdio_set_drvdata(func, smsdev);
+
+       sdio_release_host(func);
+
+       ret = smscore_start_device(smsdev->coredev);
+       if (ret < 0)
+               goto reclaim;
+
+       return 0;
+
+reclaim:
+       sdio_claim_host(func);
+       sdio_release_irq(func);
+disable:
+       sdio_disable_func(func);
+release:
+       sdio_release_host(func);
+       smscore_unregister_device(smsdev->coredev);
+free:
+       kfree(smsdev);
+
+       return ret;
+}
+
+static void smssdio_remove(struct sdio_func *func)
+{
+       struct smssdio_device *smsdev;
+
+       smsdev = sdio_get_drvdata(func);
+
+       /* FIXME: racy! */
+       if (smsdev->split_cb)
+               smscore_putbuffer(smsdev->coredev, smsdev->split_cb);
+
+       smscore_unregister_device(smsdev->coredev);
+
+       sdio_claim_host(func);
+       sdio_release_irq(func);
+       sdio_disable_func(func);
+       sdio_release_host(func);
+
+       kfree(smsdev);
+}
+
+static struct sdio_driver smssdio_driver = {
+       .name = "smssdio",
+       .id_table = smssdio_ids,
+       .probe = smssdio_probe,
+       .remove = smssdio_remove,
+};
+
+/*******************************************************************/
+/* Module functions                                                */
+/*******************************************************************/
+
+static int __init smssdio_module_init(void)
+{
+       int ret = 0;
+
+       printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n");
+       printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n");
+
+       ret = sdio_register_driver(&smssdio_driver);
+
+       return ret;
+}
+
+static void __exit smssdio_module_exit(void)
+{
+       sdio_unregister_driver(&smssdio_driver);
+}
+
+module_init(smssdio_module_init);
+module_exit(smssdio_module_exit);
+
+MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver");
+MODULE_AUTHOR("Pierre Ossman");
+MODULE_LICENSE("GPL");
index bc6456eb2c4fda8a5528e3b9b68b6014bdaccc19..3c76e62d820da4ac3ccffe8f8f4cbe6b3229451d 100644 (file)
@@ -2,33 +2,9 @@
 # Siano Mobile Silicon Digital TV device configuration
 #
 
-config SMS_SIANO_MDTV
+config SMS_USB_DRV
        tristate "Siano SMS1xxx based MDTV receiver"
        depends on DVB_CORE && RC_CORE && HAS_DMA
-       ---help---
-         Choose Y or M here if you have MDTV receiver with a Siano chipset.
-
-         To compile this driver as a module, choose M here
-         (The module will be called smsmdtv).
-
-         Further documentation on this driver can be found on the WWW
-         at http://www.siano-ms.com/
-
-if SMS_SIANO_MDTV
-menu "Siano module components"
-
-# Hardware interfaces support
-
-config SMS_USB_DRV
-       tristate "USB interface support"
-       depends on DVB_CORE && USB
        ---help---
          Choose if you would like to have Siano's support for USB interface
 
-config SMS_SDIO_DRV
-       tristate "SDIO interface support"
-       depends on DVB_CORE && MMC
-       ---help---
-         Choose if you would like to have Siano's support for SDIO interface
-endmenu
-endif # SMS_SIANO_MDTV
index 14756bdb6eaa055954d08dbd06790bc898842722..758b6a090c5955c86d84d01e902b666fa86cf21b 100644 (file)
@@ -1,11 +1,6 @@
-
-smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
-
-obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
 obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
-obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
 
 ccflags-y += -Idrivers/media/dvb-core
-
+ccflags-y += -Idrivers/media/common/siano
 ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
 
diff --git a/drivers/media/usb/siano/sms-cards.c b/drivers/media/usb/siano/sms-cards.c
deleted file mode 100644 (file)
index 680c781..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- *  Card-specific functions for the Siano SMS1xxx USB dongle
- *
- *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
- *
- *  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;
- *
- *  Software distributed under the License is distributed on an "AS IS"
- *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
- *
- *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "sms-cards.h"
-#include "smsir.h"
-#include <linux/module.h>
-
-static int sms_dbg;
-module_param_named(cards_dbg, sms_dbg, int, 0644);
-MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
-
-static struct sms_board sms_boards[] = {
-       [SMS_BOARD_UNKNOWN] = {
-               .name   = "Unknown board",
-       },
-       [SMS1XXX_BOARD_SIANO_STELLAR] = {
-               .name   = "Siano Stellar Digital Receiver",
-               .type   = SMS_STELLAR,
-       },
-       [SMS1XXX_BOARD_SIANO_NOVA_A] = {
-               .name   = "Siano Nova A Digital Receiver",
-               .type   = SMS_NOVA_A0,
-       },
-       [SMS1XXX_BOARD_SIANO_NOVA_B] = {
-               .name   = "Siano Nova B Digital Receiver",
-               .type   = SMS_NOVA_B0,
-       },
-       [SMS1XXX_BOARD_SIANO_VEGA] = {
-               .name   = "Siano Vega Digital Receiver",
-               .type   = SMS_VEGA,
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
-               .name   = "Hauppauge Catamount",
-               .type   = SMS_STELLAR,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
-               .name   = "Hauppauge Okemo-A",
-               .type   = SMS_NOVA_A0,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
-               .name   = "Hauppauge Okemo-B",
-               .type   = SMS_NOVA_B0,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
-               .name   = "Hauppauge WinTV MiniStick",
-               .type   = SMS_NOVA_B0,
-               .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
-               .rc_codes = RC_MAP_HAUPPAUGE,
-               .board_cfg.leds_power = 26,
-               .board_cfg.led0 = 27,
-               .board_cfg.led1 = 28,
-               .board_cfg.ir = 9,
-               .led_power = 26,
-               .led_lo    = 27,
-               .led_hi    = 28,
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
-               .name   = "Hauppauge WinTV MiniCard",
-               .type   = SMS_NOVA_B0,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
-               .lna_ctrl  = 29,
-               .board_cfg.foreign_lna0_ctrl = 29,
-               .rf_switch = 17,
-               .board_cfg.rf_switch_uhf = 17,
-       },
-       [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
-               .name   = "Hauppauge WinTV MiniCard",
-               .type   = SMS_NOVA_B0,
-               .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
-               .lna_ctrl  = -1,
-       },
-       [SMS1XXX_BOARD_SIANO_NICE] = {
-       /* 11 */
-               .name = "Siano Nice Digital Receiver",
-               .type = SMS_NOVA_B0,
-       },
-       [SMS1XXX_BOARD_SIANO_VENICE] = {
-       /* 12 */
-               .name = "Siano Venice Digital Receiver",
-               .type = SMS_VEGA,
-       },
-};
-
-struct sms_board *sms_get_board(unsigned id)
-{
-       BUG_ON(id >= ARRAY_SIZE(sms_boards));
-
-       return &sms_boards[id];
-}
-EXPORT_SYMBOL_GPL(sms_get_board);
-static inline void sms_gpio_assign_11xx_default_led_config(
-               struct smscore_gpio_config *pGpioConfig) {
-       pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
-       pGpioConfig->InputCharacteristics =
-               SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
-       pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
-       pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
-       pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
-}
-
-int sms_board_event(struct smscore_device_t *coredev,
-               enum SMS_BOARD_EVENTS gevent) {
-       struct smscore_gpio_config MyGpioConfig;
-
-       sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
-
-       switch (gevent) {
-       case BOARD_EVENT_POWER_INIT: /* including hotplug */
-               break; /* BOARD_EVENT_BIND */
-
-       case BOARD_EVENT_POWER_SUSPEND:
-               break; /* BOARD_EVENT_POWER_SUSPEND */
-
-       case BOARD_EVENT_POWER_RESUME:
-               break; /* BOARD_EVENT_POWER_RESUME */
-
-       case BOARD_EVENT_BIND:
-               break; /* BOARD_EVENT_BIND */
-
-       case BOARD_EVENT_SCAN_PROG:
-               break; /* BOARD_EVENT_SCAN_PROG */
-       case BOARD_EVENT_SCAN_COMP:
-               break; /* BOARD_EVENT_SCAN_COMP */
-       case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
-               break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
-       case BOARD_EVENT_FE_LOCK:
-               break; /* BOARD_EVENT_FE_LOCK */
-       case BOARD_EVENT_FE_UNLOCK:
-               break; /* BOARD_EVENT_FE_UNLOCK */
-       case BOARD_EVENT_DEMOD_LOCK:
-               break; /* BOARD_EVENT_DEMOD_LOCK */
-       case BOARD_EVENT_DEMOD_UNLOCK:
-               break; /* BOARD_EVENT_DEMOD_UNLOCK */
-       case BOARD_EVENT_RECEPTION_MAX_4:
-               break; /* BOARD_EVENT_RECEPTION_MAX_4 */
-       case BOARD_EVENT_RECEPTION_3:
-               break; /* BOARD_EVENT_RECEPTION_3 */
-       case BOARD_EVENT_RECEPTION_2:
-               break; /* BOARD_EVENT_RECEPTION_2 */
-       case BOARD_EVENT_RECEPTION_1:
-               break; /* BOARD_EVENT_RECEPTION_1 */
-       case BOARD_EVENT_RECEPTION_LOST_0:
-               break; /* BOARD_EVENT_RECEPTION_LOST_0 */
-       case BOARD_EVENT_MULTIPLEX_OK:
-               break; /* BOARD_EVENT_MULTIPLEX_OK */
-       case BOARD_EVENT_MULTIPLEX_ERRORS:
-               break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
-
-       default:
-               sms_err("Unknown SMS board event");
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_event);
-
-static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
-{
-       int lvl, ret;
-       u32 gpio;
-       struct smscore_config_gpio gpioconfig = {
-               .direction            = SMS_GPIO_DIRECTION_OUTPUT,
-               .pullupdown           = SMS_GPIO_PULLUPDOWN_NONE,
-               .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
-               .outputslewrate       = SMS_GPIO_OUTPUTSLEWRATE_FAST,
-               .outputdriving        = SMS_GPIO_OUTPUTDRIVING_4mA,
-       };
-
-       if (pin == 0)
-               return -EINVAL;
-
-       if (pin < 0) {
-               /* inverted gpio */
-               gpio = pin * -1;
-               lvl = enable ? 0 : 1;
-       } else {
-               gpio = pin;
-               lvl = enable ? 1 : 0;
-       }
-
-       ret = smscore_configure_gpio(coredev, gpio, &gpioconfig);
-       if (ret < 0)
-               return ret;
-
-       return smscore_set_gpio(coredev, gpio, lvl);
-}
-
-int sms_board_setup(struct smscore_device_t *coredev)
-{
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
-
-       switch (board_id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-               /* turn off all LEDs */
-               sms_set_gpio(coredev, board->led_power, 0);
-               sms_set_gpio(coredev, board->led_hi, 0);
-               sms_set_gpio(coredev, board->led_lo, 0);
-               break;
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-               /* turn off LNA */
-               sms_set_gpio(coredev, board->lna_ctrl, 0);
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_setup);
-
-int sms_board_power(struct smscore_device_t *coredev, int onoff)
-{
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
-
-       switch (board_id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-               /* power LED */
-               sms_set_gpio(coredev,
-                            board->led_power, onoff ? 1 : 0);
-               break;
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-               /* LNA */
-               if (!onoff)
-                       sms_set_gpio(coredev, board->lna_ctrl, 0);
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_power);
-
-int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
-{
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
-
-       /* dont touch GPIO if LEDs are already set */
-       if (smscore_led_state(coredev, -1) == led)
-               return 0;
-
-       switch (board_id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-               sms_set_gpio(coredev,
-                            board->led_lo, (led & SMS_LED_LO) ? 1 : 0);
-               sms_set_gpio(coredev,
-                            board->led_hi, (led & SMS_LED_HI) ? 1 : 0);
-
-               smscore_led_state(coredev, led);
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_led_feedback);
-
-int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
-{
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
-
-       sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
-
-       switch (board_id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-               sms_set_gpio(coredev,
-                            board->rf_switch, onoff ? 1 : 0);
-               return sms_set_gpio(coredev,
-                                   board->lna_ctrl, onoff ? 1 : 0);
-       }
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(sms_board_lna_control);
-
-int sms_board_load_modules(int id)
-{
-       switch (id) {
-       case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
-       case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
-       case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
-       case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-       case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               request_module("smsdvb");
-               break;
-       default:
-               /* do nothing */
-               break;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/usb/siano/sms-cards.h b/drivers/media/usb/siano/sms-cards.h
deleted file mode 100644 (file)
index d8cdf75..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *  Card-specific functions for the Siano SMS1xxx USB dongle
- *
- *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
- *
- *  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;
- *
- *  Software distributed under the License is distributed on an "AS IS"
- *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
- *
- *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __SMS_CARDS_H__
-#define __SMS_CARDS_H__
-
-#include <linux/usb.h>
-#include "smscoreapi.h"
-#include "smsir.h"
-
-#define SMS_BOARD_UNKNOWN 0
-#define SMS1XXX_BOARD_SIANO_STELLAR 1
-#define SMS1XXX_BOARD_SIANO_NOVA_A  2
-#define SMS1XXX_BOARD_SIANO_NOVA_B  3
-#define SMS1XXX_BOARD_SIANO_VEGA    4
-#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5
-#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6
-#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7
-#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
-#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9
-#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
-#define SMS1XXX_BOARD_SIANO_NICE       11
-#define SMS1XXX_BOARD_SIANO_VENICE     12
-
-struct sms_board_gpio_cfg {
-       int lna_vhf_exist;
-       int lna_vhf_ctrl;
-       int lna_uhf_exist;
-       int lna_uhf_ctrl;
-       int lna_uhf_d_ctrl;
-       int lna_sband_exist;
-       int lna_sband_ctrl;
-       int lna_sband_d_ctrl;
-       int foreign_lna0_ctrl;
-       int foreign_lna1_ctrl;
-       int foreign_lna2_ctrl;
-       int rf_switch_vhf;
-       int rf_switch_uhf;
-       int rf_switch_sband;
-       int leds_power;
-       int led0;
-       int led1;
-       int led2;
-       int led3;
-       int led4;
-       int ir;
-       int eeprom_wp;
-       int mrc_sense;
-       int mrc_pdn_resetn;
-       int mrc_gp0; /* mrcs spi int */
-       int mrc_gp1;
-       int mrc_gp2;
-       int mrc_gp3;
-       int mrc_gp4;
-       int host_spi_gsp_ts_int;
-};
-
-struct sms_board {
-       enum sms_device_type_st type;
-       char *name, *fw[DEVICE_MODE_MAX];
-       struct sms_board_gpio_cfg board_cfg;
-       char *rc_codes;                         /* Name of IR codes table */
-
-       /* gpios */
-       int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
-};
-
-struct sms_board *sms_get_board(unsigned id);
-
-extern struct smscore_device_t *coredev;
-
-enum SMS_BOARD_EVENTS {
-       BOARD_EVENT_POWER_INIT,
-       BOARD_EVENT_POWER_SUSPEND,
-       BOARD_EVENT_POWER_RESUME,
-       BOARD_EVENT_BIND,
-       BOARD_EVENT_SCAN_PROG,
-       BOARD_EVENT_SCAN_COMP,
-       BOARD_EVENT_EMERGENCY_WARNING_SIGNAL,
-       BOARD_EVENT_FE_LOCK,
-       BOARD_EVENT_FE_UNLOCK,
-       BOARD_EVENT_DEMOD_LOCK,
-       BOARD_EVENT_DEMOD_UNLOCK,
-       BOARD_EVENT_RECEPTION_MAX_4,
-       BOARD_EVENT_RECEPTION_3,
-       BOARD_EVENT_RECEPTION_2,
-       BOARD_EVENT_RECEPTION_1,
-       BOARD_EVENT_RECEPTION_LOST_0,
-       BOARD_EVENT_MULTIPLEX_OK,
-       BOARD_EVENT_MULTIPLEX_ERRORS
-};
-
-int sms_board_event(struct smscore_device_t *coredev,
-               enum SMS_BOARD_EVENTS gevent);
-
-int sms_board_setup(struct smscore_device_t *coredev);
-
-#define SMS_LED_OFF 0
-#define SMS_LED_LO  1
-#define SMS_LED_HI  2
-int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
-int sms_board_power(struct smscore_device_t *coredev, int onoff);
-int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
-
-extern int sms_board_load_modules(int id);
-
-#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/usb/siano/smscoreapi.c b/drivers/media/usb/siano/smscoreapi.c
deleted file mode 100644 (file)
index 9cc5554..0000000
+++ /dev/null
@@ -1,1637 +0,0 @@
-/*
- *  Siano core API module
- *
- *  This file contains implementation for the interface to sms core component
- *
- *  author: Uri Shkolnik
- *
- *  Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
- *
- *  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;
- *
- *  Software distributed under the License is distributed on an "AS IS"
- *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
- *
- *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <linux/firmware.h>
-#include <linux/wait.h>
-#include <asm/byteorder.h>
-
-#include "smscoreapi.h"
-#include "sms-cards.h"
-#include "smsir.h"
-#include "smsendian.h"
-
-static int sms_dbg;
-module_param_named(debug, sms_dbg, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
-
-struct smscore_device_notifyee_t {
-       struct list_head entry;
-       hotplug_t hotplug;
-};
-
-struct smscore_idlist_t {
-       struct list_head entry;
-       int             id;
-       int             data_type;
-};
-
-struct smscore_client_t {
-       struct list_head entry;
-       struct smscore_device_t *coredev;
-       void                    *context;
-       struct list_head        idlist;
-       onresponse_t    onresponse_handler;
-       onremove_t              onremove_handler;
-};
-
-void smscore_set_board_id(struct smscore_device_t *core, int id)
-{
-       core->board_id = id;
-}
-
-int smscore_led_state(struct smscore_device_t *core, int led)
-{
-       if (led >= 0)
-               core->led_state = led;
-       return core->led_state;
-}
-EXPORT_SYMBOL_GPL(smscore_set_board_id);
-
-int smscore_get_board_id(struct smscore_device_t *core)
-{
-       return core->board_id;
-}
-EXPORT_SYMBOL_GPL(smscore_get_board_id);
-
-struct smscore_registry_entry_t {
-       struct list_head entry;
-       char                    devpath[32];
-       int                             mode;
-       enum sms_device_type_st type;
-};
-
-static struct list_head g_smscore_notifyees;
-static struct list_head g_smscore_devices;
-static struct mutex g_smscore_deviceslock;
-
-static struct list_head g_smscore_registry;
-static struct mutex g_smscore_registrylock;
-
-static int default_mode = 4;
-
-module_param(default_mode, int, 0644);
-MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
-
-static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
-{
-       struct smscore_registry_entry_t *entry;
-       struct list_head *next;
-
-       kmutex_lock(&g_smscore_registrylock);
-       for (next = g_smscore_registry.next;
-            next != &g_smscore_registry;
-            next = next->next) {
-               entry = (struct smscore_registry_entry_t *) next;
-               if (!strcmp(entry->devpath, devpath)) {
-                       kmutex_unlock(&g_smscore_registrylock);
-                       return entry;
-               }
-       }
-       entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
-       if (entry) {
-               entry->mode = default_mode;
-               strcpy(entry->devpath, devpath);
-               list_add(&entry->entry, &g_smscore_registry);
-       } else
-               sms_err("failed to create smscore_registry.");
-       kmutex_unlock(&g_smscore_registrylock);
-       return entry;
-}
-
-int smscore_registry_getmode(char *devpath)
-{
-       struct smscore_registry_entry_t *entry;
-
-       entry = smscore_find_registry(devpath);
-       if (entry)
-               return entry->mode;
-       else
-               sms_err("No registry found.");
-
-       return default_mode;
-}
-EXPORT_SYMBOL_GPL(smscore_registry_getmode);
-
-static enum sms_device_type_st smscore_registry_gettype(char *devpath)
-{
-       struct smscore_registry_entry_t *entry;
-
-       entry = smscore_find_registry(devpath);
-       if (entry)
-               return entry->type;
-       else
-               sms_err("No registry found.");
-
-       return -1;
-}
-
-void smscore_registry_setmode(char *devpath, int mode)
-{
-       struct smscore_registry_entry_t *entry;
-
-       entry = smscore_find_registry(devpath);
-       if (entry)
-               entry->mode = mode;
-       else
-               sms_err("No registry found.");
-}
-
-static void smscore_registry_settype(char *devpath,
-                                    enum sms_device_type_st type)
-{
-       struct smscore_registry_entry_t *entry;
-
-       entry = smscore_find_registry(devpath);
-       if (entry)
-               entry->type = type;
-       else
-               sms_err("No registry found.");
-}
-
-
-static void list_add_locked(struct list_head *new, struct list_head *head,
-                           spinlock_t *lock)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(lock, flags);
-
-       list_add(new, head);
-
-       spin_unlock_irqrestore(lock, flags);
-}
-
-/**
- * register a client callback that called when device plugged in/unplugged
- * NOTE: if devices exist callback is called immediately for each device
- *
- * @param hotplug callback
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_register_hotplug(hotplug_t hotplug)
-{
-       struct smscore_device_notifyee_t *notifyee;
-       struct list_head *next, *first;
-       int rc = 0;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
-                          GFP_KERNEL);
-       if (notifyee) {
-               /* now notify callback about existing devices */
-               first = &g_smscore_devices;
-               for (next = first->next;
-                    next != first && !rc;
-                    next = next->next) {
-                       struct smscore_device_t *coredev =
-                               (struct smscore_device_t *) next;
-                       rc = hotplug(coredev, coredev->device, 1);
-               }
-
-               if (rc >= 0) {
-                       notifyee->hotplug = hotplug;
-                       list_add(&notifyee->entry, &g_smscore_notifyees);
-               } else
-                       kfree(notifyee);
-       } else
-               rc = -ENOMEM;
-
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       return rc;
-}
-EXPORT_SYMBOL_GPL(smscore_register_hotplug);
-
-/**
- * unregister a client callback that called when device plugged in/unplugged
- *
- * @param hotplug callback
- *
- */
-void smscore_unregister_hotplug(hotplug_t hotplug)
-{
-       struct list_head *next, *first;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       first = &g_smscore_notifyees;
-
-       for (next = first->next; next != first;) {
-               struct smscore_device_notifyee_t *notifyee =
-                       (struct smscore_device_notifyee_t *) next;
-               next = next->next;
-
-               if (notifyee->hotplug == hotplug) {
-                       list_del(&notifyee->entry);
-                       kfree(notifyee);
-               }
-       }
-
-       kmutex_unlock(&g_smscore_deviceslock);
-}
-EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
-
-static void smscore_notify_clients(struct smscore_device_t *coredev)
-{
-       struct smscore_client_t *client;
-
-       /* the client must call smscore_unregister_client from remove handler */
-       while (!list_empty(&coredev->clients)) {
-               client = (struct smscore_client_t *) coredev->clients.next;
-               client->onremove_handler(client->context);
-       }
-}
-
-static int smscore_notify_callbacks(struct smscore_device_t *coredev,
-                                   struct device *device, int arrival)
-{
-       struct smscore_device_notifyee_t *elem;
-       int rc = 0;
-
-       /* note: must be called under g_deviceslock */
-
-       list_for_each_entry(elem, &g_smscore_notifyees, entry) {
-               rc = elem->hotplug(coredev, device, arrival);
-               if (rc < 0)
-                       break;
-       }
-
-       return rc;
-}
-
-static struct
-smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
-                                      dma_addr_t common_buffer_phys)
-{
-       struct smscore_buffer_t *cb =
-               kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
-       if (!cb) {
-               sms_info("kmalloc(...) failed");
-               return NULL;
-       }
-
-       cb->p = buffer;
-       cb->offset_in_common = buffer - (u8 *) common_buffer;
-       cb->phys = common_buffer_phys + cb->offset_in_common;
-
-       return cb;
-}
-
-/**
- * creates coredev object for a device, prepares buffers,
- * creates buffer mappings, notifies registered hotplugs about new device.
- *
- * @param params device pointer to struct with device specific parameters
- *               and handlers
- * @param coredev pointer to a value that receives created coredev object
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_register_device(struct smsdevice_params_t *params,
-                           struct smscore_device_t **coredev)
-{
-       struct smscore_device_t *dev;
-       u8 *buffer;
-
-       dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
-       if (!dev) {
-               sms_info("kzalloc(...) failed");
-               return -ENOMEM;
-       }
-
-       /* init list entry so it could be safe in smscore_unregister_device */
-       INIT_LIST_HEAD(&dev->entry);
-
-       /* init queues */
-       INIT_LIST_HEAD(&dev->clients);
-       INIT_LIST_HEAD(&dev->buffers);
-
-       /* init locks */
-       spin_lock_init(&dev->clientslock);
-       spin_lock_init(&dev->bufferslock);
-
-       /* init completion events */
-       init_completion(&dev->version_ex_done);
-       init_completion(&dev->data_download_done);
-       init_completion(&dev->trigger_done);
-       init_completion(&dev->init_device_done);
-       init_completion(&dev->reload_start_done);
-       init_completion(&dev->resume_done);
-       init_completion(&dev->gpio_configuration_done);
-       init_completion(&dev->gpio_set_level_done);
-       init_completion(&dev->gpio_get_level_done);
-       init_completion(&dev->ir_init_done);
-
-       /* Buffer management */
-       init_waitqueue_head(&dev->buffer_mng_waitq);
-
-       /* alloc common buffer */
-       dev->common_buffer_size = params->buffer_size * params->num_buffers;
-       dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
-                                               &dev->common_buffer_phys,
-                                               GFP_KERNEL | GFP_DMA);
-       if (!dev->common_buffer) {
-               smscore_unregister_device(dev);
-               return -ENOMEM;
-       }
-
-       /* prepare dma buffers */
-       for (buffer = dev->common_buffer;
-            dev->num_buffers < params->num_buffers;
-            dev->num_buffers++, buffer += params->buffer_size) {
-               struct smscore_buffer_t *cb =
-                       smscore_createbuffer(buffer, dev->common_buffer,
-                                            dev->common_buffer_phys);
-               if (!cb) {
-                       smscore_unregister_device(dev);
-                       return -ENOMEM;
-               }
-
-               smscore_putbuffer(dev, cb);
-       }
-
-       sms_info("allocated %d buffers", dev->num_buffers);
-
-       dev->mode = DEVICE_MODE_NONE;
-       dev->context = params->context;
-       dev->device = params->device;
-       dev->setmode_handler = params->setmode_handler;
-       dev->detectmode_handler = params->detectmode_handler;
-       dev->sendrequest_handler = params->sendrequest_handler;
-       dev->preload_handler = params->preload_handler;
-       dev->postload_handler = params->postload_handler;
-
-       dev->device_flags = params->flags;
-       strcpy(dev->devpath, params->devpath);
-
-       smscore_registry_settype(dev->devpath, params->device_type);
-
-       /* add device to devices list */
-       kmutex_lock(&g_smscore_deviceslock);
-       list_add(&dev->entry, &g_smscore_devices);
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       *coredev = dev;
-
-       sms_info("device %p created", dev);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(smscore_register_device);
-
-
-static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
-               void *buffer, size_t size, struct completion *completion) {
-       int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
-       if (rc < 0) {
-               sms_info("sendrequest returned error %d", rc);
-               return rc;
-       }
-
-       return wait_for_completion_timeout(completion,
-                       msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
-                       0 : -ETIME;
-}
-
-/**
- * Starts & enables IR operations
- *
- * @return 0 on success, < 0 on error.
- */
-static int smscore_init_ir(struct smscore_device_t *coredev)
-{
-       int ir_io;
-       int rc;
-       void *buffer;
-
-       coredev->ir.dev = NULL;
-       ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
-       if (ir_io) {/* only if IR port exist we use IR sub-module */
-               sms_info("IR loading");
-               rc = sms_ir_init(coredev);
-
-               if      (rc != 0)
-                       sms_err("Error initialization DTV IR sub-module");
-               else {
-                       buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
-                                               SMS_DMA_ALIGNMENT,
-                                               GFP_KERNEL | GFP_DMA);
-                       if (buffer) {
-                               struct SmsMsgData_ST2 *msg =
-                               (struct SmsMsgData_ST2 *)
-                               SMS_ALIGN_ADDRESS(buffer);
-
-                               SMS_INIT_MSG(&msg->xMsgHeader,
-                                               MSG_SMS_START_IR_REQ,
-                                               sizeof(struct SmsMsgData_ST2));
-                               msg->msgData[0] = coredev->ir.controller;
-                               msg->msgData[1] = coredev->ir.timeout;
-
-                               smsendian_handle_tx_message(
-                                       (struct SmsMsgHdr_ST2 *)msg);
-                               rc = smscore_sendrequest_and_wait(coredev, msg,
-                                               msg->xMsgHeader. msgLength,
-                                               &coredev->ir_init_done);
-
-                               kfree(buffer);
-                       } else
-                               sms_err
-                               ("Sending IR initialization message failed");
-               }
-       } else
-               sms_info("IR port has not been detected");
-
-       return 0;
-}
-
-/**
- * sets initial device mode and notifies client hotplugs that device is ready
- *
- * @param coredev pointer to a coredev object returned by
- *               smscore_register_device
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_start_device(struct smscore_device_t *coredev)
-{
-       int rc = smscore_set_device_mode(
-                       coredev, smscore_registry_getmode(coredev->devpath));
-       if (rc < 0) {
-               sms_info("set device mode faile , rc %d", rc);
-               return rc;
-       }
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       rc = smscore_notify_callbacks(coredev, coredev->device, 1);
-       smscore_init_ir(coredev);
-
-       sms_info("device %p started, rc %d", coredev, rc);
-
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       return rc;
-}
-EXPORT_SYMBOL_GPL(smscore_start_device);
-
-
-static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
-                                        void *buffer, size_t size)
-{
-       struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
-       struct SmsMsgHdr_ST *msg;
-       u32 mem_address;
-       u8 *payload = firmware->Payload;
-       int rc = 0;
-       firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
-       firmware->Length = le32_to_cpu(firmware->Length);
-
-       mem_address = firmware->StartAddress;
-
-       sms_info("loading FW to addr 0x%x size %d",
-                mem_address, firmware->Length);
-       if (coredev->preload_handler) {
-               rc = coredev->preload_handler(coredev->context);
-               if (rc < 0)
-                       return rc;
-       }
-
-       /* PAGE_SIZE buffer shall be enough and dma aligned */
-       msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
-       if (!msg)
-               return -ENOMEM;
-
-       if (coredev->mode != DEVICE_MODE_NONE) {
-               sms_debug("sending reload command.");
-               SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
-                            sizeof(struct SmsMsgHdr_ST));
-               rc = smscore_sendrequest_and_wait(coredev, msg,
-                                                 msg->msgLength,
-                                                 &coredev->reload_start_done);
-               mem_address = *(u32 *) &payload[20];
-       }
-
-       while (size && rc >= 0) {
-               struct SmsDataDownload_ST *DataMsg =
-                       (struct SmsDataDownload_ST *) msg;
-               int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
-
-               SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
-                            (u16)(sizeof(struct SmsMsgHdr_ST) +
-                                     sizeof(u32) + payload_size));
-
-               DataMsg->MemAddr = mem_address;
-               memcpy(DataMsg->Payload, payload, payload_size);
-
-               if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
-                   (coredev->mode == DEVICE_MODE_NONE))
-                       rc = coredev->sendrequest_handler(
-                               coredev->context, DataMsg,
-                               DataMsg->xMsgHeader.msgLength);
-               else
-                       rc = smscore_sendrequest_and_wait(
-                               coredev, DataMsg,
-                               DataMsg->xMsgHeader.msgLength,
-                               &coredev->data_download_done);
-
-               payload += payload_size;
-               size -= payload_size;
-               mem_address += payload_size;
-       }
-
-       if (rc >= 0) {
-               if (coredev->mode == DEVICE_MODE_NONE) {
-                       struct SmsMsgData_ST *TriggerMsg =
-                               (struct SmsMsgData_ST *) msg;
-
-                       SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
-                                    sizeof(struct SmsMsgHdr_ST) +
-                                    sizeof(u32) * 5);
-
-                       TriggerMsg->msgData[0] = firmware->StartAddress;
-                                               /* Entry point */
-                       TriggerMsg->msgData[1] = 5; /* Priority */
-                       TriggerMsg->msgData[2] = 0x200; /* Stack size */
-                       TriggerMsg->msgData[3] = 0; /* Parameter */
-                       TriggerMsg->msgData[4] = 4; /* Task ID */
-
-                       if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
-                               rc = coredev->sendrequest_handler(
-                                       coredev->context, TriggerMsg,
-                                       TriggerMsg->xMsgHeader.msgLength);
-                               msleep(100);
-                       } else
-                               rc = smscore_sendrequest_and_wait(
-                                       coredev, TriggerMsg,
-                                       TriggerMsg->xMsgHeader.msgLength,
-                                       &coredev->trigger_done);
-               } else {
-                       SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
-                                    sizeof(struct SmsMsgHdr_ST));
-
-                       rc = coredev->sendrequest_handler(coredev->context,
-                                                         msg, msg->msgLength);
-               }
-               msleep(500);
-       }
-
-       sms_debug("rc=%d, postload=%p ", rc,
-                 coredev->postload_handler);
-
-       kfree(msg);
-
-       return ((rc >= 0) && coredev->postload_handler) ?
-               coredev->postload_handler(coredev->context) :
-               rc;
-}
-
-/**
- * loads specified firmware into a buffer and calls device loadfirmware_handler
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param filename null-terminated string specifies firmware file name
- * @param loadfirmware_handler device handler that loads firmware
- *
- * @return 0 on success, <0 on error.
- */
-static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
-                                          char *filename,
-                                          loadfirmware_t loadfirmware_handler)
-{
-       int rc = -ENOENT;
-       const struct firmware *fw;
-       u8 *fw_buffer;
-
-       if (loadfirmware_handler == NULL && !(coredev->device_flags &
-                                             SMS_DEVICE_FAMILY2))
-               return -EINVAL;
-
-       rc = request_firmware(&fw, filename, coredev->device);
-       if (rc < 0) {
-               sms_info("failed to open \"%s\"", filename);
-               return rc;
-       }
-       sms_info("read FW %s, size=%zd", filename, fw->size);
-       fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
-                           GFP_KERNEL | GFP_DMA);
-       if (fw_buffer) {
-               memcpy(fw_buffer, fw->data, fw->size);
-
-               rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
-                     smscore_load_firmware_family2(coredev,
-                                                   fw_buffer,
-                                                   fw->size) :
-                     loadfirmware_handler(coredev->context,
-                                          fw_buffer, fw->size);
-
-               kfree(fw_buffer);
-       } else {
-               sms_info("failed to allocate firmware buffer");
-               rc = -ENOMEM;
-       }
-
-       release_firmware(fw);
-
-       return rc;
-}
-
-/**
- * notifies all clients registered with the device, notifies hotplugs,
- * frees all buffers and coredev object
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- *
- * @return 0 on success, <0 on error.
- */
-void smscore_unregister_device(struct smscore_device_t *coredev)
-{
-       struct smscore_buffer_t *cb;
-       int num_buffers = 0;
-       int retry = 0;
-
-       kmutex_lock(&g_smscore_deviceslock);
-
-       /* Release input device (IR) resources */
-       sms_ir_exit(coredev);
-
-       smscore_notify_clients(coredev);
-       smscore_notify_callbacks(coredev, NULL, 0);
-
-       /* at this point all buffers should be back
-        * onresponse must no longer be called */
-
-       while (1) {
-               while (!list_empty(&coredev->buffers)) {
-                       cb = (struct smscore_buffer_t *) coredev->buffers.next;
-                       list_del(&cb->entry);
-                       kfree(cb);
-                       num_buffers++;
-               }
-               if (num_buffers == coredev->num_buffers)
-                       break;
-               if (++retry > 10) {
-                       sms_info("exiting although "
-                                "not all buffers released.");
-                       break;
-               }
-
-               sms_info("waiting for %d buffer(s)",
-                        coredev->num_buffers - num_buffers);
-               msleep(100);
-       }
-
-       sms_info("freed %d buffers", num_buffers);
-
-       if (coredev->common_buffer)
-               dma_free_coherent(NULL, coredev->common_buffer_size,
-                       coredev->common_buffer, coredev->common_buffer_phys);
-
-       if (coredev->fw_buf != NULL)
-               kfree(coredev->fw_buf);
-
-       list_del(&coredev->entry);
-       kfree(coredev);
-
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       sms_info("device %p destroyed", coredev);
-}
-EXPORT_SYMBOL_GPL(smscore_unregister_device);
-
-static int smscore_detect_mode(struct smscore_device_t *coredev)
-{
-       void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
-                              GFP_KERNEL | GFP_DMA);
-       struct SmsMsgHdr_ST *msg =
-               (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
-       int rc;
-
-       if (!buffer)
-               return -ENOMEM;
-
-       SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
-                    sizeof(struct SmsMsgHdr_ST));
-
-       rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
-                                         &coredev->version_ex_done);
-       if (rc == -ETIME) {
-               sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
-
-               if (wait_for_completion_timeout(&coredev->resume_done,
-                                               msecs_to_jiffies(5000))) {
-                       rc = smscore_sendrequest_and_wait(
-                               coredev, msg, msg->msgLength,
-                               &coredev->version_ex_done);
-                       if (rc < 0)
-                               sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
-                                       "second try, rc %d", rc);
-               } else
-                       rc = -ETIME;
-       }
-
-       kfree(buffer);
-
-       return rc;
-}
-
-static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
-       /*Stellar               NOVA A0         Nova B0         VEGA*/
-       /*DVBT*/
-       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
-       /*DVBH*/
-       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
-       /*TDMB*/
-       {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
-       /*DABIP*/
-       {"none", "none", "none", "none"},
-       /*BDA*/
-       {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
-       /*ISDBT*/
-       {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
-       /*ISDBTBDA*/
-       {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
-       /*CMMB*/
-       {"none", "none", "none", "cmmb_vega_12mhz.inp"}
-};
-
-static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
-                                   int mode, enum sms_device_type_st type)
-{
-       char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
-       return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
-}
-
-/**
- * calls device handler to change mode of operation
- * NOTE: stellar/usb may disconnect when changing mode
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param mode requested mode of operation
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
-{
-       void *buffer;
-       int rc = 0;
-       enum sms_device_type_st type;
-
-       sms_debug("set device mode to %d", mode);
-       if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
-               if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
-                       sms_err("invalid mode specified %d", mode);
-                       return -EINVAL;
-               }
-
-               smscore_registry_setmode(coredev->devpath, mode);
-
-               if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
-                       rc = smscore_detect_mode(coredev);
-                       if (rc < 0) {
-                               sms_err("mode detect failed %d", rc);
-                               return rc;
-                       }
-               }
-
-               if (coredev->mode == mode) {
-                       sms_info("device mode %d already set", mode);
-                       return 0;
-               }
-
-               if (!(coredev->modes_supported & (1 << mode))) {
-                       char *fw_filename;
-
-                       type = smscore_registry_gettype(coredev->devpath);
-                       fw_filename = sms_get_fw_name(coredev, mode, type);
-
-                       rc = smscore_load_firmware_from_file(coredev,
-                                                            fw_filename, NULL);
-                       if (rc < 0) {
-                               sms_warn("error %d loading firmware: %s, "
-                                        "trying again with default firmware",
-                                        rc, fw_filename);
-
-                               /* try again with the default firmware */
-                               fw_filename = smscore_fw_lkup[mode][type];
-                               rc = smscore_load_firmware_from_file(coredev,
-                                                            fw_filename, NULL);
-
-                               if (rc < 0) {
-                                       sms_warn("error %d loading "
-                                                "firmware: %s", rc,
-                                                fw_filename);
-                                       return rc;
-                               }
-                       }
-                       sms_log("firmware download success: %s", fw_filename);
-               } else
-                       sms_info("mode %d supported by running "
-                                "firmware", mode);
-
-               buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
-                                SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
-               if (buffer) {
-                       struct SmsMsgData_ST *msg =
-                               (struct SmsMsgData_ST *)
-                                       SMS_ALIGN_ADDRESS(buffer);
-
-                       SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
-                                    sizeof(struct SmsMsgData_ST));
-                       msg->msgData[0] = mode;
-
-                       rc = smscore_sendrequest_and_wait(
-                               coredev, msg, msg->xMsgHeader.msgLength,
-                               &coredev->init_device_done);
-
-                       kfree(buffer);
-               } else {
-                       sms_err("Could not allocate buffer for "
-                               "init device message.");
-                       rc = -ENOMEM;
-               }
-       } else {
-               if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
-                       sms_err("invalid mode specified %d", mode);
-                       return -EINVAL;
-               }
-
-               smscore_registry_setmode(coredev->devpath, mode);
-
-               if (coredev->detectmode_handler)
-                       coredev->detectmode_handler(coredev->context,
-                                                   &coredev->mode);
-
-               if (coredev->mode != mode && coredev->setmode_handler)
-                       rc = coredev->setmode_handler(coredev->context, mode);
-       }
-
-       if (rc >= 0) {
-               coredev->mode = mode;
-               coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
-       }
-
-       if (rc < 0)
-               sms_err("return error code %d.", rc);
-       return rc;
-}
-
-/**
- * calls device handler to get current mode of operation
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- *
- * @return current mode
- */
-int smscore_get_device_mode(struct smscore_device_t *coredev)
-{
-       return coredev->mode;
-}
-EXPORT_SYMBOL_GPL(smscore_get_device_mode);
-
-/**
- * find client by response id & type within the clients list.
- * return client handle or NULL.
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param data_type client data type (SMS_DONT_CARE for all types)
- * @param id client id (SMS_DONT_CARE for all id)
- *
- */
-static struct
-smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
-                                     int data_type, int id)
-{
-       struct list_head *first;
-       struct smscore_client_t *client;
-       unsigned long flags;
-       struct list_head *firstid;
-       struct smscore_idlist_t *client_id;
-
-       spin_lock_irqsave(&coredev->clientslock, flags);
-       first = &coredev->clients;
-       list_for_each_entry(client, first, entry) {
-               firstid = &client->idlist;
-               list_for_each_entry(client_id, firstid, entry) {
-                       if ((client_id->id == id) &&
-                           (client_id->data_type == data_type ||
-                           (client_id->data_type == 0)))
-                               goto found;
-               }
-       }
-       client = NULL;
-found:
-       spin_unlock_irqrestore(&coredev->clientslock, flags);
-       return client;
-}
-
-/**
- * find client by response id/type, call clients onresponse handler
- * return buffer to pool on error
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param cb pointer to response buffer descriptor
- *
- */
-void smscore_onresponse(struct smscore_device_t *coredev,
-               struct smscore_buffer_t *cb) {
-       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
-                       + cb->offset);
-       struct smscore_client_t *client;
-       int rc = -EBUSY;
-       static unsigned long last_sample_time; /* = 0; */
-       static int data_total; /* = 0; */
-       unsigned long time_now = jiffies_to_msecs(jiffies);
-
-       if (!last_sample_time)
-               last_sample_time = time_now;
-
-       if (time_now - last_sample_time > 10000) {
-               sms_debug("\ndata rate %d bytes/secs",
-                         (int)((data_total * 1000) /
-                               (time_now - last_sample_time)));
-
-               last_sample_time = time_now;
-               data_total = 0;
-       }
-
-       data_total += cb->size;
-       /* Do we need to re-route? */
-       if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
-                       (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
-               if (coredev->mode == DEVICE_MODE_DVBT_BDA)
-                       phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
-       }
-
-
-       client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
-
-       /* If no client registered for type & id,
-        * check for control client where type is not registered */
-       if (client)
-               rc = client->onresponse_handler(client->context, cb);
-
-       if (rc < 0) {
-               switch (phdr->msgType) {
-               case MSG_SMS_GET_VERSION_EX_RES:
-               {
-                       struct SmsVersionRes_ST *ver =
-                               (struct SmsVersionRes_ST *) phdr;
-                       sms_debug("MSG_SMS_GET_VERSION_EX_RES "
-                                 "id %d prots 0x%x ver %d.%d",
-                                 ver->FirmwareId, ver->SupportedProtocols,
-                                 ver->RomVersionMajor, ver->RomVersionMinor);
-
-                       coredev->mode = ver->FirmwareId == 255 ?
-                               DEVICE_MODE_NONE : ver->FirmwareId;
-                       coredev->modes_supported = ver->SupportedProtocols;
-
-                       complete(&coredev->version_ex_done);
-                       break;
-               }
-               case MSG_SMS_INIT_DEVICE_RES:
-                       sms_debug("MSG_SMS_INIT_DEVICE_RES");
-                       complete(&coredev->init_device_done);
-                       break;
-               case MSG_SW_RELOAD_START_RES:
-                       sms_debug("MSG_SW_RELOAD_START_RES");
-                       complete(&coredev->reload_start_done);
-                       break;
-               case MSG_SMS_DATA_DOWNLOAD_RES:
-                       complete(&coredev->data_download_done);
-                       break;
-               case MSG_SW_RELOAD_EXEC_RES:
-                       sms_debug("MSG_SW_RELOAD_EXEC_RES");
-                       break;
-               case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
-                       sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
-                       complete(&coredev->trigger_done);
-                       break;
-               case MSG_SMS_SLEEP_RESUME_COMP_IND:
-                       complete(&coredev->resume_done);
-                       break;
-               case MSG_SMS_GPIO_CONFIG_EX_RES:
-                       sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
-                       complete(&coredev->gpio_configuration_done);
-                       break;
-               case MSG_SMS_GPIO_SET_LEVEL_RES:
-                       sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
-                       complete(&coredev->gpio_set_level_done);
-                       break;
-               case MSG_SMS_GPIO_GET_LEVEL_RES:
-               {
-                       u32 *msgdata = (u32 *) phdr;
-                       coredev->gpio_get_res = msgdata[1];
-                       sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
-                                       coredev->gpio_get_res);
-                       complete(&coredev->gpio_get_level_done);
-                       break;
-               }
-               case MSG_SMS_START_IR_RES:
-                       complete(&coredev->ir_init_done);
-                       break;
-               case MSG_SMS_IR_SAMPLES_IND:
-                       sms_ir_event(coredev,
-                               (const char *)
-                               ((char *)phdr
-                               + sizeof(struct SmsMsgHdr_ST)),
-                               (int)phdr->msgLength
-                               - sizeof(struct SmsMsgHdr_ST));
-                       break;
-
-               default:
-                       break;
-               }
-               smscore_putbuffer(coredev, cb);
-       }
-}
-EXPORT_SYMBOL_GPL(smscore_onresponse);
-
-/**
- * return pointer to next free buffer descriptor from core pool
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- *
- * @return pointer to descriptor on success, NULL on error.
- */
-
-struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
-{
-       struct smscore_buffer_t *cb = NULL;
-       unsigned long flags;
-
-       spin_lock_irqsave(&coredev->bufferslock, flags);
-       if (!list_empty(&coredev->buffers)) {
-               cb = (struct smscore_buffer_t *) coredev->buffers.next;
-               list_del(&cb->entry);
-       }
-       spin_unlock_irqrestore(&coredev->bufferslock, flags);
-       return cb;
-}
-
-struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
-{
-       struct smscore_buffer_t *cb = NULL;
-
-       wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
-
-       return cb;
-}
-EXPORT_SYMBOL_GPL(smscore_getbuffer);
-
-/**
- * return buffer descriptor to a pool
- *
- * @param coredev pointer to a coredev object returned by
- *                smscore_register_device
- * @param cb pointer buffer descriptor
- *
- */
-void smscore_putbuffer(struct smscore_device_t *coredev,
-               struct smscore_buffer_t *cb) {
-       wake_up_interruptible(&coredev->buffer_mng_waitq);
-       list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
-}
-EXPORT_SYMBOL_GPL(smscore_putbuffer);
-
-static int smscore_validate_client(struct smscore_device_t *coredev,
-                                  struct smscore_client_t *client,
-                                  int data_type, int id)
-{
-       struct smscore_idlist_t *listentry;
-       struct smscore_client_t *registered_client;
-
-       if (!client) {
-               sms_err("bad parameter.");
-               return -EINVAL;
-       }
-       registered_client = smscore_find_client(coredev, data_type, id);
-       if (registered_client == client)
-               return 0;
-
-       if (registered_client) {
-               sms_err("The msg ID already registered to another client.");
-               return -EEXIST;
-       }
-       listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
-       if (!listentry) {
-               sms_err("Can't allocate memory for client id.");
-               return -ENOMEM;
-       }
-       listentry->id = id;
-       listentry->data_type = data_type;
-       list_add_locked(&listentry->entry, &client->idlist,
-                       &coredev->clientslock);
-       return 0;
-}
-
-/**
- * creates smsclient object, check that id is taken by another client
- *
- * @param coredev pointer to a coredev object from clients hotplug
- * @param initial_id all messages with this id would be sent to this client
- * @param data_type all messages of this type would be sent to this client
- * @param onresponse_handler client handler that is called to
- *                           process incoming messages
- * @param onremove_handler client handler that is called when device is removed
- * @param context client-specific context
- * @param client pointer to a value that receives created smsclient object
- *
- * @return 0 on success, <0 on error.
- */
-int smscore_register_client(struct smscore_device_t *coredev,
-                           struct smsclient_params_t *params,
-                           struct smscore_client_t **client)
-{
-       struct smscore_client_t *newclient;
-       /* check that no other channel with same parameters exists */
-       if (smscore_find_client(coredev, params->data_type,
-                               params->initial_id)) {
-               sms_err("Client already exist.");
-               return -EEXIST;
-       }
-
-       newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
-       if (!newclient) {
-               sms_err("Failed to allocate memory for client.");
-               return -ENOMEM;
-       }
-
-       INIT_LIST_HEAD(&newclient->idlist);
-       newclient->coredev = coredev;
-       newclient->onresponse_handler = params->onresponse_handler;
-       newclient->onremove_handler = params->onremove_handler;
-       newclient->context = params->context;
-       list_add_locked(&newclient->entry, &coredev->clients,
-                       &coredev->clientslock);
-       smscore_validate_client(coredev, newclient, params->data_type,
-                               params->initial_id);
-       *client = newclient;
-       sms_debug("%p %d %d", params->context, params->data_type,
-                 params->initial_id);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(smscore_register_client);
-
-/**
- * frees smsclient object and all subclients associated with it
- *
- * @param client pointer to smsclient object returned by
- *               smscore_register_client
- *
- */
-void smscore_unregister_client(struct smscore_client_t *client)
-{
-       struct smscore_device_t *coredev = client->coredev;
-       unsigned long flags;
-
-       spin_lock_irqsave(&coredev->clientslock, flags);
-
-
-       while (!list_empty(&client->idlist)) {
-               struct smscore_idlist_t *identry =
-                       (struct smscore_idlist_t *) client->idlist.next;
-               list_del(&identry->entry);
-               kfree(identry);
-       }
-
-       sms_info("%p", client->context);
-
-       list_del(&client->entry);
-       kfree(client);
-
-       spin_unlock_irqrestore(&coredev->clientslock, flags);
-}
-EXPORT_SYMBOL_GPL(smscore_unregister_client);
-
-/**
- * verifies that source id is not taken by another client,
- * calls device handler to send requests to the device
- *
- * @param client pointer to smsclient object returned by
- *               smscore_register_client
- * @param buffer pointer to a request buffer
- * @param size size (in bytes) of request buffer
- *
- * @return 0 on success, <0 on error.
- */
-int smsclient_sendrequest(struct smscore_client_t *client,
-                         void *buffer, size_t size)
-{
-       struct smscore_device_t *coredev;
-       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
-       int rc;
-
-       if (client == NULL) {
-               sms_err("Got NULL client");
-               return -EINVAL;
-       }
-
-       coredev = client->coredev;
-
-       /* check that no other channel with same id exists */
-       if (coredev == NULL) {
-               sms_err("Got NULL coredev");
-               return -EINVAL;
-       }
-
-       rc = smscore_validate_client(client->coredev, client, 0,
-                                    phdr->msgSrcId);
-       if (rc < 0)
-               return rc;
-
-       return coredev->sendrequest_handler(coredev->context, buffer, size);
-}
-EXPORT_SYMBOL_GPL(smsclient_sendrequest);
-
-
-/* old GPIO managements implementation */
-int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
-                          struct smscore_config_gpio *pinconfig)
-{
-       struct {
-               struct SmsMsgHdr_ST hdr;
-               u32 data[6];
-       } msg;
-
-       if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
-               msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-               msg.hdr.msgDstId = HIF_TASK;
-               msg.hdr.msgFlags = 0;
-               msg.hdr.msgType  = MSG_SMS_GPIO_CONFIG_EX_REQ;
-               msg.hdr.msgLength = sizeof(msg);
-
-               msg.data[0] = pin;
-               msg.data[1] = pinconfig->pullupdown;
-
-               /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
-               msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
-
-               switch (pinconfig->outputdriving) {
-               case SMS_GPIO_OUTPUTDRIVING_16mA:
-                       msg.data[3] = 7; /* Nova - 16mA */
-                       break;
-               case SMS_GPIO_OUTPUTDRIVING_12mA:
-                       msg.data[3] = 5; /* Nova - 11mA */
-                       break;
-               case SMS_GPIO_OUTPUTDRIVING_8mA:
-                       msg.data[3] = 3; /* Nova - 7mA */
-                       break;
-               case SMS_GPIO_OUTPUTDRIVING_4mA:
-               default:
-                       msg.data[3] = 2; /* Nova - 4mA */
-                       break;
-               }
-
-               msg.data[4] = pinconfig->direction;
-               msg.data[5] = 0;
-       } else /* TODO: SMS_DEVICE_FAMILY1 */
-               return -EINVAL;
-
-       return coredev->sendrequest_handler(coredev->context,
-                                           &msg, sizeof(msg));
-}
-
-int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
-{
-       struct {
-               struct SmsMsgHdr_ST hdr;
-               u32 data[3];
-       } msg;
-
-       if (pin > MAX_GPIO_PIN_NUMBER)
-               return -EINVAL;
-
-       msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       msg.hdr.msgDstId = HIF_TASK;
-       msg.hdr.msgFlags = 0;
-       msg.hdr.msgType  = MSG_SMS_GPIO_SET_LEVEL_REQ;
-       msg.hdr.msgLength = sizeof(msg);
-
-       msg.data[0] = pin;
-       msg.data[1] = level ? 1 : 0;
-       msg.data[2] = 0;
-
-       return coredev->sendrequest_handler(coredev->context,
-                                           &msg, sizeof(msg));
-}
-
-/* new GPIO management implementation */
-static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
-               u32 *pGroupNum, u32 *pGroupCfg) {
-
-       *pGroupCfg = 1;
-
-       if (PinNum <= 1)        {
-               *pTranslatedPinNum = 0;
-               *pGroupNum = 9;
-               *pGroupCfg = 2;
-       } else if (PinNum >= 2 && PinNum <= 6) {
-               *pTranslatedPinNum = 2;
-               *pGroupNum = 0;
-               *pGroupCfg = 2;
-       } else if (PinNum >= 7 && PinNum <= 11) {
-               *pTranslatedPinNum = 7;
-               *pGroupNum = 1;
-       } else if (PinNum >= 12 && PinNum <= 15) {
-               *pTranslatedPinNum = 12;
-               *pGroupNum = 2;
-               *pGroupCfg = 3;
-       } else if (PinNum == 16) {
-               *pTranslatedPinNum = 16;
-               *pGroupNum = 23;
-       } else if (PinNum >= 17 && PinNum <= 24) {
-               *pTranslatedPinNum = 17;
-               *pGroupNum = 3;
-       } else if (PinNum == 25) {
-               *pTranslatedPinNum = 25;
-               *pGroupNum = 6;
-       } else if (PinNum >= 26 && PinNum <= 28) {
-               *pTranslatedPinNum = 26;
-               *pGroupNum = 4;
-       } else if (PinNum == 29) {
-               *pTranslatedPinNum = 29;
-               *pGroupNum = 5;
-               *pGroupCfg = 2;
-       } else if (PinNum == 30) {
-               *pTranslatedPinNum = 30;
-               *pGroupNum = 8;
-       } else if (PinNum == 31) {
-               *pTranslatedPinNum = 31;
-               *pGroupNum = 17;
-       } else
-               return -1;
-
-       *pGroupCfg <<= 24;
-
-       return 0;
-}
-
-int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
-               struct smscore_gpio_config *pGpioConfig) {
-
-       u32 totalLen;
-       u32 TranslatedPinNum = 0;
-       u32 GroupNum = 0;
-       u32 ElectricChar;
-       u32 groupCfg;
-       void *buffer;
-       int rc;
-
-       struct SetGpioMsg {
-               struct SmsMsgHdr_ST xMsgHeader;
-               u32 msgData[6];
-       } *pMsg;
-
-
-       if (PinNum > MAX_GPIO_PIN_NUMBER)
-               return -EINVAL;
-
-       if (pGpioConfig == NULL)
-               return -EINVAL;
-
-       totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
-
-       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
-                       GFP_KERNEL | GFP_DMA);
-       if (!buffer)
-               return -ENOMEM;
-
-       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
-
-       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       pMsg->xMsgHeader.msgDstId = HIF_TASK;
-       pMsg->xMsgHeader.msgFlags = 0;
-       pMsg->xMsgHeader.msgLength = (u16) totalLen;
-       pMsg->msgData[0] = PinNum;
-
-       if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
-               pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
-               if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
-                               &groupCfg) != 0) {
-                       rc = -EINVAL;
-                       goto free;
-               }
-
-               pMsg->msgData[1] = TranslatedPinNum;
-               pMsg->msgData[2] = GroupNum;
-               ElectricChar = (pGpioConfig->PullUpDown)
-                               | (pGpioConfig->InputCharacteristics << 2)
-                               | (pGpioConfig->OutputSlewRate << 3)
-                               | (pGpioConfig->OutputDriving << 4);
-               pMsg->msgData[3] = ElectricChar;
-               pMsg->msgData[4] = pGpioConfig->Direction;
-               pMsg->msgData[5] = groupCfg;
-       } else {
-               pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
-               pMsg->msgData[1] = pGpioConfig->PullUpDown;
-               pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
-               pMsg->msgData[3] = pGpioConfig->OutputDriving;
-               pMsg->msgData[4] = pGpioConfig->Direction;
-               pMsg->msgData[5] = 0;
-       }
-
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
-       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
-                       &coredev->gpio_configuration_done);
-
-       if (rc != 0) {
-               if (rc == -ETIME)
-                       sms_err("smscore_gpio_configure timeout");
-               else
-                       sms_err("smscore_gpio_configure error");
-       }
-free:
-       kfree(buffer);
-
-       return rc;
-}
-
-int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
-               u8 NewLevel) {
-
-       u32 totalLen;
-       int rc;
-       void *buffer;
-
-       struct SetGpioMsg {
-               struct SmsMsgHdr_ST xMsgHeader;
-               u32 msgData[3]; /* keep it 3 ! */
-       } *pMsg;
-
-       if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER))
-               return -EINVAL;
-
-       totalLen = sizeof(struct SmsMsgHdr_ST) +
-                       (3 * sizeof(u32)); /* keep it 3 ! */
-
-       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
-                       GFP_KERNEL | GFP_DMA);
-       if (!buffer)
-               return -ENOMEM;
-
-       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
-
-       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       pMsg->xMsgHeader.msgDstId = HIF_TASK;
-       pMsg->xMsgHeader.msgFlags = 0;
-       pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
-       pMsg->xMsgHeader.msgLength = (u16) totalLen;
-       pMsg->msgData[0] = PinNum;
-       pMsg->msgData[1] = NewLevel;
-
-       /* Send message to SMS */
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
-       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
-                       &coredev->gpio_set_level_done);
-
-       if (rc != 0) {
-               if (rc == -ETIME)
-                       sms_err("smscore_gpio_set_level timeout");
-               else
-                       sms_err("smscore_gpio_set_level error");
-       }
-       kfree(buffer);
-
-       return rc;
-}
-
-int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
-               u8 *level) {
-
-       u32 totalLen;
-       int rc;
-       void *buffer;
-
-       struct SetGpioMsg {
-               struct SmsMsgHdr_ST xMsgHeader;
-               u32 msgData[2];
-       } *pMsg;
-
-
-       if (PinNum > MAX_GPIO_PIN_NUMBER)
-               return -EINVAL;
-
-       totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
-
-       buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
-                       GFP_KERNEL | GFP_DMA);
-       if (!buffer)
-               return -ENOMEM;
-
-       pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
-
-       pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       pMsg->xMsgHeader.msgDstId = HIF_TASK;
-       pMsg->xMsgHeader.msgFlags = 0;
-       pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
-       pMsg->xMsgHeader.msgLength = (u16) totalLen;
-       pMsg->msgData[0] = PinNum;
-       pMsg->msgData[1] = 0;
-
-       /* Send message to SMS */
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
-       rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
-                       &coredev->gpio_get_level_done);
-
-       if (rc != 0) {
-               if (rc == -ETIME)
-                       sms_err("smscore_gpio_get_level timeout");
-               else
-                       sms_err("smscore_gpio_get_level error");
-       }
-       kfree(buffer);
-
-       /* Its a race between other gpio_get_level() and the copy of the single
-        * global 'coredev->gpio_get_res' to  the function's variable 'level'
-        */
-       *level = coredev->gpio_get_res;
-
-       return rc;
-}
-
-static int __init smscore_module_init(void)
-{
-       int rc = 0;
-
-       INIT_LIST_HEAD(&g_smscore_notifyees);
-       INIT_LIST_HEAD(&g_smscore_devices);
-       kmutex_init(&g_smscore_deviceslock);
-
-       INIT_LIST_HEAD(&g_smscore_registry);
-       kmutex_init(&g_smscore_registrylock);
-
-       return rc;
-}
-
-static void __exit smscore_module_exit(void)
-{
-       kmutex_lock(&g_smscore_deviceslock);
-       while (!list_empty(&g_smscore_notifyees)) {
-               struct smscore_device_notifyee_t *notifyee =
-                       (struct smscore_device_notifyee_t *)
-                               g_smscore_notifyees.next;
-
-               list_del(&notifyee->entry);
-               kfree(notifyee);
-       }
-       kmutex_unlock(&g_smscore_deviceslock);
-
-       kmutex_lock(&g_smscore_registrylock);
-       while (!list_empty(&g_smscore_registry)) {
-               struct smscore_registry_entry_t *entry =
-                       (struct smscore_registry_entry_t *)
-                               g_smscore_registry.next;
-
-               list_del(&entry->entry);
-               kfree(entry);
-       }
-       kmutex_unlock(&g_smscore_registrylock);
-
-       sms_debug("");
-}
-
-module_init(smscore_module_init);
-module_exit(smscore_module_exit);
-
-MODULE_DESCRIPTION("Siano MDTV Core module");
-MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/siano/smscoreapi.h b/drivers/media/usb/siano/smscoreapi.h
deleted file mode 100644 (file)
index c592ae0..0000000
+++ /dev/null
@@ -1,775 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat
-
-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.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#ifndef __SMS_CORE_API_H__
-#define __SMS_CORE_API_H__
-
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/types.h>
-#include <linux/mutex.h>
-#include <linux/wait.h>
-#include <linux/timer.h>
-
-#include <asm/page.h>
-
-#include "smsir.h"
-
-#define kmutex_init(_p_) mutex_init(_p_)
-#define kmutex_lock(_p_) mutex_lock(_p_)
-#define kmutex_trylock(_p_) mutex_trylock(_p_)
-#define kmutex_unlock(_p_) mutex_unlock(_p_)
-
-#ifndef min
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS                 (10000)
-#define SMS_ALLOC_ALIGNMENT                            128
-#define SMS_DMA_ALIGNMENT                              16
-#define SMS_ALIGN_ADDRESS(addr) \
-       ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
-
-#define SMS_DEVICE_FAMILY2                             1
-#define SMS_ROM_NO_RESPONSE                            2
-#define SMS_DEVICE_NOT_READY                           0x8000000
-
-enum sms_device_type_st {
-       SMS_STELLAR = 0,
-       SMS_NOVA_A0,
-       SMS_NOVA_B0,
-       SMS_VEGA,
-       SMS_NUM_OF_DEVICE_TYPES
-};
-
-struct smscore_device_t;
-struct smscore_client_t;
-struct smscore_buffer_t;
-
-typedef int (*hotplug_t)(struct smscore_device_t *coredev,
-                        struct device *device, int arrival);
-
-typedef int (*setmode_t)(void *context, int mode);
-typedef void (*detectmode_t)(void *context, int *mode);
-typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
-typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
-typedef int (*preload_t)(void *context);
-typedef int (*postload_t)(void *context);
-
-typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
-typedef void (*onremove_t)(void *context);
-
-struct smscore_buffer_t {
-       /* public members, once passed to clients can be changed freely */
-       struct list_head entry;
-       int size;
-       int offset;
-
-       /* private members, read-only for clients */
-       void *p;
-       dma_addr_t phys;
-       unsigned long offset_in_common;
-};
-
-struct smsdevice_params_t {
-       struct device   *device;
-
-       int                             buffer_size;
-       int                             num_buffers;
-
-       char                    devpath[32];
-       unsigned long   flags;
-
-       setmode_t               setmode_handler;
-       detectmode_t    detectmode_handler;
-       sendrequest_t   sendrequest_handler;
-       preload_t               preload_handler;
-       postload_t              postload_handler;
-
-       void                    *context;
-       enum sms_device_type_st device_type;
-};
-
-struct smsclient_params_t {
-       int                             initial_id;
-       int                             data_type;
-       onresponse_t    onresponse_handler;
-       onremove_t              onremove_handler;
-       void                    *context;
-};
-
-struct smscore_device_t {
-       struct list_head entry;
-
-       struct list_head clients;
-       struct list_head subclients;
-       spinlock_t clientslock;
-
-       struct list_head buffers;
-       spinlock_t bufferslock;
-       int num_buffers;
-
-       void *common_buffer;
-       int common_buffer_size;
-       dma_addr_t common_buffer_phys;
-
-       void *context;
-       struct device *device;
-
-       char devpath[32];
-       unsigned long device_flags;
-
-       setmode_t setmode_handler;
-       detectmode_t detectmode_handler;
-       sendrequest_t sendrequest_handler;
-       preload_t preload_handler;
-       postload_t postload_handler;
-
-       int mode, modes_supported;
-
-       /* host <--> device messages */
-       struct completion version_ex_done, data_download_done, trigger_done;
-       struct completion init_device_done, reload_start_done, resume_done;
-       struct completion gpio_configuration_done, gpio_set_level_done;
-       struct completion gpio_get_level_done, ir_init_done;
-
-       /* Buffer management */
-       wait_queue_head_t buffer_mng_waitq;
-
-       /* GPIO */
-       int gpio_get_res;
-
-       /* Target hardware board */
-       int board_id;
-
-       /* Firmware */
-       u8 *fw_buf;
-       u32 fw_buf_size;
-
-       /* Infrared (IR) */
-       struct ir_t ir;
-
-       int led_state;
-};
-
-/* GPIO definitions for antenna frequency domain control (SMS8021) */
-#define SMS_ANTENNA_GPIO_0                                     1
-#define SMS_ANTENNA_GPIO_1                                     0
-
-#define BW_8_MHZ                                                       0
-#define BW_7_MHZ                                                       1
-#define BW_6_MHZ                                                       2
-#define BW_5_MHZ                                                       3
-#define BW_ISDBT_1SEG                                          4
-#define BW_ISDBT_3SEG                                          5
-
-#define MSG_HDR_FLAG_SPLIT_MSG                         4
-
-#define MAX_GPIO_PIN_NUMBER                                    31
-
-#define HIF_TASK                                                       11
-#define SMS_HOST_LIB                                           150
-#define DVBT_BDA_CONTROL_MSG_ID                                201
-
-#define SMS_MAX_PAYLOAD_SIZE                           240
-#define SMS_TUNE_TIMEOUT                                       500
-
-#define MSG_SMS_GPIO_CONFIG_REQ                                507
-#define MSG_SMS_GPIO_CONFIG_RES                                508
-#define MSG_SMS_GPIO_SET_LEVEL_REQ                     509
-#define MSG_SMS_GPIO_SET_LEVEL_RES                     510
-#define MSG_SMS_GPIO_GET_LEVEL_REQ                     511
-#define MSG_SMS_GPIO_GET_LEVEL_RES                     512
-#define MSG_SMS_RF_TUNE_REQ                                    561
-#define MSG_SMS_RF_TUNE_RES                                    562
-#define MSG_SMS_INIT_DEVICE_REQ                                578
-#define MSG_SMS_INIT_DEVICE_RES                                579
-#define MSG_SMS_ADD_PID_FILTER_REQ                     601
-#define MSG_SMS_ADD_PID_FILTER_RES                     602
-#define MSG_SMS_REMOVE_PID_FILTER_REQ                  603
-#define MSG_SMS_REMOVE_PID_FILTER_RES                  604
-#define MSG_SMS_DAB_CHANNEL                            607
-#define MSG_SMS_GET_PID_FILTER_LIST_REQ                        608
-#define MSG_SMS_GET_PID_FILTER_LIST_RES                        609
-#define MSG_SMS_GET_STATISTICS_RES                     616
-#define MSG_SMS_GET_STATISTICS_REQ                     615
-#define MSG_SMS_HO_PER_SLICES_IND                      630
-#define MSG_SMS_SET_ANTENNA_CONFIG_REQ                 651
-#define MSG_SMS_SET_ANTENNA_CONFIG_RES                 652
-#define MSG_SMS_SLEEP_RESUME_COMP_IND                  655
-#define MSG_SMS_DATA_DOWNLOAD_REQ                      660
-#define MSG_SMS_DATA_DOWNLOAD_RES                      661
-#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ         664
-#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES         665
-#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ                666
-#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES                667
-#define MSG_SMS_GET_VERSION_EX_REQ                     668
-#define MSG_SMS_GET_VERSION_EX_RES                     669
-#define MSG_SMS_SET_CLOCK_OUTPUT_REQ           670
-#define MSG_SMS_I2C_SET_FREQ_REQ                       685
-#define MSG_SMS_GENERIC_I2C_REQ                                687
-#define MSG_SMS_GENERIC_I2C_RES                                688
-#define MSG_SMS_DVBT_BDA_DATA                          693
-#define MSG_SW_RELOAD_REQ                                      697
-#define MSG_SMS_DATA_MSG                                       699
-#define MSG_SW_RELOAD_START_REQ                                702
-#define MSG_SW_RELOAD_START_RES                                703
-#define MSG_SW_RELOAD_EXEC_REQ                         704
-#define MSG_SW_RELOAD_EXEC_RES                         705
-#define MSG_SMS_SPI_INT_LINE_SET_REQ           710
-#define MSG_SMS_GPIO_CONFIG_EX_REQ                     712
-#define MSG_SMS_GPIO_CONFIG_EX_RES                     713
-#define MSG_SMS_ISDBT_TUNE_REQ                         776
-#define MSG_SMS_ISDBT_TUNE_RES                         777
-#define MSG_SMS_TRANSMISSION_IND                       782
-#define MSG_SMS_START_IR_REQ                           800
-#define MSG_SMS_START_IR_RES                           801
-#define MSG_SMS_IR_SAMPLES_IND                         802
-#define MSG_SMS_SIGNAL_DETECTED_IND                    827
-#define MSG_SMS_NO_SIGNAL_IND                          828
-
-#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
-       (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
-       (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
-} while (0)
-
-#define SMS_INIT_MSG(ptr, type, len) \
-       SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
-
-enum SMS_DVB3_EVENTS {
-       DVB3_EVENT_INIT = 0,
-       DVB3_EVENT_SLEEP,
-       DVB3_EVENT_HOTPLUG,
-       DVB3_EVENT_FE_LOCK,
-       DVB3_EVENT_FE_UNLOCK,
-       DVB3_EVENT_UNC_OK,
-       DVB3_EVENT_UNC_ERR
-};
-
-enum SMS_DEVICE_MODE {
-       DEVICE_MODE_NONE = -1,
-       DEVICE_MODE_DVBT = 0,
-       DEVICE_MODE_DVBH,
-       DEVICE_MODE_DAB_TDMB,
-       DEVICE_MODE_DAB_TDMB_DABIP,
-       DEVICE_MODE_DVBT_BDA,
-       DEVICE_MODE_ISDBT,
-       DEVICE_MODE_ISDBT_BDA,
-       DEVICE_MODE_CMMB,
-       DEVICE_MODE_RAW_TUNER,
-       DEVICE_MODE_MAX,
-};
-
-struct SmsMsgHdr_ST {
-       u16     msgType;
-       u8      msgSrcId;
-       u8      msgDstId;
-       u16     msgLength; /* Length of entire message, including header */
-       u16     msgFlags;
-};
-
-struct SmsMsgData_ST {
-       struct SmsMsgHdr_ST xMsgHeader;
-       u32 msgData[1];
-};
-
-struct SmsMsgData_ST2 {
-       struct SmsMsgHdr_ST xMsgHeader;
-       u32 msgData[2];
-};
-
-struct SmsDataDownload_ST {
-       struct SmsMsgHdr_ST     xMsgHeader;
-       u32                     MemAddr;
-       u8                      Payload[SMS_MAX_PAYLOAD_SIZE];
-};
-
-struct SmsVersionRes_ST {
-       struct SmsMsgHdr_ST     xMsgHeader;
-
-       u16             ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
-       u8              Step; /* 0 - Step A */
-       u8              MetalFix; /* 0 - Metal 0 */
-
-       /* FirmwareId 0xFF if ROM, otherwise the
-        * value indicated by SMSHOSTLIB_DEVICE_MODES_E */
-       u8 FirmwareId;
-       /* SupportedProtocols Bitwise OR combination of
-                                            * supported protocols */
-       u8 SupportedProtocols;
-
-       u8              VersionMajor;
-       u8              VersionMinor;
-       u8              VersionPatch;
-       u8              VersionFieldPatch;
-
-       u8              RomVersionMajor;
-       u8              RomVersionMinor;
-       u8              RomVersionPatch;
-       u8              RomVersionFieldPatch;
-
-       u8              TextLabel[34];
-};
-
-struct SmsFirmware_ST {
-       u32                     CheckSum;
-       u32                     Length;
-       u32                     StartAddress;
-       u8                      Payload[1];
-};
-
-/* Statistics information returned as response for
- * SmsHostApiGetStatistics_Req */
-struct SMSHOSTLIB_STATISTICS_ST {
-       u32 Reserved;           /* Reserved */
-
-       /* Common parameters */
-       u32 IsRfLocked;         /* 0 - not locked, 1 - locked */
-       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
-       u32 IsExternalLNAOn;    /* 0 - external LNA off, 1 - external LNA on */
-
-       /* Reception quality */
-       s32 SNR;                /* dB */
-       u32 BER;                /* Post Viterbi BER [1E-5] */
-       u32 FIB_CRC;            /* CRC errors percentage, valid only for DAB */
-       u32 TS_PER;             /* Transport stream PER,
-       0xFFFFFFFF indicate N/A, valid only for DVB-T/H */
-       u32 MFER;               /* DVB-H frame error rate in percentage,
-       0xFFFFFFFF indicate N/A, valid only for DVB-H */
-       s32 RSSI;               /* dBm */
-       s32 InBandPwr;          /* In band power in dBM */
-       s32 CarrierOffset;      /* Carrier Offset in bin/1024 */
-
-       /* Transmission parameters */
-       u32 Frequency;          /* Frequency in Hz */
-       u32 Bandwidth;          /* Bandwidth in MHz, valid only for DVB-T/H */
-       u32 TransmissionMode;   /* Transmission Mode, for DAB modes 1-4,
-       for DVB-T/H FFT mode carriers in Kilos */
-       u32 ModemState;         /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
-       valid only for DVB-T/H */
-       u32 GuardInterval;      /* Guard Interval from
-       SMSHOSTLIB_GUARD_INTERVALS_ET,  valid only for DVB-T/H */
-       u32 CodeRate;           /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
-       valid only for DVB-T/H */
-       u32 LPCodeRate;         /* Low Priority Code Rate from
-       SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */
-       u32 Hierarchy;          /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET,
-       valid only for DVB-T/H */
-       u32 Constellation;      /* Constellation from
-       SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */
-
-       /* Burst parameters, valid only for DVB-H */
-       u32 BurstSize;          /* Current burst size in bytes,
-       valid only for DVB-H */
-       u32 BurstDuration;      /* Current burst duration in mSec,
-       valid only for DVB-H */
-       u32 BurstCycleTime;     /* Current burst cycle time in mSec,
-       valid only for DVB-H */
-       u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec,
-       as calculated by demodulator, valid only for DVB-H */
-       u32 NumOfRows;          /* Number of rows in MPE table,
-       valid only for DVB-H */
-       u32 NumOfPaddCols;      /* Number of padding columns in MPE table,
-       valid only for DVB-H */
-       u32 NumOfPunctCols;     /* Number of puncturing columns in MPE table,
-       valid only for DVB-H */
-       u32 ErrorTSPackets;     /* Number of erroneous
-       transport-stream packets */
-       u32 TotalTSPackets;     /* Total number of transport-stream packets */
-       u32 NumOfValidMpeTlbs;  /* Number of MPE tables which do not include
-       errors after MPE RS decoding */
-       u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
-       after MPE RS decoding */
-       u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were
-       corrected by MPE RS decoding */
-       /* Common params */
-       u32 BERErrorCount;      /* Number of errornous SYNC bits. */
-       u32 BERBitCount;        /* Total number of SYNC bits. */
-
-       /* Interface information */
-       u32 SmsToHostTxErrors;  /* Total number of transmission errors. */
-
-       /* DAB/T-DMB */
-       u32 PreBER;             /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
-
-       /* DVB-H TPS parameters */
-       u32 CellId;             /* TPS Cell ID in bits 15..0, bits 31..16 zero;
-        if set to 0xFFFFFFFF cell_id not yet recovered */
-       u32 DvbhSrvIndHP;       /* DVB-H service indication info, bit 1 -
-       Time Slicing indicator, bit 0 - MPE-FEC indicator */
-       u32 DvbhSrvIndLP;       /* DVB-H service indication info, bit 1 -
-       Time Slicing indicator, bit 0 - MPE-FEC indicator */
-
-       u32 NumMPEReceived;     /* DVB-H, Num MPE section received */
-
-       u32 ReservedFields[10]; /* Reserved */
-};
-
-struct SmsMsgStatisticsInfo_ST {
-       u32 RequestResult;
-
-       struct SMSHOSTLIB_STATISTICS_ST Stat;
-
-       /* Split the calc of the SNR in DAB */
-       u32 Signal; /* dB */
-       u32 Noise; /* dB */
-
-};
-
-struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
-       /* Per-layer information */
-       u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
-                      * 255 means layer does not exist */
-       u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
-                           * 255 means layer does not exist */
-       u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
-       u32 BERErrorCount; /* Post Viterbi Error Bits Count */
-       u32 BERBitCount; /* Post Viterbi Total Bits Count */
-       u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
-       u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
-       u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
-       u32 TotalTSPackets; /* Total number of transport-stream packets */
-       u32 TILdepthI; /* Time interleaver depth I parameter,
-                       * 255 means layer does not exist */
-       u32 NumberOfSegments; /* Number of segments in layer A,
-                              * 255 means layer does not exist */
-       u32 TMCCErrors; /* TMCC errors */
-};
-
-struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
-       u32 StatisticsType; /* Enumerator identifying the type of the
-                               * structure.  Values are the same as
-                               * SMSHOSTLIB_DEVICE_MODES_E
-                               *
-                               * This field MUST always be first in any
-                               * statistics structure */
-
-       u32 FullSize; /* Total size of the structure returned by the modem.
-                      * If the size requested by the host is smaller than
-                      * FullSize, the struct will be truncated */
-
-       /* Common parameters */
-       u32 IsRfLocked; /* 0 - not locked, 1 - locked */
-       u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
-       u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
-
-       /* Reception quality */
-       s32  SNR; /* dB */
-       s32  RSSI; /* dBm */
-       s32  InBandPwr; /* In band power in dBM */
-       s32  CarrierOffset; /* Carrier Offset in Hz */
-
-       /* Transmission parameters */
-       u32 Frequency; /* Frequency in Hz */
-       u32 Bandwidth; /* Bandwidth in MHz */
-       u32 TransmissionMode; /* ISDB-T transmission mode */
-       u32 ModemState; /* 0 - Acquisition, 1 - Locked */
-       u32 GuardInterval; /* Guard Interval, 1 divided by value */
-       u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
-       u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
-       u32 NumOfLayers; /* Number of ISDB-T layers in the network */
-
-       /* Per-layer information */
-       /* Layers A, B and C */
-       struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST   LayerInfo[3];
-       /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
-
-       /* Interface information */
-       u32 SmsToHostTxErrors; /* Total number of transmission errors. */
-};
-
-struct PID_STATISTICS_DATA_S {
-       struct PID_BURST_S {
-               u32 size;
-               u32 padding_cols;
-               u32 punct_cols;
-               u32 duration;
-               u32 cycle;
-               u32 calc_cycle;
-       } burst;
-
-       u32 tot_tbl_cnt;
-       u32 invalid_tbl_cnt;
-       u32 tot_cor_tbl;
-};
-
-struct PID_DATA_S {
-       u32 pid;
-       u32 num_rows;
-       struct PID_STATISTICS_DATA_S pid_statistics;
-};
-
-#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1)
-#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth)
-#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \
-       if (_stat.TransmissionMode == 0) \
-               _stat.TransmissionMode = 2; \
-       else if (_stat.TransmissionMode == 1) \
-               _stat.TransmissionMode = 8; \
-               else \
-                       _stat.TransmissionMode = 4;
-
-struct TRANSMISSION_STATISTICS_S {
-       u32 Frequency;          /* Frequency in Hz */
-       u32 Bandwidth;          /* Bandwidth in MHz */
-       u32 TransmissionMode;   /* FFT mode carriers in Kilos */
-       u32 GuardInterval;      /* Guard Interval from
-       SMSHOSTLIB_GUARD_INTERVALS_ET */
-       u32 CodeRate;           /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
-       u32 LPCodeRate;         /* Low Priority Code Rate from
-       SMSHOSTLIB_CODE_RATE_ET */
-       u32 Hierarchy;          /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
-       u32 Constellation;      /* Constellation from
-       SMSHOSTLIB_CONSTELLATION_ET */
-
-       /* DVB-H TPS parameters */
-       u32 CellId;             /* TPS Cell ID in bits 15..0, bits 31..16 zero;
-        if set to 0xFFFFFFFF cell_id not yet recovered */
-       u32 DvbhSrvIndHP;       /* DVB-H service indication info, bit 1 -
-        Time Slicing indicator, bit 0 - MPE-FEC indicator */
-       u32 DvbhSrvIndLP;       /* DVB-H service indication info, bit 1 -
-        Time Slicing indicator, bit 0 - MPE-FEC indicator */
-       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
-};
-
-struct RECEPTION_STATISTICS_S {
-       u32 IsRfLocked;         /* 0 - not locked, 1 - locked */
-       u32 IsDemodLocked;      /* 0 - not locked, 1 - locked */
-       u32 IsExternalLNAOn;    /* 0 - external LNA off, 1 - external LNA on */
-
-       u32 ModemState;         /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
-       s32 SNR;                /* dB */
-       u32 BER;                /* Post Viterbi BER [1E-5] */
-       u32 BERErrorCount;      /* Number of erronous SYNC bits. */
-       u32 BERBitCount;        /* Total number of SYNC bits. */
-       u32 TS_PER;             /* Transport stream PER,
-       0xFFFFFFFF indicate N/A */
-       u32 MFER;               /* DVB-H frame error rate in percentage,
-       0xFFFFFFFF indicate N/A, valid only for DVB-H */
-       s32 RSSI;               /* dBm */
-       s32 InBandPwr;          /* In band power in dBM */
-       s32 CarrierOffset;      /* Carrier Offset in bin/1024 */
-       u32 ErrorTSPackets;     /* Number of erroneous
-       transport-stream packets */
-       u32 TotalTSPackets;     /* Total number of transport-stream packets */
-
-       s32 MRC_SNR;            /* dB */
-       s32 MRC_RSSI;           /* dBm */
-       s32 MRC_InBandPwr;      /* In band power in dBM */
-};
-
-
-/* Statistics information returned as response for
- * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */
-struct SMSHOSTLIB_STATISTICS_DVB_S {
-       /* Reception */
-       struct RECEPTION_STATISTICS_S ReceptionData;
-
-       /* Transmission parameters */
-       struct TRANSMISSION_STATISTICS_S TransmissionData;
-
-       /* Burst parameters, valid only for DVB-H */
-#define        SRVM_MAX_PID_FILTERS 8
-       struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS];
-};
-
-struct SRVM_SIGNAL_STATUS_S {
-       u32 result;
-       u32 snr;
-       u32 tsPackets;
-       u32 etsPackets;
-       u32 constellation;
-       u32 hpCode;
-       u32 tpsSrvIndLP;
-       u32 tpsSrvIndHP;
-       u32 cellId;
-       u32 reason;
-
-       s32 inBandPower;
-       u32 requestId;
-};
-
-struct SMSHOSTLIB_I2C_REQ_ST {
-       u32     DeviceAddress; /* I2c device address */
-       u32     WriteCount; /* number of bytes to write */
-       u32     ReadCount; /* number of bytes to read */
-       u8      Data[1];
-};
-
-struct SMSHOSTLIB_I2C_RES_ST {
-       u32     Status; /* non-zero value in case of failure */
-       u32     ReadCount; /* number of bytes read */
-       u8      Data[1];
-};
-
-
-struct smscore_config_gpio {
-#define SMS_GPIO_DIRECTION_INPUT  0
-#define SMS_GPIO_DIRECTION_OUTPUT 1
-       u8 direction;
-
-#define SMS_GPIO_PULLUPDOWN_NONE     0
-#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
-#define SMS_GPIO_PULLUPDOWN_PULLUP   2
-#define SMS_GPIO_PULLUPDOWN_KEEPER   3
-       u8 pullupdown;
-
-#define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL  0
-#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
-       u8 inputcharacteristics;
-
-#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
-#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
-       u8 outputslewrate;
-
-#define SMS_GPIO_OUTPUTDRIVING_4mA  0
-#define SMS_GPIO_OUTPUTDRIVING_8mA  1
-#define SMS_GPIO_OUTPUTDRIVING_12mA 2
-#define SMS_GPIO_OUTPUTDRIVING_16mA 3
-       u8 outputdriving;
-};
-
-struct smscore_gpio_config {
-#define SMS_GPIO_DIRECTION_INPUT  0
-#define SMS_GPIO_DIRECTION_OUTPUT 1
-       u8 Direction;
-
-#define SMS_GPIO_PULL_UP_DOWN_NONE     0
-#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1
-#define SMS_GPIO_PULL_UP_DOWN_PULLUP   2
-#define SMS_GPIO_PULL_UP_DOWN_KEEPER   3
-       u8 PullUpDown;
-
-#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL  0
-#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
-       u8 InputCharacteristics;
-
-#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW         1 /* 10xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST         0 /* 10xx */
-
-
-#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS    0 /* 11xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS     1 /* 11xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS     2 /* 11xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS     3 /* 11xx */
-       u8 OutputSlewRate;
-
-#define SMS_GPIO_OUTPUT_DRIVING_S_4mA          0 /* 10xx */
-#define SMS_GPIO_OUTPUT_DRIVING_S_8mA          1 /* 10xx */
-#define SMS_GPIO_OUTPUT_DRIVING_S_12mA         2 /* 10xx */
-#define SMS_GPIO_OUTPUT_DRIVING_S_16mA         3 /* 10xx */
-
-#define SMS_GPIO_OUTPUT_DRIVING_1_5mA          0 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_2_8mA          1 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_4mA            2 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_7mA            3 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_10mA           4 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_11mA           5 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_14mA           6 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_16mA           7 /* 11xx */
-       u8 OutputDriving;
-};
-
-extern void smscore_registry_setmode(char *devpath, int mode);
-extern int smscore_registry_getmode(char *devpath);
-
-extern int smscore_register_hotplug(hotplug_t hotplug);
-extern void smscore_unregister_hotplug(hotplug_t hotplug);
-
-extern int smscore_register_device(struct smsdevice_params_t *params,
-                                  struct smscore_device_t **coredev);
-extern void smscore_unregister_device(struct smscore_device_t *coredev);
-
-extern int smscore_start_device(struct smscore_device_t *coredev);
-extern int smscore_load_firmware(struct smscore_device_t *coredev,
-                                char *filename,
-                                loadfirmware_t loadfirmware_handler);
-
-extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
-extern int smscore_get_device_mode(struct smscore_device_t *coredev);
-
-extern int smscore_register_client(struct smscore_device_t *coredev,
-                                   struct smsclient_params_t *params,
-                                   struct smscore_client_t **client);
-extern void smscore_unregister_client(struct smscore_client_t *client);
-
-extern int smsclient_sendrequest(struct smscore_client_t *client,
-                                void *buffer, size_t size);
-extern void smscore_onresponse(struct smscore_device_t *coredev,
-                              struct smscore_buffer_t *cb);
-
-extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
-extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
-                                     struct vm_area_struct *vma);
-extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
-                                  int mode, char *filename);
-extern int smscore_send_fw_file(struct smscore_device_t *coredev,
-                               u8 *ufwbuf, int size);
-
-extern
-struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
-extern void smscore_putbuffer(struct smscore_device_t *coredev,
-                             struct smscore_buffer_t *cb);
-
-/* old GPIO management */
-int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
-                          struct smscore_config_gpio *pinconfig);
-int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
-
-/* new GPIO management */
-extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
-               struct smscore_gpio_config *pGpioConfig);
-extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
-               u8 NewLevel);
-extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
-               u8 *level);
-
-void smscore_set_board_id(struct smscore_device_t *core, int id);
-int smscore_get_board_id(struct smscore_device_t *core);
-
-int smscore_led_state(struct smscore_device_t *core, int led);
-
-
-/* ------------------------------------------------------------------------ */
-
-#define DBG_INFO 1
-#define DBG_ADV  2
-
-#define sms_printk(kern, fmt, arg...) \
-       printk(kern "%s: " fmt "\n", __func__, ##arg)
-
-#define dprintk(kern, lvl, fmt, arg...) do {\
-       if (sms_dbg & lvl) \
-               sms_printk(kern, fmt, ##arg); } while (0)
-
-#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
-#define sms_err(fmt, arg...) \
-       sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
-#define sms_warn(fmt, arg...)  sms_printk(KERN_WARNING, fmt, ##arg)
-#define sms_info(fmt, arg...) \
-       dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
-#define sms_debug(fmt, arg...) \
-       dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
-
-
-#endif /* __SMS_CORE_API_H__ */
diff --git a/drivers/media/usb/siano/smsdvb.c b/drivers/media/usb/siano/smsdvb.c
deleted file mode 100644 (file)
index aa77e54..0000000
+++ /dev/null
@@ -1,1078 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2008, Uri Shkolnik
-
-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.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-
-#include "smscoreapi.h"
-#include "smsendian.h"
-#include "sms-cards.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct smsdvb_client_t {
-       struct list_head entry;
-
-       struct smscore_device_t *coredev;
-       struct smscore_client_t *smsclient;
-
-       struct dvb_adapter      adapter;
-       struct dvb_demux        demux;
-       struct dmxdev           dmxdev;
-       struct dvb_frontend     frontend;
-
-       fe_status_t             fe_status;
-
-       struct completion       tune_done;
-
-       struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb;
-       int event_fe_state;
-       int event_unc_state;
-};
-
-static struct list_head g_smsdvb_clients;
-static struct mutex g_smsdvb_clientslock;
-
-static int sms_dbg;
-module_param_named(debug, sms_dbg, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
-
-/* Events that may come from DVB v3 adapter */
-static void sms_board_dvb3_event(struct smsdvb_client_t *client,
-               enum SMS_DVB3_EVENTS event) {
-
-       struct smscore_device_t *coredev = client->coredev;
-       switch (event) {
-       case DVB3_EVENT_INIT:
-               sms_debug("DVB3_EVENT_INIT");
-               sms_board_event(coredev, BOARD_EVENT_BIND);
-               break;
-       case DVB3_EVENT_SLEEP:
-               sms_debug("DVB3_EVENT_SLEEP");
-               sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
-               break;
-       case DVB3_EVENT_HOTPLUG:
-               sms_debug("DVB3_EVENT_HOTPLUG");
-               sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
-               break;
-       case DVB3_EVENT_FE_LOCK:
-               if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
-                       client->event_fe_state = DVB3_EVENT_FE_LOCK;
-                       sms_debug("DVB3_EVENT_FE_LOCK");
-                       sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
-               }
-               break;
-       case DVB3_EVENT_FE_UNLOCK:
-               if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
-                       client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
-                       sms_debug("DVB3_EVENT_FE_UNLOCK");
-                       sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
-               }
-               break;
-       case DVB3_EVENT_UNC_OK:
-               if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
-                       client->event_unc_state = DVB3_EVENT_UNC_OK;
-                       sms_debug("DVB3_EVENT_UNC_OK");
-                       sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
-               }
-               break;
-       case DVB3_EVENT_UNC_ERR:
-               if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
-                       client->event_unc_state = DVB3_EVENT_UNC_ERR;
-                       sms_debug("DVB3_EVENT_UNC_ERR");
-                       sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
-               }
-               break;
-
-       default:
-               sms_err("Unknown dvb3 api event");
-               break;
-       }
-}
-
-
-static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
-                                  struct SMSHOSTLIB_STATISTICS_ST *p)
-{
-       if (sms_dbg & 2) {
-               printk(KERN_DEBUG "Reserved = %d", p->Reserved);
-               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
-               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
-               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
-               printk(KERN_DEBUG "SNR = %d", p->SNR);
-               printk(KERN_DEBUG "BER = %d", p->BER);
-               printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
-               printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
-               printk(KERN_DEBUG "MFER = %d", p->MFER);
-               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
-               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
-               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
-               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
-               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
-               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
-               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
-               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
-               printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
-               printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
-               printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
-               printk(KERN_DEBUG "Constellation = %d", p->Constellation);
-               printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
-               printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
-               printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
-               printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
-               printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
-               printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
-               printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
-               printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
-               printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
-               printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
-               printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
-               printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
-               printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
-               printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
-               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
-               printk(KERN_DEBUG "PreBER = %d", p->PreBER);
-               printk(KERN_DEBUG "CellId = %d", p->CellId);
-               printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
-               printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
-               printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
-       }
-
-       pReceptionData->IsDemodLocked = p->IsDemodLocked;
-
-       pReceptionData->SNR = p->SNR;
-       pReceptionData->BER = p->BER;
-       pReceptionData->BERErrorCount = p->BERErrorCount;
-       pReceptionData->InBandPwr = p->InBandPwr;
-       pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
-};
-
-
-static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
-                                   struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
-{
-       int i;
-
-       if (sms_dbg & 2) {
-               printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
-               printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
-               printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
-               printk(KERN_DEBUG "SNR = %d", p->SNR);
-               printk(KERN_DEBUG "RSSI = %d", p->RSSI);
-               printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
-               printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
-               printk(KERN_DEBUG "Frequency = %d", p->Frequency);
-               printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
-               printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
-               printk(KERN_DEBUG "ModemState = %d", p->ModemState);
-               printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
-               printk(KERN_DEBUG "SystemType = %d", p->SystemType);
-               printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
-               printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
-               printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
-
-               for (i = 0; i < 3; i++) {
-                       printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
-                       printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
-                       printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
-                       printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
-                       printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
-                       printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
-                       printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
-                       printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
-                       printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
-                       printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
-                       printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
-                       printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
-               }
-       }
-
-       pReceptionData->IsDemodLocked = p->IsDemodLocked;
-
-       pReceptionData->SNR = p->SNR;
-       pReceptionData->InBandPwr = p->InBandPwr;
-
-       pReceptionData->ErrorTSPackets = 0;
-       pReceptionData->BER = 0;
-       pReceptionData->BERErrorCount = 0;
-       for (i = 0; i < 3; i++) {
-               pReceptionData->BER += p->LayerInfo[i].BER;
-               pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
-               pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
-       }
-}
-
-static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
-{
-       struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
-       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
-                       + cb->offset);
-       u32 *pMsgData = (u32 *) phdr + 1;
-       /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
-       bool is_status_update = false;
-
-       smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);
-
-       switch (phdr->msgType) {
-       case MSG_SMS_DVBT_BDA_DATA:
-               dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1),
-                                cb->size - sizeof(struct SmsMsgHdr_ST));
-               break;
-
-       case MSG_SMS_RF_TUNE_RES:
-       case MSG_SMS_ISDBT_TUNE_RES:
-               complete(&client->tune_done);
-               break;
-
-       case MSG_SMS_SIGNAL_DETECTED_IND:
-               sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
-               client->sms_stat_dvb.TransmissionData.IsDemodLocked = true;
-               is_status_update = true;
-               break;
-
-       case MSG_SMS_NO_SIGNAL_IND:
-               sms_info("MSG_SMS_NO_SIGNAL_IND");
-               client->sms_stat_dvb.TransmissionData.IsDemodLocked = false;
-               is_status_update = true;
-               break;
-
-       case MSG_SMS_TRANSMISSION_IND: {
-               sms_info("MSG_SMS_TRANSMISSION_IND");
-
-               pMsgData++;
-               memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
-                               sizeof(struct TRANSMISSION_STATISTICS_S));
-
-               /* Mo need to correct guard interval
-                * (as opposed to old statistics message).
-                */
-               CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
-               CORRECT_STAT_TRANSMISSON_MODE(
-                               client->sms_stat_dvb.TransmissionData);
-               is_status_update = true;
-               break;
-       }
-       case MSG_SMS_HO_PER_SLICES_IND: {
-               struct RECEPTION_STATISTICS_S *pReceptionData =
-                               &client->sms_stat_dvb.ReceptionData;
-               struct SRVM_SIGNAL_STATUS_S SignalStatusData;
-
-               /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
-               pMsgData++;
-               SignalStatusData.result = pMsgData[0];
-               SignalStatusData.snr = pMsgData[1];
-               SignalStatusData.inBandPower = (s32) pMsgData[2];
-               SignalStatusData.tsPackets = pMsgData[3];
-               SignalStatusData.etsPackets = pMsgData[4];
-               SignalStatusData.constellation = pMsgData[5];
-               SignalStatusData.hpCode = pMsgData[6];
-               SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
-               SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
-               SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
-               SignalStatusData.reason = pMsgData[10];
-               SignalStatusData.requestId = pMsgData[11];
-               pReceptionData->IsRfLocked = pMsgData[16];
-               pReceptionData->IsDemodLocked = pMsgData[17];
-               pReceptionData->ModemState = pMsgData[12];
-               pReceptionData->SNR = pMsgData[1];
-               pReceptionData->BER = pMsgData[13];
-               pReceptionData->RSSI = pMsgData[14];
-               CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
-
-               pReceptionData->InBandPwr = (s32) pMsgData[2];
-               pReceptionData->CarrierOffset = (s32) pMsgData[15];
-               pReceptionData->TotalTSPackets = pMsgData[3];
-               pReceptionData->ErrorTSPackets = pMsgData[4];
-
-               /* TS PER */
-               if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
-                               > 0) {
-                       pReceptionData->TS_PER = (SignalStatusData.etsPackets
-                                       * 100) / (SignalStatusData.tsPackets
-                                       + SignalStatusData.etsPackets);
-               } else {
-                       pReceptionData->TS_PER = 0;
-               }
-
-               pReceptionData->BERBitCount = pMsgData[18];
-               pReceptionData->BERErrorCount = pMsgData[19];
-
-               pReceptionData->MRC_SNR = pMsgData[20];
-               pReceptionData->MRC_InBandPwr = pMsgData[21];
-               pReceptionData->MRC_RSSI = pMsgData[22];
-
-               is_status_update = true;
-               break;
-       }
-       case MSG_SMS_GET_STATISTICS_RES: {
-               union {
-                       struct SMSHOSTLIB_STATISTICS_ISDBT_ST  isdbt;
-                       struct SmsMsgStatisticsInfo_ST         dvb;
-               } *p = (void *) (phdr + 1);
-               struct RECEPTION_STATISTICS_S *pReceptionData =
-                               &client->sms_stat_dvb.ReceptionData;
-
-               sms_info("MSG_SMS_GET_STATISTICS_RES");
-
-               is_status_update = true;
-
-               switch (smscore_get_device_mode(client->coredev)) {
-               case DEVICE_MODE_ISDBT:
-               case DEVICE_MODE_ISDBT_BDA:
-                       smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
-                       break;
-               default:
-                       smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
-               }
-               if (!pReceptionData->IsDemodLocked) {
-                       pReceptionData->SNR = 0;
-                       pReceptionData->BER = 0;
-                       pReceptionData->BERErrorCount = 0;
-                       pReceptionData->InBandPwr = 0;
-                       pReceptionData->ErrorTSPackets = 0;
-               }
-
-               complete(&client->tune_done);
-               break;
-       }
-       default:
-               sms_info("Unhandled message %d", phdr->msgType);
-
-       }
-       smscore_putbuffer(client->coredev, cb);
-
-       if (is_status_update) {
-               if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
-                       client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
-                               | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-                       sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
-                       if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets
-                                       == 0)
-                               sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
-                       else
-                               sms_board_dvb3_event(client,
-                                               DVB3_EVENT_UNC_ERR);
-
-               } else {
-                       if (client->sms_stat_dvb.ReceptionData.IsRfLocked)
-                               client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
-                       else
-                               client->fe_status = 0;
-                       sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
-               }
-       }
-
-       return 0;
-}
-
-static void smsdvb_unregister_client(struct smsdvb_client_t *client)
-{
-       /* must be called under clientslock */
-
-       list_del(&client->entry);
-
-       smscore_unregister_client(client->smsclient);
-       dvb_unregister_frontend(&client->frontend);
-       dvb_dmxdev_release(&client->dmxdev);
-       dvb_dmx_release(&client->demux);
-       dvb_unregister_adapter(&client->adapter);
-       kfree(client);
-}
-
-static void smsdvb_onremove(void *context)
-{
-       kmutex_lock(&g_smsdvb_clientslock);
-
-       smsdvb_unregister_client((struct smsdvb_client_t *) context);
-
-       kmutex_unlock(&g_smsdvb_clientslock);
-}
-
-static int smsdvb_start_feed(struct dvb_demux_feed *feed)
-{
-       struct smsdvb_client_t *client =
-               container_of(feed->demux, struct smsdvb_client_t, demux);
-       struct SmsMsgData_ST PidMsg;
-
-       sms_debug("add pid %d(%x)",
-                 feed->pid, feed->pid);
-
-       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
-       PidMsg.xMsgHeader.msgFlags = 0;
-       PidMsg.xMsgHeader.msgType  = MSG_SMS_ADD_PID_FILTER_REQ;
-       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
-       PidMsg.msgData[0] = feed->pid;
-
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
-       return smsclient_sendrequest(client->smsclient,
-                                    &PidMsg, sizeof(PidMsg));
-}
-
-static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
-{
-       struct smsdvb_client_t *client =
-               container_of(feed->demux, struct smsdvb_client_t, demux);
-       struct SmsMsgData_ST PidMsg;
-
-       sms_debug("remove pid %d(%x)",
-                 feed->pid, feed->pid);
-
-       PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       PidMsg.xMsgHeader.msgDstId = HIF_TASK;
-       PidMsg.xMsgHeader.msgFlags = 0;
-       PidMsg.xMsgHeader.msgType  = MSG_SMS_REMOVE_PID_FILTER_REQ;
-       PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
-       PidMsg.msgData[0] = feed->pid;
-
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
-       return smsclient_sendrequest(client->smsclient,
-                                    &PidMsg, sizeof(PidMsg));
-}
-
-static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
-                                       void *buffer, size_t size,
-                                       struct completion *completion)
-{
-       int rc;
-
-       smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer);
-       rc = smsclient_sendrequest(client->smsclient, buffer, size);
-       if (rc < 0)
-               return rc;
-
-       return wait_for_completion_timeout(completion,
-                                          msecs_to_jiffies(2000)) ?
-                                               0 : -ETIME;
-}
-
-static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
-{
-       int rc;
-       struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
-                                   DVBT_BDA_CONTROL_MSG_ID,
-                                   HIF_TASK,
-                                   sizeof(struct SmsMsgHdr_ST), 0 };
-
-       rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
-                                         &client->tune_done);
-
-       return rc;
-}
-
-static inline int led_feedback(struct smsdvb_client_t *client)
-{
-       if (client->fe_status & FE_HAS_LOCK)
-               return sms_board_led_feedback(client->coredev,
-                       (client->sms_stat_dvb.ReceptionData.BER
-                       == 0) ? SMS_LED_HI : SMS_LED_LO);
-       else
-               return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
-}
-
-static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
-{
-       int rc;
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       *stat = client->fe_status;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
-       int rc;
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       *ber = client->sms_stat_dvb.ReceptionData.BER;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       int rc;
-
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
-               *strength = 0;
-               else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
-                       *strength = 100;
-               else
-                       *strength =
-                               (client->sms_stat_dvb.ReceptionData.InBandPwr
-                               + 95) * 3 / 2;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-       int rc;
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       *snr = client->sms_stat_dvb.ReceptionData.SNR;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
-       int rc;
-       struct smsdvb_client_t *client;
-       client = container_of(fe, struct smsdvb_client_t, frontend);
-
-       rc = smsdvb_send_statistics_request(client);
-
-       *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
-
-       led_feedback(client);
-
-       return rc;
-}
-
-static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
-                                   struct dvb_frontend_tune_settings *tune)
-{
-       sms_debug("");
-
-       tune->min_delay_ms = 400;
-       tune->step_size = 250000;
-       tune->max_drift = 0;
-       return 0;
-}
-
-static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-
-       struct {
-               struct SmsMsgHdr_ST     Msg;
-               u32             Data[3];
-       } Msg;
-
-       int ret;
-
-       client->fe_status = FE_HAS_SIGNAL;
-       client->event_fe_state = -1;
-       client->event_unc_state = -1;
-       fe->dtv_property_cache.delivery_system = SYS_DVBT;
-
-       Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
-       Msg.Msg.msgDstId = HIF_TASK;
-       Msg.Msg.msgFlags = 0;
-       Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
-       Msg.Msg.msgLength = sizeof(Msg);
-       Msg.Data[0] = c->frequency;
-       Msg.Data[2] = 12000000;
-
-       sms_info("%s: freq %d band %d", __func__, c->frequency,
-                c->bandwidth_hz);
-
-       switch (c->bandwidth_hz / 1000000) {
-       case 8:
-               Msg.Data[1] = BW_8_MHZ;
-               break;
-       case 7:
-               Msg.Data[1] = BW_7_MHZ;
-               break;
-       case 6:
-               Msg.Data[1] = BW_6_MHZ;
-               break;
-       case 0:
-               return -EOPNOTSUPP;
-       default:
-               return -EINVAL;
-       }
-       /* Disable LNA, if any. An error is returned if no LNA is present */
-       ret = sms_board_lna_control(client->coredev, 0);
-       if (ret == 0) {
-               fe_status_t status;
-
-               /* tune with LNA off at first */
-               ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
-                                                 &client->tune_done);
-
-               smsdvb_read_status(fe, &status);
-
-               if (status & FE_HAS_LOCK)
-                       return ret;
-
-               /* previous tune didn't lock - enable LNA and tune again */
-               sms_board_lna_control(client->coredev, 1);
-       }
-
-       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
-                                          &client->tune_done);
-}
-
-static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-
-       struct {
-               struct SmsMsgHdr_ST     Msg;
-               u32             Data[4];
-       } Msg;
-
-       fe->dtv_property_cache.delivery_system = SYS_ISDBT;
-
-       Msg.Msg.msgSrcId  = DVBT_BDA_CONTROL_MSG_ID;
-       Msg.Msg.msgDstId  = HIF_TASK;
-       Msg.Msg.msgFlags  = 0;
-       Msg.Msg.msgType   = MSG_SMS_ISDBT_TUNE_REQ;
-       Msg.Msg.msgLength = sizeof(Msg);
-
-       if (c->isdbt_sb_segment_idx == -1)
-               c->isdbt_sb_segment_idx = 0;
-
-       switch (c->isdbt_sb_segment_count) {
-       case 3:
-               Msg.Data[1] = BW_ISDBT_3SEG;
-               break;
-       case 1:
-               Msg.Data[1] = BW_ISDBT_1SEG;
-               break;
-       case 0: /* AUTO */
-               switch (c->bandwidth_hz / 1000000) {
-               case 8:
-               case 7:
-                       c->isdbt_sb_segment_count = 3;
-                       Msg.Data[1] = BW_ISDBT_3SEG;
-                       break;
-               case 6:
-                       c->isdbt_sb_segment_count = 1;
-                       Msg.Data[1] = BW_ISDBT_1SEG;
-                       break;
-               default: /* Assumes 6 MHZ bw */
-                       c->isdbt_sb_segment_count = 1;
-                       c->bandwidth_hz = 6000;
-                       Msg.Data[1] = BW_ISDBT_1SEG;
-                       break;
-               }
-               break;
-       default:
-               sms_info("Segment count %d not supported", c->isdbt_sb_segment_count);
-               return -EINVAL;
-       }
-
-       Msg.Data[0] = c->frequency;
-       Msg.Data[2] = 12000000;
-       Msg.Data[3] = c->isdbt_sb_segment_idx;
-
-       sms_info("%s: freq %d segwidth %d segindex %d\n", __func__,
-                c->frequency, c->isdbt_sb_segment_count,
-                c->isdbt_sb_segment_idx);
-
-       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
-                                          &client->tune_done);
-}
-
-static int smsdvb_set_frontend(struct dvb_frontend *fe)
-{
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-       struct smscore_device_t *coredev = client->coredev;
-
-       switch (smscore_get_device_mode(coredev)) {
-       case DEVICE_MODE_DVBT:
-       case DEVICE_MODE_DVBT_BDA:
-               return smsdvb_dvbt_set_frontend(fe);
-       case DEVICE_MODE_ISDBT:
-       case DEVICE_MODE_ISDBT_BDA:
-               return smsdvb_isdbt_set_frontend(fe);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int smsdvb_get_frontend(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-       struct smscore_device_t *coredev = client->coredev;
-       struct TRANSMISSION_STATISTICS_S *td =
-               &client->sms_stat_dvb.TransmissionData;
-
-       switch (smscore_get_device_mode(coredev)) {
-       case DEVICE_MODE_DVBT:
-       case DEVICE_MODE_DVBT_BDA:
-               fep->frequency = td->Frequency;
-
-               switch (td->Bandwidth) {
-               case 6:
-                       fep->bandwidth_hz = 6000000;
-                       break;
-               case 7:
-                       fep->bandwidth_hz = 7000000;
-                       break;
-               case 8:
-                       fep->bandwidth_hz = 8000000;
-                       break;
-               }
-
-               switch (td->TransmissionMode) {
-               case 2:
-                       fep->transmission_mode = TRANSMISSION_MODE_2K;
-                       break;
-               case 8:
-                       fep->transmission_mode = TRANSMISSION_MODE_8K;
-               }
-
-               switch (td->GuardInterval) {
-               case 0:
-                       fep->guard_interval = GUARD_INTERVAL_1_32;
-                       break;
-               case 1:
-                       fep->guard_interval = GUARD_INTERVAL_1_16;
-                       break;
-               case 2:
-                       fep->guard_interval = GUARD_INTERVAL_1_8;
-                       break;
-               case 3:
-                       fep->guard_interval = GUARD_INTERVAL_1_4;
-                       break;
-               }
-
-               switch (td->CodeRate) {
-               case 0:
-                       fep->code_rate_HP = FEC_1_2;
-                       break;
-               case 1:
-                       fep->code_rate_HP = FEC_2_3;
-                       break;
-               case 2:
-                       fep->code_rate_HP = FEC_3_4;
-                       break;
-               case 3:
-                       fep->code_rate_HP = FEC_5_6;
-                       break;
-               case 4:
-                       fep->code_rate_HP = FEC_7_8;
-                       break;
-               }
-
-               switch (td->LPCodeRate) {
-               case 0:
-                       fep->code_rate_LP = FEC_1_2;
-                       break;
-               case 1:
-                       fep->code_rate_LP = FEC_2_3;
-                       break;
-               case 2:
-                       fep->code_rate_LP = FEC_3_4;
-                       break;
-               case 3:
-                       fep->code_rate_LP = FEC_5_6;
-                       break;
-               case 4:
-                       fep->code_rate_LP = FEC_7_8;
-                       break;
-               }
-
-               switch (td->Constellation) {
-               case 0:
-                       fep->modulation = QPSK;
-                       break;
-               case 1:
-                       fep->modulation = QAM_16;
-                       break;
-               case 2:
-                       fep->modulation = QAM_64;
-                       break;
-               }
-
-               switch (td->Hierarchy) {
-               case 0:
-                       fep->hierarchy = HIERARCHY_NONE;
-                       break;
-               case 1:
-                       fep->hierarchy = HIERARCHY_1;
-                       break;
-               case 2:
-                       fep->hierarchy = HIERARCHY_2;
-                       break;
-               case 3:
-                       fep->hierarchy = HIERARCHY_4;
-                       break;
-               }
-
-               fep->inversion = INVERSION_AUTO;
-               break;
-       case DEVICE_MODE_ISDBT:
-       case DEVICE_MODE_ISDBT_BDA:
-               fep->frequency = td->Frequency;
-               fep->bandwidth_hz = 6000000;
-               /* todo: retrive the other parameters */
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int smsdvb_init(struct dvb_frontend *fe)
-{
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-
-       sms_board_power(client->coredev, 1);
-
-       sms_board_dvb3_event(client, DVB3_EVENT_INIT);
-       return 0;
-}
-
-static int smsdvb_sleep(struct dvb_frontend *fe)
-{
-       struct smsdvb_client_t *client =
-               container_of(fe, struct smsdvb_client_t, frontend);
-
-       sms_board_led_feedback(client->coredev, SMS_LED_OFF);
-       sms_board_power(client->coredev, 0);
-
-       sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
-
-       return 0;
-}
-
-static void smsdvb_release(struct dvb_frontend *fe)
-{
-       /* do nothing */
-}
-
-static struct dvb_frontend_ops smsdvb_fe_ops = {
-       .info = {
-               .name                   = "Siano Mobile Digital MDTV Receiver",
-               .frequency_min          = 44250000,
-               .frequency_max          = 867250000,
-               .frequency_stepsize     = 250000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-                       FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
-                       FE_CAN_GUARD_INTERVAL_AUTO |
-                       FE_CAN_RECOVER |
-                       FE_CAN_HIERARCHY_AUTO,
-       },
-
-       .release = smsdvb_release,
-
-       .set_frontend = smsdvb_set_frontend,
-       .get_frontend = smsdvb_get_frontend,
-       .get_tune_settings = smsdvb_get_tune_settings,
-
-       .read_status = smsdvb_read_status,
-       .read_ber = smsdvb_read_ber,
-       .read_signal_strength = smsdvb_read_signal_strength,
-       .read_snr = smsdvb_read_snr,
-       .read_ucblocks = smsdvb_read_ucblocks,
-
-       .init = smsdvb_init,
-       .sleep = smsdvb_sleep,
-};
-
-static int smsdvb_hotplug(struct smscore_device_t *coredev,
-                         struct device *device, int arrival)
-{
-       struct smsclient_params_t params;
-       struct smsdvb_client_t *client;
-       int rc;
-
-       /* device removal handled by onremove callback */
-       if (!arrival)
-               return 0;
-       client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
-       if (!client) {
-               sms_err("kmalloc() failed");
-               return -ENOMEM;
-       }
-
-       /* register dvb adapter */
-       rc = dvb_register_adapter(&client->adapter,
-                                 sms_get_board(
-                                       smscore_get_board_id(coredev))->name,
-                                 THIS_MODULE, device, adapter_nr);
-       if (rc < 0) {
-               sms_err("dvb_register_adapter() failed %d", rc);
-               goto adapter_error;
-       }
-
-       /* init dvb demux */
-       client->demux.dmx.capabilities = DMX_TS_FILTERING;
-       client->demux.filternum = 32; /* todo: nova ??? */
-       client->demux.feednum = 32;
-       client->demux.start_feed = smsdvb_start_feed;
-       client->demux.stop_feed = smsdvb_stop_feed;
-
-       rc = dvb_dmx_init(&client->demux);
-       if (rc < 0) {
-               sms_err("dvb_dmx_init failed %d", rc);
-               goto dvbdmx_error;
-       }
-
-       /* init dmxdev */
-       client->dmxdev.filternum = 32;
-       client->dmxdev.demux = &client->demux.dmx;
-       client->dmxdev.capabilities = 0;
-
-       rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
-       if (rc < 0) {
-               sms_err("dvb_dmxdev_init failed %d", rc);
-               goto dmxdev_error;
-       }
-
-       /* init and register frontend */
-       memcpy(&client->frontend.ops, &smsdvb_fe_ops,
-              sizeof(struct dvb_frontend_ops));
-
-       switch (smscore_get_device_mode(coredev)) {
-       case DEVICE_MODE_DVBT:
-       case DEVICE_MODE_DVBT_BDA:
-               client->frontend.ops.delsys[0] = SYS_DVBT;
-               break;
-       case DEVICE_MODE_ISDBT:
-       case DEVICE_MODE_ISDBT_BDA:
-               client->frontend.ops.delsys[0] = SYS_ISDBT;
-               break;
-       }
-
-       rc = dvb_register_frontend(&client->adapter, &client->frontend);
-       if (rc < 0) {
-               sms_err("frontend registration failed %d", rc);
-               goto frontend_error;
-       }
-
-       params.initial_id = 1;
-       params.data_type = MSG_SMS_DVBT_BDA_DATA;
-       params.onresponse_handler = smsdvb_onresponse;
-       params.onremove_handler = smsdvb_onremove;
-       params.context = client;
-
-       rc = smscore_register_client(coredev, &params, &client->smsclient);
-       if (rc < 0) {
-               sms_err("smscore_register_client() failed %d", rc);
-               goto client_error;
-       }
-
-       client->coredev = coredev;
-
-       init_completion(&client->tune_done);
-
-       kmutex_lock(&g_smsdvb_clientslock);
-
-       list_add(&client->entry, &g_smsdvb_clients);
-
-       kmutex_unlock(&g_smsdvb_clientslock);
-
-       client->event_fe_state = -1;
-       client->event_unc_state = -1;
-       sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
-
-       sms_info("success");
-       sms_board_setup(coredev);
-
-       return 0;
-
-client_error:
-       dvb_unregister_frontend(&client->frontend);
-
-frontend_error:
-       dvb_dmxdev_release(&client->dmxdev);
-
-dmxdev_error:
-       dvb_dmx_release(&client->demux);
-
-dvbdmx_error:
-       dvb_unregister_adapter(&client->adapter);
-
-adapter_error:
-       kfree(client);
-       return rc;
-}
-
-static int __init smsdvb_module_init(void)
-{
-       int rc;
-
-       INIT_LIST_HEAD(&g_smsdvb_clients);
-       kmutex_init(&g_smsdvb_clientslock);
-
-       rc = smscore_register_hotplug(smsdvb_hotplug);
-
-       sms_debug("");
-
-       return rc;
-}
-
-static void __exit smsdvb_module_exit(void)
-{
-       smscore_unregister_hotplug(smsdvb_hotplug);
-
-       kmutex_lock(&g_smsdvb_clientslock);
-
-       while (!list_empty(&g_smsdvb_clients))
-              smsdvb_unregister_client(
-                       (struct smsdvb_client_t *) g_smsdvb_clients.next);
-
-       kmutex_unlock(&g_smsdvb_clientslock);
-}
-
-module_init(smsdvb_module_init);
-module_exit(smsdvb_module_exit);
-
-MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
-MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/siano/smsendian.c b/drivers/media/usb/siano/smsendian.c
deleted file mode 100644 (file)
index e2657c2..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************
-
- Siano Mobile Silicon, Inc.
- MDTV receiver kernel modules.
- Copyright (C) 2006-2009, Uri Shkolnik
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
- ****************************************************************/
-
-#include <linux/export.h>
-#include <asm/byteorder.h>
-
-#include "smsendian.h"
-#include "smscoreapi.h"
-
-void smsendian_handle_tx_message(void *buffer)
-{
-#ifdef __BIG_ENDIAN
-       struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
-       int i;
-       int msgWords;
-
-       switch (msg->xMsgHeader.msgType) {
-       case MSG_SMS_DATA_DOWNLOAD_REQ:
-       {
-               msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
-               break;
-       }
-
-       default:
-               msgWords = (msg->xMsgHeader.msgLength -
-                               sizeof(struct SmsMsgHdr_ST))/4;
-
-               for (i = 0; i < msgWords; i++)
-                       msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
-
-               break;
-       }
-#endif /* __BIG_ENDIAN */
-}
-EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
-
-void smsendian_handle_rx_message(void *buffer)
-{
-#ifdef __BIG_ENDIAN
-       struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
-       int i;
-       int msgWords;
-
-       switch (msg->xMsgHeader.msgType) {
-       case MSG_SMS_GET_VERSION_EX_RES:
-       {
-               struct SmsVersionRes_ST *ver =
-                       (struct SmsVersionRes_ST *) msg;
-               ver->ChipModel = le16_to_cpu(ver->ChipModel);
-               break;
-       }
-
-       case MSG_SMS_DVBT_BDA_DATA:
-       case MSG_SMS_DAB_CHANNEL:
-       case MSG_SMS_DATA_MSG:
-       {
-               break;
-       }
-
-       default:
-       {
-               msgWords = (msg->xMsgHeader.msgLength -
-                               sizeof(struct SmsMsgHdr_ST))/4;
-
-               for (i = 0; i < msgWords; i++)
-                       msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
-
-               break;
-       }
-       }
-#endif /* __BIG_ENDIAN */
-}
-EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
-
-void smsendian_handle_message_header(void *msg)
-{
-#ifdef __BIG_ENDIAN
-       struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
-
-       phdr->msgType = le16_to_cpu(phdr->msgType);
-       phdr->msgLength = le16_to_cpu(phdr->msgLength);
-       phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
-#endif /* __BIG_ENDIAN */
-}
-EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/usb/siano/smsendian.h b/drivers/media/usb/siano/smsendian.h
deleted file mode 100644 (file)
index 1624d6f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2009, Uri Shkolnik
-
-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.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#ifndef __SMS_ENDIAN_H__
-#define __SMS_ENDIAN_H__
-
-#include <asm/byteorder.h>
-
-extern void smsendian_handle_tx_message(void *buffer);
-extern void smsendian_handle_rx_message(void *buffer);
-extern void smsendian_handle_message_header(void *msg);
-
-#endif /* __SMS_ENDIAN_H__ */
-
diff --git a/drivers/media/usb/siano/smsir.c b/drivers/media/usb/siano/smsir.c
deleted file mode 100644 (file)
index 37bc5c4..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************
-
- Siano Mobile Silicon, Inc.
- MDTV receiver kernel modules.
- Copyright (C) 2006-2009, Uri Shkolnik
-
- Copyright (c) 2010 - Mauro Carvalho Chehab
-       - Ported the driver to use rc-core
-       - IR raw event decoding is now done at rc-core
-       - Code almost re-written
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
- ****************************************************************/
-
-
-#include <linux/types.h>
-#include <linux/input.h>
-
-#include "smscoreapi.h"
-#include "smsir.h"
-#include "sms-cards.h"
-
-#define MODULE_NAME "smsmdtv"
-
-void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
-{
-       int i;
-       const s32 *samples = (const void *)buf;
-
-       for (i = 0; i < len >> 2; i++) {
-               DEFINE_IR_RAW_EVENT(ev);
-
-               ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
-               ev.pulse = (samples[i] > 0) ? false : true;
-
-               ir_raw_event_store(coredev->ir.dev, &ev);
-       }
-       ir_raw_event_handle(coredev->ir.dev);
-}
-
-int sms_ir_init(struct smscore_device_t *coredev)
-{
-       int err;
-       int board_id = smscore_get_board_id(coredev);
-       struct rc_dev *dev;
-
-       sms_log("Allocating rc device");
-       dev = rc_allocate_device();
-       if (!dev) {
-               sms_err("Not enough memory");
-               return -ENOMEM;
-       }
-
-       coredev->ir.controller = 0;     /* Todo: vega/nova SPI number */
-       coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
-       sms_log("IR port %d, timeout %d ms",
-                       coredev->ir.controller, coredev->ir.timeout);
-
-       snprintf(coredev->ir.name, sizeof(coredev->ir.name),
-                "SMS IR (%s)", sms_get_board(board_id)->name);
-
-       strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
-       strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
-
-       dev->input_name = coredev->ir.name;
-       dev->input_phys = coredev->ir.phys;
-       dev->dev.parent = coredev->device;
-
-#if 0
-       /* TODO: properly initialize the parameters bellow */
-       dev->input_id.bustype = BUS_USB;
-       dev->input_id.version = 1;
-       dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
-       dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
-#endif
-
-       dev->priv = coredev;
-       dev->driver_type = RC_DRIVER_IR_RAW;
-       dev->allowed_protos = RC_TYPE_ALL;
-       dev->map_name = sms_get_board(board_id)->rc_codes;
-       dev->driver_name = MODULE_NAME;
-
-       sms_log("Input device (IR) %s is set for key events", dev->input_name);
-
-       err = rc_register_device(dev);
-       if (err < 0) {
-               sms_err("Failed to register device");
-               rc_free_device(dev);
-               return err;
-       }
-
-       coredev->ir.dev = dev;
-       return 0;
-}
-
-void sms_ir_exit(struct smscore_device_t *coredev)
-{
-       if (coredev->ir.dev)
-               rc_unregister_device(coredev->ir.dev);
-
-       sms_log("");
-}
diff --git a/drivers/media/usb/siano/smsir.h b/drivers/media/usb/siano/smsir.h
deleted file mode 100644 (file)
index ae92b3a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2009, Uri Shkolnik
-
- Copyright (c) 2010 - Mauro Carvalho Chehab
-       - Ported the driver to use rc-core
-       - IR raw event decoding is now done at rc-core
-       - Code almost re-written
-
-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.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#ifndef __SMS_IR_H__
-#define __SMS_IR_H__
-
-#include <linux/input.h>
-#include <media/rc-core.h>
-
-#define IR_DEFAULT_TIMEOUT             100
-
-struct smscore_device_t;
-
-struct ir_t {
-       struct rc_dev *dev;
-       char name[40];
-       char phys[32];
-
-       char *rc_codes;
-       u64 protocol;
-
-       u32 timeout;
-       u32 controller;
-};
-
-int sms_ir_init(struct smscore_device_t *coredev);
-void sms_ir_exit(struct smscore_device_t *coredev);
-void sms_ir_event(struct smscore_device_t *coredev,
-                       const char *buf, int len);
-
-#endif /* __SMS_IR_H__ */
-
diff --git a/drivers/media/usb/siano/smssdio.c b/drivers/media/usb/siano/smssdio.c
deleted file mode 100644 (file)
index d6f3f10..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- *  smssdio.c - Siano 1xxx SDIO interface driver
- *
- *  Copyright 2008 Pierre Ossman
- *
- * Based on code by Siano Mobile Silicon, Inc.,
- * Copyright (C) 2006-2008, Uri Shkolnik
- *
- * 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 hardware is a bit odd in that all transfers should be done
- * to/from the SMSSDIO_DATA register, yet the "increase address" bit
- * always needs to be set.
- *
- * Also, buffers from the card are always aligned to 128 byte
- * boundaries.
- */
-
-/*
- * General cleanup notes:
- *
- * - only typedefs should be name *_t
- *
- * - use ERR_PTR and friends for smscore_register_device()
- *
- * - smscore_getbuffer should zero fields
- *
- * Fix stop command
- */
-
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/module.h>
-
-#include "smscoreapi.h"
-#include "sms-cards.h"
-
-/* Registers */
-
-#define SMSSDIO_DATA           0x00
-#define SMSSDIO_INT            0x04
-#define SMSSDIO_BLOCK_SIZE     128
-
-static const struct sdio_device_id smssdio_ids[] __devinitconst = {
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
-        .driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
-        .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A},
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0),
-        .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B},
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0),
-        .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
-       {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE),
-        .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
-       { /* end: all zeroes */ },
-};
-
-MODULE_DEVICE_TABLE(sdio, smssdio_ids);
-
-struct smssdio_device {
-       struct sdio_func *func;
-
-       struct smscore_device_t *coredev;
-
-       struct smscore_buffer_t *split_cb;
-};
-
-/*******************************************************************/
-/* Siano core callbacks                                            */
-/*******************************************************************/
-
-static int smssdio_sendrequest(void *context, void *buffer, size_t size)
-{
-       int ret = 0;
-       struct smssdio_device *smsdev;
-
-       smsdev = context;
-
-       sdio_claim_host(smsdev->func);
-
-       while (size >= smsdev->func->cur_blksize) {
-               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
-                                       buffer, smsdev->func->cur_blksize);
-               if (ret)
-                       goto out;
-
-               buffer += smsdev->func->cur_blksize;
-               size -= smsdev->func->cur_blksize;
-       }
-
-       if (size) {
-               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
-                                       buffer, size);
-       }
-
-out:
-       sdio_release_host(smsdev->func);
-
-       return ret;
-}
-
-/*******************************************************************/
-/* SDIO callbacks                                                  */
-/*******************************************************************/
-
-static void smssdio_interrupt(struct sdio_func *func)
-{
-       int ret;
-
-       struct smssdio_device *smsdev;
-       struct smscore_buffer_t *cb;
-       struct SmsMsgHdr_ST *hdr;
-       size_t size;
-
-       smsdev = sdio_get_drvdata(func);
-
-       /*
-        * The interrupt register has no defined meaning. It is just
-        * a way of turning of the level triggered interrupt.
-        */
-       (void)sdio_readb(func, SMSSDIO_INT, &ret);
-       if (ret) {
-               sms_err("Unable to read interrupt register!\n");
-               return;
-       }
-
-       if (smsdev->split_cb == NULL) {
-               cb = smscore_getbuffer(smsdev->coredev);
-               if (!cb) {
-                       sms_err("Unable to allocate data buffer!\n");
-                       return;
-               }
-
-               ret = sdio_memcpy_fromio(smsdev->func,
-                                        cb->p,
-                                        SMSSDIO_DATA,
-                                        SMSSDIO_BLOCK_SIZE);
-               if (ret) {
-                       sms_err("Error %d reading initial block!\n", ret);
-                       return;
-               }
-
-               hdr = cb->p;
-
-               if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) {
-                       smsdev->split_cb = cb;
-                       return;
-               }
-
-               if (hdr->msgLength > smsdev->func->cur_blksize)
-                       size = hdr->msgLength - smsdev->func->cur_blksize;
-               else
-                       size = 0;
-       } else {
-               cb = smsdev->split_cb;
-               hdr = cb->p;
-
-               size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST);
-
-               smsdev->split_cb = NULL;
-       }
-
-       if (size) {
-               void *buffer;
-
-               buffer = cb->p + (hdr->msgLength - size);
-               size = ALIGN(size, SMSSDIO_BLOCK_SIZE);
-
-               BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE);
-
-               /*
-                * First attempt to transfer all of it in one go...
-                */
-               ret = sdio_memcpy_fromio(smsdev->func,
-                                        buffer,
-                                        SMSSDIO_DATA,
-                                        size);
-               if (ret && ret != -EINVAL) {
-                       smscore_putbuffer(smsdev->coredev, cb);
-                       sms_err("Error %d reading data from card!\n", ret);
-                       return;
-               }
-
-               /*
-                * ..then fall back to one block at a time if that is
-                * not possible...
-                *
-                * (we have to do this manually because of the
-                * problem with the "increase address" bit)
-                */
-               if (ret == -EINVAL) {
-                       while (size) {
-                               ret = sdio_memcpy_fromio(smsdev->func,
-                                                 buffer, SMSSDIO_DATA,
-                                                 smsdev->func->cur_blksize);
-                               if (ret) {
-                                       smscore_putbuffer(smsdev->coredev, cb);
-                                       sms_err("Error %d reading "
-                                               "data from card!\n", ret);
-                                       return;
-                               }
-
-                               buffer += smsdev->func->cur_blksize;
-                               if (size > smsdev->func->cur_blksize)
-                                       size -= smsdev->func->cur_blksize;
-                               else
-                                       size = 0;
-                       }
-               }
-       }
-
-       cb->size = hdr->msgLength;
-       cb->offset = 0;
-
-       smscore_onresponse(smsdev->coredev, cb);
-}
-
-static int __devinit smssdio_probe(struct sdio_func *func,
-                        const struct sdio_device_id *id)
-{
-       int ret;
-
-       int board_id;
-       struct smssdio_device *smsdev;
-       struct smsdevice_params_t params;
-
-       board_id = id->driver_data;
-
-       smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL);
-       if (!smsdev)
-               return -ENOMEM;
-
-       smsdev->func = func;
-
-       memset(&params, 0, sizeof(struct smsdevice_params_t));
-
-       params.device = &func->dev;
-       params.buffer_size = 0x5000;    /* ?? */
-       params.num_buffers = 22;        /* ?? */
-       params.context = smsdev;
-
-       snprintf(params.devpath, sizeof(params.devpath),
-                "sdio\\%s", sdio_func_id(func));
-
-       params.sendrequest_handler = smssdio_sendrequest;
-
-       params.device_type = sms_get_board(board_id)->type;
-
-       if (params.device_type != SMS_STELLAR)
-               params.flags |= SMS_DEVICE_FAMILY2;
-       else {
-               /*
-                * FIXME: Stellar needs special handling...
-                */
-               ret = -ENODEV;
-               goto free;
-       }
-
-       ret = smscore_register_device(&params, &smsdev->coredev);
-       if (ret < 0)
-               goto free;
-
-       smscore_set_board_id(smsdev->coredev, board_id);
-
-       sdio_claim_host(func);
-
-       ret = sdio_enable_func(func);
-       if (ret)
-               goto release;
-
-       ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE);
-       if (ret)
-               goto disable;
-
-       ret = sdio_claim_irq(func, smssdio_interrupt);
-       if (ret)
-               goto disable;
-
-       sdio_set_drvdata(func, smsdev);
-
-       sdio_release_host(func);
-
-       ret = smscore_start_device(smsdev->coredev);
-       if (ret < 0)
-               goto reclaim;
-
-       return 0;
-
-reclaim:
-       sdio_claim_host(func);
-       sdio_release_irq(func);
-disable:
-       sdio_disable_func(func);
-release:
-       sdio_release_host(func);
-       smscore_unregister_device(smsdev->coredev);
-free:
-       kfree(smsdev);
-
-       return ret;
-}
-
-static void smssdio_remove(struct sdio_func *func)
-{
-       struct smssdio_device *smsdev;
-
-       smsdev = sdio_get_drvdata(func);
-
-       /* FIXME: racy! */
-       if (smsdev->split_cb)
-               smscore_putbuffer(smsdev->coredev, smsdev->split_cb);
-
-       smscore_unregister_device(smsdev->coredev);
-
-       sdio_claim_host(func);
-       sdio_release_irq(func);
-       sdio_disable_func(func);
-       sdio_release_host(func);
-
-       kfree(smsdev);
-}
-
-static struct sdio_driver smssdio_driver = {
-       .name = "smssdio",
-       .id_table = smssdio_ids,
-       .probe = smssdio_probe,
-       .remove = smssdio_remove,
-};
-
-/*******************************************************************/
-/* Module functions                                                */
-/*******************************************************************/
-
-static int __init smssdio_module_init(void)
-{
-       int ret = 0;
-
-       printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n");
-       printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n");
-
-       ret = sdio_register_driver(&smssdio_driver);
-
-       return ret;
-}
-
-static void __exit smssdio_module_exit(void)
-{
-       sdio_unregister_driver(&smssdio_driver);
-}
-
-module_init(smssdio_module_init);
-module_exit(smssdio_module_exit);
-
-MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver");
-MODULE_AUTHOR("Pierre Ossman");
-MODULE_LICENSE("GPL");