diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-06-14 16:36:01 -0300 | 
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 23:52:52 -0300 | 
| commit | 0013ca8c52ba7bb1030ed75d6df7e58af0314018 (patch) | |
| tree | 31672d38162cff3dee895d1d815a8dd85ba67d5d /drivers/media/usb/siano | |
| parent | ed0c8b5465d6cec5458d9a3041a5167d83f40fdb (diff) | |
| download | linux-0013ca8c52ba7bb1030ed75d6df7e58af0314018.tar.bz2 | |
[media] siano: break it into common, mmc and usb
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>
Diffstat (limited to 'drivers/media/usb/siano')
| -rw-r--r-- | drivers/media/usb/siano/Kconfig | 26 | ||||
| -rw-r--r-- | drivers/media/usb/siano/Makefile | 7 | ||||
| -rw-r--r-- | drivers/media/usb/siano/sms-cards.c | 311 | ||||
| -rw-r--r-- | drivers/media/usb/siano/sms-cards.h | 123 | ||||
| -rw-r--r-- | drivers/media/usb/siano/smscoreapi.c | 1637 | ||||
| -rw-r--r-- | drivers/media/usb/siano/smscoreapi.h | 775 | ||||
| -rw-r--r-- | drivers/media/usb/siano/smsdvb.c | 1078 | ||||
| -rw-r--r-- | drivers/media/usb/siano/smsendian.c | 103 | ||||
| -rw-r--r-- | drivers/media/usb/siano/smsendian.h | 32 | ||||
| -rw-r--r-- | drivers/media/usb/siano/smsir.c | 114 | ||||
| -rw-r--r-- | drivers/media/usb/siano/smsir.h | 55 | ||||
| -rw-r--r-- | drivers/media/usb/siano/smssdio.c | 365 | 
12 files changed, 2 insertions, 4624 deletions
| diff --git a/drivers/media/usb/siano/Kconfig b/drivers/media/usb/siano/Kconfig index bc6456eb2c4f..3c76e62d820d 100644 --- a/drivers/media/usb/siano/Kconfig +++ b/drivers/media/usb/siano/Kconfig @@ -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 diff --git a/drivers/media/usb/siano/Makefile b/drivers/media/usb/siano/Makefile index 14756bdb6eaa..758b6a090c59 100644 --- a/drivers/media/usb/siano/Makefile +++ b/drivers/media/usb/siano/Makefile @@ -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 index 680c781c8dd6..000000000000 --- a/drivers/media/usb/siano/sms-cards.c +++ /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 index d8cdf756f7cf..000000000000 --- a/drivers/media/usb/siano/sms-cards.h +++ /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 index 9cc55546cc30..000000000000 --- a/drivers/media/usb/siano/smscoreapi.c +++ /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(¬ifyee->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(¬ifyee->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(¬ifyee->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 index c592ae090397..000000000000 --- a/drivers/media/usb/siano/smscoreapi.h +++ /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 index aa77e54a8fae..000000000000 --- a/drivers/media/usb/siano/smsdvb.c +++ /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, ¶ms, &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 index e2657c2f0109..000000000000 --- a/drivers/media/usb/siano/smsendian.c +++ /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 index 1624d6fd367b..000000000000 --- a/drivers/media/usb/siano/smsendian.h +++ /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 index 37bc5c4b8ad8..000000000000 --- a/drivers/media/usb/siano/smsir.c +++ /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 index ae92b3a8587e..000000000000 --- a/drivers/media/usb/siano/smsir.h +++ /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 index d6f3f100699a..000000000000 --- a/drivers/media/usb/siano/smssdio.c +++ /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(¶ms, 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(¶ms, &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"); |