• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/media/dvb/siano/
1/*
2 *  Card-specific functions for the Siano SMS1xxx USB dongle
3 *
4 *  Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
5 *
6 *  This program is free software; you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License version 2 as
8 *  published by the Free Software Foundation;
9 *
10 *  Software distributed under the License is distributed on an "AS IS"
11 *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
12 *
13 *  See the GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include "sms-cards.h"
21#include "smsir.h"
22
23static int sms_dbg;
24module_param_named(cards_dbg, sms_dbg, int, 0644);
25MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
26
27static struct sms_board sms_boards[] = {
28	[SMS_BOARD_UNKNOWN] = {
29		.name	= "Unknown board",
30	},
31	[SMS1XXX_BOARD_SIANO_STELLAR] = {
32		.name	= "Siano Stellar Digital Receiver",
33		.type	= SMS_STELLAR,
34	},
35	[SMS1XXX_BOARD_SIANO_NOVA_A] = {
36		.name	= "Siano Nova A Digital Receiver",
37		.type	= SMS_NOVA_A0,
38	},
39	[SMS1XXX_BOARD_SIANO_NOVA_B] = {
40		.name	= "Siano Nova B Digital Receiver",
41		.type	= SMS_NOVA_B0,
42	},
43	[SMS1XXX_BOARD_SIANO_VEGA] = {
44		.name	= "Siano Vega Digital Receiver",
45		.type	= SMS_VEGA,
46	},
47	[SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
48		.name	= "Hauppauge Catamount",
49		.type	= SMS_STELLAR,
50		.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
51	},
52	[SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
53		.name	= "Hauppauge Okemo-A",
54		.type	= SMS_NOVA_A0,
55		.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
56	},
57	[SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
58		.name	= "Hauppauge Okemo-B",
59		.type	= SMS_NOVA_B0,
60		.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
61	},
62	[SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
63		.name	= "Hauppauge WinTV MiniStick",
64		.type	= SMS_NOVA_B0,
65		.fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
66		.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
67		.rc_codes = RC_MAP_RC5_HAUPPAUGE_NEW,
68		.board_cfg.leds_power = 26,
69		.board_cfg.led0 = 27,
70		.board_cfg.led1 = 28,
71		.board_cfg.ir = 9,
72		.led_power = 26,
73		.led_lo    = 27,
74		.led_hi    = 28,
75	},
76	[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
77		.name	= "Hauppauge WinTV MiniCard",
78		.type	= SMS_NOVA_B0,
79		.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
80		.lna_ctrl  = 29,
81		.board_cfg.foreign_lna0_ctrl = 29,
82		.rf_switch = 17,
83		.board_cfg.rf_switch_uhf = 17,
84	},
85	[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
86		.name	= "Hauppauge WinTV MiniCard",
87		.type	= SMS_NOVA_B0,
88		.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
89		.lna_ctrl  = -1,
90	},
91	[SMS1XXX_BOARD_SIANO_NICE] = {
92	/* 11 */
93		.name = "Siano Nice Digital Receiver",
94		.type = SMS_NOVA_B0,
95	},
96	[SMS1XXX_BOARD_SIANO_VENICE] = {
97	/* 12 */
98		.name = "Siano Venice Digital Receiver",
99		.type = SMS_VEGA,
100	},
101};
102
103struct sms_board *sms_get_board(unsigned id)
104{
105	BUG_ON(id >= ARRAY_SIZE(sms_boards));
106
107	return &sms_boards[id];
108}
109EXPORT_SYMBOL_GPL(sms_get_board);
110static inline void sms_gpio_assign_11xx_default_led_config(
111		struct smscore_gpio_config *pGpioConfig) {
112	pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
113	pGpioConfig->InputCharacteristics =
114		SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
115	pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
116	pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
117	pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
118}
119
120int sms_board_event(struct smscore_device_t *coredev,
121		enum SMS_BOARD_EVENTS gevent) {
122	struct smscore_gpio_config MyGpioConfig;
123
124	sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
125
126	switch (gevent) {
127	case BOARD_EVENT_POWER_INIT: /* including hotplug */
128		break; /* BOARD_EVENT_BIND */
129
130	case BOARD_EVENT_POWER_SUSPEND:
131		break; /* BOARD_EVENT_POWER_SUSPEND */
132
133	case BOARD_EVENT_POWER_RESUME:
134		break; /* BOARD_EVENT_POWER_RESUME */
135
136	case BOARD_EVENT_BIND:
137		break; /* BOARD_EVENT_BIND */
138
139	case BOARD_EVENT_SCAN_PROG:
140		break; /* BOARD_EVENT_SCAN_PROG */
141	case BOARD_EVENT_SCAN_COMP:
142		break; /* BOARD_EVENT_SCAN_COMP */
143	case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
144		break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
145	case BOARD_EVENT_FE_LOCK:
146		break; /* BOARD_EVENT_FE_LOCK */
147	case BOARD_EVENT_FE_UNLOCK:
148		break; /* BOARD_EVENT_FE_UNLOCK */
149	case BOARD_EVENT_DEMOD_LOCK:
150		break; /* BOARD_EVENT_DEMOD_LOCK */
151	case BOARD_EVENT_DEMOD_UNLOCK:
152		break; /* BOARD_EVENT_DEMOD_UNLOCK */
153	case BOARD_EVENT_RECEPTION_MAX_4:
154		break; /* BOARD_EVENT_RECEPTION_MAX_4 */
155	case BOARD_EVENT_RECEPTION_3:
156		break; /* BOARD_EVENT_RECEPTION_3 */
157	case BOARD_EVENT_RECEPTION_2:
158		break; /* BOARD_EVENT_RECEPTION_2 */
159	case BOARD_EVENT_RECEPTION_1:
160		break; /* BOARD_EVENT_RECEPTION_1 */
161	case BOARD_EVENT_RECEPTION_LOST_0:
162		break; /* BOARD_EVENT_RECEPTION_LOST_0 */
163	case BOARD_EVENT_MULTIPLEX_OK:
164		break; /* BOARD_EVENT_MULTIPLEX_OK */
165	case BOARD_EVENT_MULTIPLEX_ERRORS:
166		break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
167
168	default:
169		sms_err("Unknown SMS board event");
170		break;
171	}
172	return 0;
173}
174EXPORT_SYMBOL_GPL(sms_board_event);
175
176static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
177{
178	int lvl, ret;
179	u32 gpio;
180	struct smscore_config_gpio gpioconfig = {
181		.direction            = SMS_GPIO_DIRECTION_OUTPUT,
182		.pullupdown           = SMS_GPIO_PULLUPDOWN_NONE,
183		.inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
184		.outputslewrate       = SMS_GPIO_OUTPUTSLEWRATE_FAST,
185		.outputdriving        = SMS_GPIO_OUTPUTDRIVING_4mA,
186	};
187
188	if (pin == 0)
189		return -EINVAL;
190
191	if (pin < 0) {
192		/* inverted gpio */
193		gpio = pin * -1;
194		lvl = enable ? 0 : 1;
195	} else {
196		gpio = pin;
197		lvl = enable ? 1 : 0;
198	}
199
200	ret = smscore_configure_gpio(coredev, gpio, &gpioconfig);
201	if (ret < 0)
202		return ret;
203
204	return smscore_set_gpio(coredev, gpio, lvl);
205}
206
207int sms_board_setup(struct smscore_device_t *coredev)
208{
209	int board_id = smscore_get_board_id(coredev);
210	struct sms_board *board = sms_get_board(board_id);
211
212	switch (board_id) {
213	case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
214		/* turn off all LEDs */
215		sms_set_gpio(coredev, board->led_power, 0);
216		sms_set_gpio(coredev, board->led_hi, 0);
217		sms_set_gpio(coredev, board->led_lo, 0);
218		break;
219	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
220	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
221		/* turn off LNA */
222		sms_set_gpio(coredev, board->lna_ctrl, 0);
223		break;
224	}
225	return 0;
226}
227EXPORT_SYMBOL_GPL(sms_board_setup);
228
229int sms_board_power(struct smscore_device_t *coredev, int onoff)
230{
231	int board_id = smscore_get_board_id(coredev);
232	struct sms_board *board = sms_get_board(board_id);
233
234	switch (board_id) {
235	case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
236		/* power LED */
237		sms_set_gpio(coredev,
238			     board->led_power, onoff ? 1 : 0);
239		break;
240	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
241	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
242		/* LNA */
243		if (!onoff)
244			sms_set_gpio(coredev, board->lna_ctrl, 0);
245		break;
246	}
247	return 0;
248}
249EXPORT_SYMBOL_GPL(sms_board_power);
250
251int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
252{
253	int board_id = smscore_get_board_id(coredev);
254	struct sms_board *board = sms_get_board(board_id);
255
256	/* dont touch GPIO if LEDs are already set */
257	if (smscore_led_state(coredev, -1) == led)
258		return 0;
259
260	switch (board_id) {
261	case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
262		sms_set_gpio(coredev,
263			     board->led_lo, (led & SMS_LED_LO) ? 1 : 0);
264		sms_set_gpio(coredev,
265			     board->led_hi, (led & SMS_LED_HI) ? 1 : 0);
266
267		smscore_led_state(coredev, led);
268		break;
269	}
270	return 0;
271}
272EXPORT_SYMBOL_GPL(sms_board_led_feedback);
273
274int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
275{
276	int board_id = smscore_get_board_id(coredev);
277	struct sms_board *board = sms_get_board(board_id);
278
279	sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
280
281	switch (board_id) {
282	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
283	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
284		sms_set_gpio(coredev,
285			     board->rf_switch, onoff ? 1 : 0);
286		return sms_set_gpio(coredev,
287				    board->lna_ctrl, onoff ? 1 : 0);
288	}
289	return -EINVAL;
290}
291EXPORT_SYMBOL_GPL(sms_board_lna_control);
292
293int sms_board_load_modules(int id)
294{
295	switch (id) {
296	case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
297	case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
298	case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
299	case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
300	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
301	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
302		request_module("smsdvb");
303		break;
304	default:
305		/* do nothing */
306		break;
307	}
308	return 0;
309}
310EXPORT_SYMBOL_GPL(sms_board_load_modules);
311