int sms_ir_init(struct smscore_device_t *coredev) { struct input_dev *input_dev; sms_log("Allocating input device"); input_dev = input_allocate_device(); if (!input_dev) { sms_err("Not enough memory"); return -ENOMEM; } coredev->ir.input_dev = input_dev; coredev->ir.ir_kb_type = sms_get_board(smscore_get_board_id(coredev))->ir_kb_type; coredev->ir.keyboard_layout_map = keyboard_layout_maps[coredev->ir.ir_kb_type]. keyboard_layout_map; sms_log("IR remote keyboard type is %d", coredev->ir.ir_kb_type); 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, IR_DEV_NAME_MAX_LEN, "SMS IR w/kbd type %d", coredev->ir.ir_kb_type); input_dev->name = coredev->ir.name; input_dev->phys = coredev->ir.name; input_dev->dev.parent = coredev->device; /* Key press events only */ input_dev->evbit[0] = BIT_MASK(EV_KEY); input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); sms_log("Input device (IR) %s is set for key events", input_dev->name); if (input_register_device(input_dev)) { sms_err("Failed to register device"); input_free_device(input_dev); return -EACCES; } return 0; }
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; }
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; }
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; }
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; }
static int 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, 128); 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; }
int sms_board_event(struct smscore_device_t *coredev, enum SMS_BOARD_EVENTS gevent) { int board_id = smscore_get_board_id(coredev); struct sms_board *board = sms_get_board(board_id); struct smscore_gpio_config MyGpioConfig; sms_gpio_assign_11xx_default_led_config(&MyGpioConfig); switch (gevent) { case BOARD_EVENT_POWER_INIT: /* including hotplug */ switch (board_id) { case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: /* set I/O and turn off all LEDs */ smscore_gpio_configure(coredev, board->board_cfg.leds_power, &MyGpioConfig); smscore_gpio_set_level(coredev, board->board_cfg.leds_power, 0); smscore_gpio_configure(coredev, board->board_cfg.led0, &MyGpioConfig); smscore_gpio_set_level(coredev, board->board_cfg.led0, 0); smscore_gpio_configure(coredev, board->board_cfg.led1, &MyGpioConfig); smscore_gpio_set_level(coredev, board->board_cfg.led1, 0); break; case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: /* set I/O and turn off LNA */ smscore_gpio_configure(coredev, board->board_cfg.foreign_lna0_ctrl, &MyGpioConfig); smscore_gpio_set_level(coredev, board->board_cfg.foreign_lna0_ctrl, 0); break; } break; /* BOARD_EVENT_BIND */ case BOARD_EVENT_POWER_SUSPEND: switch (board_id) { case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: smscore_gpio_set_level(coredev, board->board_cfg.leds_power, 0); smscore_gpio_set_level(coredev, board->board_cfg.led0, 0); smscore_gpio_set_level(coredev, board->board_cfg.led1, 0); break; case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: smscore_gpio_set_level(coredev, board->board_cfg.foreign_lna0_ctrl, 0); break; } break; /* BOARD_EVENT_POWER_SUSPEND */ case BOARD_EVENT_POWER_RESUME: switch (board_id) { case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: smscore_gpio_set_level(coredev, board->board_cfg.leds_power, 1); smscore_gpio_set_level(coredev, board->board_cfg.led0, 1); smscore_gpio_set_level(coredev, board->board_cfg.led1, 0); break; case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: smscore_gpio_set_level(coredev, board->board_cfg.foreign_lna0_ctrl, 1); break; } break; /* BOARD_EVENT_POWER_RESUME */ case BOARD_EVENT_BIND: switch (board_id) { case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: smscore_gpio_set_level(coredev, board->board_cfg.leds_power, 1); smscore_gpio_set_level(coredev, board->board_cfg.led0, 1); smscore_gpio_set_level(coredev, board->board_cfg.led1, 0); break; case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: smscore_gpio_set_level(coredev, board->board_cfg.foreign_lna0_ctrl, 1); break; } 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: switch (board_id) { case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: smscore_gpio_set_level(coredev, board->board_cfg.led1, 1); break; } break; /* BOARD_EVENT_FE_LOCK */ case BOARD_EVENT_FE_UNLOCK: switch (board_id) { case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: smscore_gpio_set_level(coredev, board->board_cfg.led1, 0); break; } 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: switch (board_id) { case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: smscore_gpio_set_level(coredev, board->board_cfg.led1, 1); break; } break; /* BOARD_EVENT_MULTIPLEX_OK */ case BOARD_EVENT_MULTIPLEX_ERRORS: switch (board_id) { case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: smscore_gpio_set_level(coredev, board->board_cfg.led1, 0); break; } break; /* BOARD_EVENT_MULTIPLEX_ERRORS */ default: sms_err("Unknown SMS board event"); break; } return 0; }
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; if (smscore_get_device_mode(coredev) != 4) { sms_err("SMS Device mode is not set for " "DVB operation."); 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)); 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); init_completion(&client->stat_done); kmutex_lock(&g_smsdvb_clientslock); list_add(&client->entry, &g_smsdvb_clients); kmutex_unlock(&g_smsdvb_clientslock); 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 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); int board_id = smscore_get_board_id(client->coredev); struct sms_board *board = sms_get_board(board_id); enum sms_device_type_st type = board->type; int ret; struct { struct sms_msg_hdr msg; u32 Data[4]; } msg; fe->dtv_property_cache.delivery_system = SYS_ISDBT; msg.msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID; msg.msg.msg_dst_id = HIF_TASK; msg.msg.msg_flags = 0; msg.msg.msg_type = MSG_SMS_ISDBT_TUNE_REQ; msg.msg.msg_length = sizeof(msg); if (c->isdbt_sb_segment_idx == -1) c->isdbt_sb_segment_idx = 0; if (!c->isdbt_layer_enabled) c->isdbt_layer_enabled = 7; msg.Data[0] = c->frequency; msg.Data[1] = BW_ISDBT_1SEG; msg.Data[2] = 12000000; msg.Data[3] = c->isdbt_sb_segment_idx; if (c->isdbt_partial_reception) { if ((type == SMS_PELE || type == SMS_RIO) && c->isdbt_sb_segment_count > 3) msg.Data[1] = BW_ISDBT_13SEG; else if (c->isdbt_sb_segment_count > 1) msg.Data[1] = BW_ISDBT_3SEG; } else if (type == SMS_PELE || type == SMS_RIO) msg.Data[1] = BW_ISDBT_13SEG; c->bandwidth_hz = 6000000; pr_debug("freq %d segwidth %d segindex %d\n", c->frequency, c->isdbt_sb_segment_count, c->isdbt_sb_segment_idx); /* Disable LNA, if any. An error is returned if no LNA is present */ ret = sms_board_lna_control(client->coredev, 0); if (ret == 0) { enum fe_status 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_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) 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) { pr_err("dvb_register_adapter() failed %d\n", rc); goto adapter_error; } dvb_register_media_controller(&client->adapter, coredev->media_dev); /* 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) { pr_err("dvb_dmx_init failed %d\n", 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) { pr_err("dvb_dmxdev_init failed %d\n", 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) { pr_err("frontend registration failed %d\n", 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) { pr_err("smscore_register_client() failed %d\n", rc); goto client_error; } client->coredev = coredev; init_completion(&client->tune_done); init_completion(&client->stats_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_board_setup(coredev); if (smsdvb_debugfs_create(client) < 0) pr_info("failed to create debugfs node\n"); rc = dvb_create_media_graph(&client->adapter, true); if (rc < 0) { pr_err("dvb_create_media_graph failed %d\n", rc); goto client_error; } pr_info("DVB interface registered.\n"); 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: smsdvb_media_device_unregister(client); dvb_unregister_adapter(&client->adapter); adapter_error: kfree(client); return rc; }
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; int mode = smscore_get_device_mode(coredev); //mode = 6; /* device removal handled by onremove callback */ if (!arrival) return 0; if ( (mode != DEVICE_MODE_DVBT_BDA) && (mode != DEVICE_MODE_ISDBT_BDA) ) { sms_err("SMS Device mode is not set for " "DVB operation."); return 0; } client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); if (!client) { sms_err("kmalloc() failed"); return -ENOMEM; } /* register dvb adapter */ #ifdef SMS_DVB_OLD_DVB_REGISTER_ADAPTER rc = dvb_register_adapter(&client->adapter, sms_get_board(smscore_get_board_id(coredev))-> name, THIS_MODULE, device); #else rc = dvb_register_adapter(&client->adapter, sms_get_board(smscore_get_board_id(coredev))-> name, THIS_MODULE, device, adapter_nr); #endif 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; } //add by luis printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__); //add by luis /* init and register frontend */ memcpy(&client->frontend.ops, &smsdvb_fe_ops, sizeof(struct dvb_frontend_ops)); //add by luis printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__); //add by luis 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; //add by luis printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__); //add by luis 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); init_completion(&client->get_stats_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); //add by luis printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__); //add by luis sms_info("success"); 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; }