349 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Card-specific functions for the Siano SMS1xxx USB dongle4 *5 * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>6 */7 8#include "sms-cards.h"9#include "smsir.h"10#include <linux/module.h>11 12static struct sms_board sms_boards[] = {13 [SMS_BOARD_UNKNOWN] = {14 .name = "Unknown board",15 .type = SMS_UNKNOWN_TYPE,16 .default_mode = DEVICE_MODE_NONE,17 },18 [SMS1XXX_BOARD_SIANO_STELLAR] = {19 .name = "Siano Stellar Digital Receiver",20 .type = SMS_STELLAR,21 .default_mode = DEVICE_MODE_DVBT_BDA,22 },23 [SMS1XXX_BOARD_SIANO_NOVA_A] = {24 .name = "Siano Nova A Digital Receiver",25 .type = SMS_NOVA_A0,26 .default_mode = DEVICE_MODE_DVBT_BDA,27 },28 [SMS1XXX_BOARD_SIANO_NOVA_B] = {29 .name = "Siano Nova B Digital Receiver",30 .type = SMS_NOVA_B0,31 .default_mode = DEVICE_MODE_DVBT_BDA,32 },33 [SMS1XXX_BOARD_SIANO_VEGA] = {34 .name = "Siano Vega Digital Receiver",35 .type = SMS_VEGA,36 .default_mode = DEVICE_MODE_CMMB,37 },38 [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {39 .name = "Hauppauge Catamount",40 .type = SMS_STELLAR,41 .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_STELLAR,42 .default_mode = DEVICE_MODE_DVBT_BDA,43 },44 [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {45 .name = "Hauppauge Okemo-A",46 .type = SMS_NOVA_A0,47 .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_A,48 .default_mode = DEVICE_MODE_DVBT_BDA,49 },50 [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {51 .name = "Hauppauge Okemo-B",52 .type = SMS_NOVA_B0,53 .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_B,54 .default_mode = DEVICE_MODE_DVBT_BDA,55 },56 [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {57 .name = "Hauppauge WinTV MiniStick",58 .type = SMS_NOVA_B0,59 .fw[DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_HCW_55XXX,60 .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,61 .default_mode = DEVICE_MODE_DVBT_BDA,62 .rc_codes = RC_MAP_HAUPPAUGE,63 .board_cfg.leds_power = 26,64 .board_cfg.led0 = 27,65 .board_cfg.led1 = 28,66 .board_cfg.ir = 9,67 .led_power = 26,68 .led_lo = 27,69 .led_hi = 28,70 },71 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {72 .name = "Hauppauge WinTV MiniCard",73 .type = SMS_NOVA_B0,74 .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,75 .default_mode = DEVICE_MODE_DVBT_BDA,76 .lna_ctrl = 29,77 .board_cfg.foreign_lna0_ctrl = 29,78 .rf_switch = 17,79 .board_cfg.rf_switch_uhf = 17,80 },81 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {82 .name = "Hauppauge WinTV MiniCard Rev 2",83 .type = SMS_NOVA_B0,84 .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,85 .default_mode = DEVICE_MODE_DVBT_BDA,86 .lna_ctrl = -1,87 },88 [SMS1XXX_BOARD_SIANO_NICE] = {89 .name = "Siano Nice Digital Receiver",90 .type = SMS_NOVA_B0,91 .default_mode = DEVICE_MODE_DVBT_BDA,92 },93 [SMS1XXX_BOARD_SIANO_VENICE] = {94 .name = "Siano Venice Digital Receiver",95 .type = SMS_VEGA,96 .default_mode = DEVICE_MODE_CMMB,97 },98 [SMS1XXX_BOARD_SIANO_STELLAR_ROM] = {99 .name = "Siano Stellar Digital Receiver ROM",100 .type = SMS_STELLAR,101 .default_mode = DEVICE_MODE_DVBT_BDA,102 .intf_num = 1,103 },104 [SMS1XXX_BOARD_ZTE_DVB_DATA_CARD] = {105 .name = "ZTE Data Card Digital Receiver",106 .type = SMS_NOVA_B0,107 .default_mode = DEVICE_MODE_DVBT_BDA,108 .intf_num = 5,109 .mtu = 15792,110 },111 [SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD] = {112 .name = "ONDA Data Card Digital Receiver",113 .type = SMS_NOVA_B0,114 .default_mode = DEVICE_MODE_DVBT_BDA,115 .intf_num = 6,116 .mtu = 15792,117 },118 [SMS1XXX_BOARD_SIANO_MING] = {119 .name = "Siano Ming Digital Receiver",120 .type = SMS_MING,121 .default_mode = DEVICE_MODE_CMMB,122 },123 [SMS1XXX_BOARD_SIANO_PELE] = {124 .name = "Siano Pele Digital Receiver",125 .type = SMS_PELE,126 .default_mode = DEVICE_MODE_ISDBT_BDA,127 },128 [SMS1XXX_BOARD_SIANO_RIO] = {129 .name = "Siano Rio Digital Receiver",130 .type = SMS_RIO,131 .default_mode = DEVICE_MODE_ISDBT_BDA,132 },133 [SMS1XXX_BOARD_SIANO_DENVER_1530] = {134 .name = "Siano Denver (ATSC-M/H) Digital Receiver",135 .type = SMS_DENVER_1530,136 .default_mode = DEVICE_MODE_ATSC,137 .crystal = 2400,138 },139 [SMS1XXX_BOARD_SIANO_DENVER_2160] = {140 .name = "Siano Denver (TDMB) Digital Receiver",141 .type = SMS_DENVER_2160,142 .default_mode = DEVICE_MODE_DAB_TDMB,143 },144 [SMS1XXX_BOARD_PCTV_77E] = {145 .name = "Hauppauge microStick 77e",146 .type = SMS_NOVA_B0,147 .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_NOVA_12MHZ_B0,148 .default_mode = DEVICE_MODE_DVBT_BDA,149 },150};151 152struct sms_board *sms_get_board(unsigned id)153{154 BUG_ON(id >= ARRAY_SIZE(sms_boards));155 156 return &sms_boards[id];157}158EXPORT_SYMBOL_GPL(sms_get_board);159static inline void sms_gpio_assign_11xx_default_led_config(160 struct smscore_config_gpio *p_gpio_config) {161 p_gpio_config->direction = SMS_GPIO_DIRECTION_OUTPUT;162 p_gpio_config->inputcharacteristics =163 SMS_GPIO_INPUTCHARACTERISTICS_NORMAL;164 p_gpio_config->outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA;165 p_gpio_config->outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;166 p_gpio_config->pullupdown = SMS_GPIO_PULLUPDOWN_NONE;167}168 169int sms_board_event(struct smscore_device_t *coredev,170 enum SMS_BOARD_EVENTS gevent)171{172 struct smscore_config_gpio my_gpio_config;173 174 sms_gpio_assign_11xx_default_led_config(&my_gpio_config);175 176 switch (gevent) {177 case BOARD_EVENT_POWER_INIT: /* including hotplug */178 break; /* BOARD_EVENT_BIND */179 180 case BOARD_EVENT_POWER_SUSPEND:181 break; /* BOARD_EVENT_POWER_SUSPEND */182 183 case BOARD_EVENT_POWER_RESUME:184 break; /* BOARD_EVENT_POWER_RESUME */185 186 case BOARD_EVENT_BIND:187 break; /* BOARD_EVENT_BIND */188 189 case BOARD_EVENT_SCAN_PROG:190 break; /* BOARD_EVENT_SCAN_PROG */191 case BOARD_EVENT_SCAN_COMP:192 break; /* BOARD_EVENT_SCAN_COMP */193 case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:194 break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */195 case BOARD_EVENT_FE_LOCK:196 break; /* BOARD_EVENT_FE_LOCK */197 case BOARD_EVENT_FE_UNLOCK:198 break; /* BOARD_EVENT_FE_UNLOCK */199 case BOARD_EVENT_DEMOD_LOCK:200 break; /* BOARD_EVENT_DEMOD_LOCK */201 case BOARD_EVENT_DEMOD_UNLOCK:202 break; /* BOARD_EVENT_DEMOD_UNLOCK */203 case BOARD_EVENT_RECEPTION_MAX_4:204 break; /* BOARD_EVENT_RECEPTION_MAX_4 */205 case BOARD_EVENT_RECEPTION_3:206 break; /* BOARD_EVENT_RECEPTION_3 */207 case BOARD_EVENT_RECEPTION_2:208 break; /* BOARD_EVENT_RECEPTION_2 */209 case BOARD_EVENT_RECEPTION_1:210 break; /* BOARD_EVENT_RECEPTION_1 */211 case BOARD_EVENT_RECEPTION_LOST_0:212 break; /* BOARD_EVENT_RECEPTION_LOST_0 */213 case BOARD_EVENT_MULTIPLEX_OK:214 break; /* BOARD_EVENT_MULTIPLEX_OK */215 case BOARD_EVENT_MULTIPLEX_ERRORS:216 break; /* BOARD_EVENT_MULTIPLEX_ERRORS */217 218 default:219 pr_err("Unknown SMS board event\n");220 break;221 }222 return 0;223}224EXPORT_SYMBOL_GPL(sms_board_event);225 226static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)227{228 int lvl, ret;229 u32 gpio;230 struct smscore_config_gpio gpioconfig = {231 .direction = SMS_GPIO_DIRECTION_OUTPUT,232 .pullupdown = SMS_GPIO_PULLUPDOWN_NONE,233 .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,234 .outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_FAST,235 .outputdriving = SMS_GPIO_OUTPUTDRIVING_S_4mA,236 };237 238 if (pin == 0)239 return -EINVAL;240 241 if (pin < 0) {242 /* inverted gpio */243 gpio = pin * -1;244 lvl = enable ? 0 : 1;245 } else {246 gpio = pin;247 lvl = enable ? 1 : 0;248 }249 250 ret = smscore_configure_gpio(coredev, gpio, &gpioconfig);251 if (ret < 0)252 return ret;253 254 return smscore_set_gpio(coredev, gpio, lvl);255}256 257int sms_board_setup(struct smscore_device_t *coredev)258{259 int board_id = smscore_get_board_id(coredev);260 struct sms_board *board = sms_get_board(board_id);261 262 switch (board_id) {263 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:264 /* turn off all LEDs */265 sms_set_gpio(coredev, board->led_power, 0);266 sms_set_gpio(coredev, board->led_hi, 0);267 sms_set_gpio(coredev, board->led_lo, 0);268 break;269 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:270 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:271 /* turn off LNA */272 sms_set_gpio(coredev, board->lna_ctrl, 0);273 break;274 }275 return 0;276}277EXPORT_SYMBOL_GPL(sms_board_setup);278 279int sms_board_power(struct smscore_device_t *coredev, int onoff)280{281 int board_id = smscore_get_board_id(coredev);282 struct sms_board *board = sms_get_board(board_id);283 284 switch (board_id) {285 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:286 /* power LED */287 sms_set_gpio(coredev,288 board->led_power, onoff ? 1 : 0);289 break;290 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:291 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:292 /* LNA */293 if (!onoff)294 sms_set_gpio(coredev, board->lna_ctrl, 0);295 break;296 }297 return 0;298}299EXPORT_SYMBOL_GPL(sms_board_power);300 301int sms_board_led_feedback(struct smscore_device_t *coredev, int led)302{303 int board_id = smscore_get_board_id(coredev);304 struct sms_board *board = sms_get_board(board_id);305 306 /* don't touch GPIO if LEDs are already set */307 if (smscore_led_state(coredev, -1) == led)308 return 0;309 310 switch (board_id) {311 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:312 sms_set_gpio(coredev,313 board->led_lo, (led & SMS_LED_LO) ? 1 : 0);314 sms_set_gpio(coredev,315 board->led_hi, (led & SMS_LED_HI) ? 1 : 0);316 317 smscore_led_state(coredev, led);318 break;319 }320 return 0;321}322EXPORT_SYMBOL_GPL(sms_board_led_feedback);323 324int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)325{326 int board_id = smscore_get_board_id(coredev);327 struct sms_board *board = sms_get_board(board_id);328 329 pr_debug("%s: LNA %s\n", __func__, onoff ? "enabled" : "disabled");330 331 switch (board_id) {332 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:333 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:334 sms_set_gpio(coredev,335 board->rf_switch, onoff ? 1 : 0);336 return sms_set_gpio(coredev,337 board->lna_ctrl, onoff ? 1 : 0);338 }339 return -EINVAL;340}341EXPORT_SYMBOL_GPL(sms_board_lna_control);342 343int sms_board_load_modules(int id)344{345 request_module("smsdvb");346 return 0;347}348EXPORT_SYMBOL_GPL(sms_board_load_modules);349