Merge remote-tracking branch 'stable/linux-3.0.y' into develop-3.0
[firefly-linux-kernel-4.4.55.git] / drivers / cmmb / siano / sms-cards.c
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
22 struct usb_device_id smsusb_id_table[] = {
23         { USB_DEVICE(0x187f, 0x0010),
24                 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
25         { USB_DEVICE(0x187f, 0x0100),
26                 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
27         { USB_DEVICE(0x187f, 0x0200),
28                 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
29         { USB_DEVICE(0x187f, 0x0201),
30                 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
31         { USB_DEVICE(0x187f, 0x0300),
32                 .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
33         { USB_DEVICE(0x2040, 0x1700),
34                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
35         { USB_DEVICE(0x2040, 0x1800),
36                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
37         { USB_DEVICE(0x2040, 0x1801),
38                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
39         { USB_DEVICE(0x2040, 0x2000),
40                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
41         { USB_DEVICE(0x2040, 0x2009),
42                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
43         { USB_DEVICE(0x2040, 0x200a),
44                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
45         { USB_DEVICE(0x2040, 0x2010),
46                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
47         { USB_DEVICE(0x2040, 0x2019),
48                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
49         { USB_DEVICE(0x2040, 0x5500),
50                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
51         { USB_DEVICE(0x2040, 0x5510),
52                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
53         { USB_DEVICE(0x2040, 0x5520),
54                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
55         { USB_DEVICE(0x2040, 0x5530),
56                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
57         { USB_DEVICE(0x2040, 0x5580),
58                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
59         { USB_DEVICE(0x2040, 0x5590),
60                 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
61         { USB_DEVICE(0x187f, 0x0202),
62                 .driver_info = SMS1XXX_BOARD_SIANO_NICE },
63         { USB_DEVICE(0x187f, 0x0301),
64                 .driver_info = SMS1XXX_BOARD_SIANO_VENICE },
65         { } /* Terminating entry */
66         };
67
68 MODULE_DEVICE_TABLE(usb, smsusb_id_table);
69
70 static struct sms_board sms_boards[] = {
71         [SMS_BOARD_UNKNOWN] = {
72         /* 0 */
73                 .name = "Unknown board",
74         },
75         [SMS1XXX_BOARD_SIANO_STELLAR] = {
76         /* 1 */
77                 .name =
78                 "Siano Stellar Digital Receiver",
79                 .type = SMS_STELLAR,
80                 .fw[DEVICE_MODE_DVBT_BDA] =
81                 "sms1xxx-stellar-dvbt-01.fw",
82         },
83         [SMS1XXX_BOARD_SIANO_NOVA_A] = {
84         /* 2 */
85                 .name = "Siano Nova A Digital Receiver",
86                 .type = SMS_NOVA_A0,
87                 .fw[DEVICE_MODE_DVBT_BDA] =
88                 "sms1xxx-nova-a-dvbt-01.fw",
89         },
90         [SMS1XXX_BOARD_SIANO_NOVA_B] = {
91         /* 3 */
92                 .name = "Siano Nova B Digital Receiver",
93                 .type = SMS_NOVA_B0,
94                 .fw[DEVICE_MODE_DVBT_BDA] =
95                 "sms1xxx-nova-b-dvbt-01.fw",
96         },
97         [SMS1XXX_BOARD_SIANO_VEGA] = {
98         /* 4 */
99                 .name = "Siano Vega Digital Receiver",
100                 .type = SMS_VEGA,
101         },
102         [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
103         /* 5 */
104                 .name = "Hauppauge Catamount",
105                 .type = SMS_STELLAR,
106                 .fw[DEVICE_MODE_DVBT_BDA] =
107                 "sms1xxx-stellar-dvbt-01.fw",
108         },
109         [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
110         /* 6 */
111                 .name = "Hauppauge Okemo-A",
112                 .type = SMS_NOVA_A0,
113                 .fw[DEVICE_MODE_DVBT_BDA] =
114                 "sms1xxx-nova-a-dvbt-01.fw",
115         },
116         [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
117         /* 7 */
118                 .name = "Hauppauge Okemo-B",
119                 .type = SMS_NOVA_B0,
120                 .fw[DEVICE_MODE_DVBT_BDA] =
121                 "sms1xxx-nova-b-dvbt-01.fw",
122         },
123         [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
124         /* 8 */
125                 .name = "Hauppauge WinTV MiniStick",
126                 .type = SMS_NOVA_B0,
127                 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
128                 .board_cfg.leds_power = 26,
129                 .board_cfg.led0 = 27,
130                 .board_cfg.led1 = 28,
131         },
132         [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
133         /* 9 */
134                 .name = "Hauppauge WinTV MiniCard",
135                 .type = SMS_NOVA_B0,
136                 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
137                 .board_cfg.foreign_lna0_ctrl = 29,
138         },
139         [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
140         /* 10 */
141                 .name = "Hauppauge WinTV MiniCard",
142                 .type = SMS_NOVA_B0,
143                 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
144                 .board_cfg.foreign_lna0_ctrl = 1,
145         },
146         [SMS1XXX_BOARD_SIANO_NICE] = {
147         /* 11 */
148                 .name = "Siano Nice Digital Receiver",
149                 .type = SMS_NOVA_B0,
150         },
151         [SMS1XXX_BOARD_SIANO_VENICE] = {
152         /* 12 */
153                 .name = "Siano Venice Digital Receiver",
154                 .type = SMS_VEGA,
155         },
156 };
157
158 struct sms_board *sms_get_board(int id)
159 {
160         BUG_ON(id >= ARRAY_SIZE(sms_boards));
161         return &sms_boards[id];
162 }
163
164 static inline void sms_gpio_assign_11xx_default_led_config(
165                 struct smscore_gpio_config *pGpioConfig) {
166         pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
167         pGpioConfig->InputCharacteristics =
168                 SMS_GPIO_INPUTCHARACTERISTICS_NORMAL;
169         pGpioConfig->OutputDriving = SMS_GPIO_OUTPUTDRIVING_4mA;
170         pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUTSLEWRATE_0_45_V_NS;
171         pGpioConfig->PullUpDown = SMS_GPIO_PULLUPDOWN_NONE;
172 }
173
174 int sms_board_event(struct smscore_device_t *coredev,
175                 enum SMS_BOARD_EVENTS gevent) {
176         int board_id = smscore_get_board_id(coredev);
177         struct sms_board *board = sms_get_board(board_id);
178         struct smscore_gpio_config MyGpioConfig;
179
180         sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
181
182         switch (gevent) {
183         case BOARD_EVENT_POWER_INIT: /* including hotplug */
184                 switch (board_id) {
185                 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
186                         /* set I/O and turn off all LEDs */
187                         smscore_gpio_configure(coredev,
188                                         board->board_cfg.leds_power,
189                                         &MyGpioConfig);
190                         smscore_gpio_set_level(coredev,
191                                         board->board_cfg.leds_power, 0);
192                         smscore_gpio_configure(coredev, board->board_cfg.led0,
193                                         &MyGpioConfig);
194                         smscore_gpio_set_level(coredev,
195                                         board->board_cfg.led0, 0);
196                         smscore_gpio_configure(coredev, board->board_cfg.led1,
197                                         &MyGpioConfig);
198                         smscore_gpio_set_level(coredev,
199                                         board->board_cfg.led1, 0);
200                         break;
201                 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
202                 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
203                         /* set I/O and turn off LNA */
204                         smscore_gpio_configure(coredev,
205                                         board->board_cfg.foreign_lna0_ctrl,
206                                         &MyGpioConfig);
207                         smscore_gpio_set_level(coredev,
208                                         board->board_cfg.foreign_lna0_ctrl,
209                                         0);
210                         break;
211                 }
212                 break; /* BOARD_EVENT_BIND */
213
214         case BOARD_EVENT_POWER_SUSPEND:
215                 switch (board_id) {
216                 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
217                         smscore_gpio_set_level(coredev,
218                                                 board->board_cfg.leds_power, 0);
219                         smscore_gpio_set_level(coredev,
220                                                 board->board_cfg.led0, 0);
221                         smscore_gpio_set_level(coredev,
222                                                 board->board_cfg.led1, 0);
223                         break;
224                 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
225                 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
226                         smscore_gpio_set_level(coredev,
227                                         board->board_cfg.foreign_lna0_ctrl,
228                                         0);
229                         break;
230                 }
231                 break; /* BOARD_EVENT_POWER_SUSPEND */
232
233         case BOARD_EVENT_POWER_RESUME:
234                 switch (board_id) {
235                 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
236                         smscore_gpio_set_level(coredev,
237                                                 board->board_cfg.leds_power, 1);
238                         smscore_gpio_set_level(coredev,
239                                                 board->board_cfg.led0, 1);
240                         smscore_gpio_set_level(coredev,
241                                                 board->board_cfg.led1, 0);
242                         break;
243                 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
244                 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
245                         smscore_gpio_set_level(coredev,
246                                         board->board_cfg.foreign_lna0_ctrl,
247                                         1);
248                         break;
249                 }
250                 break; /* BOARD_EVENT_POWER_RESUME */
251
252         case BOARD_EVENT_BIND:
253                 switch (board_id) {
254                 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
255                         smscore_gpio_set_level(coredev,
256                                 board->board_cfg.leds_power, 1);
257                         smscore_gpio_set_level(coredev,
258                                 board->board_cfg.led0, 1);
259                         smscore_gpio_set_level(coredev,
260                                 board->board_cfg.led1, 0);
261                         break;
262                 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
263                 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
264                         smscore_gpio_set_level(coredev,
265                                         board->board_cfg.foreign_lna0_ctrl,
266                                         1);
267                         break;
268                 }
269                 break; /* BOARD_EVENT_BIND */
270
271         case BOARD_EVENT_SCAN_PROG:
272                 break; /* BOARD_EVENT_SCAN_PROG */
273         case BOARD_EVENT_SCAN_COMP:
274                 break; /* BOARD_EVENT_SCAN_COMP */
275         case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
276                 break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
277         case BOARD_EVENT_FE_LOCK:
278                 switch (board_id) {
279                 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
280                         smscore_gpio_set_level(coredev,
281                         board->board_cfg.led1, 1);
282                         break;
283                 }
284                 break; /* BOARD_EVENT_FE_LOCK */
285         case BOARD_EVENT_FE_UNLOCK:
286                 switch (board_id) {
287                 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
288                         smscore_gpio_set_level(coredev,
289                                                 board->board_cfg.led1, 0);
290                         break;
291                 }
292                 break; /* BOARD_EVENT_FE_UNLOCK */
293         case BOARD_EVENT_DEMOD_LOCK:
294                 break; /* BOARD_EVENT_DEMOD_LOCK */
295         case BOARD_EVENT_DEMOD_UNLOCK:
296                 break; /* BOARD_EVENT_DEMOD_UNLOCK */
297         case BOARD_EVENT_RECEPTION_MAX_4:
298                 break; /* BOARD_EVENT_RECEPTION_MAX_4 */
299         case BOARD_EVENT_RECEPTION_3:
300                 break; /* BOARD_EVENT_RECEPTION_3 */
301         case BOARD_EVENT_RECEPTION_2:
302                 break; /* BOARD_EVENT_RECEPTION_2 */
303         case BOARD_EVENT_RECEPTION_1:
304                 break; /* BOARD_EVENT_RECEPTION_1 */
305         case BOARD_EVENT_RECEPTION_LOST_0:
306                 break; /* BOARD_EVENT_RECEPTION_LOST_0 */
307         case BOARD_EVENT_MULTIPLEX_OK:
308                 switch (board_id) {
309                 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
310                         smscore_gpio_set_level(coredev,
311                                                 board->board_cfg.led1, 1);
312                         break;
313                 }
314                 break; /* BOARD_EVENT_MULTIPLEX_OK */
315         case BOARD_EVENT_MULTIPLEX_ERRORS:
316                 switch (board_id) {
317                 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
318                         smscore_gpio_set_level(coredev,
319                                                 board->board_cfg.led1, 0);
320                         break;
321                 }
322                 break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
323
324         default:
325                 sms_err("Unknown SMS board event");
326                 break;
327         }
328         return 0;
329 }