# HG changeset patch # User Uri Shkolnik <uris@xxxxxxxxxxxx> # Date 1231847701 -7200 # Node ID a9dd63fe39745548432a32617f059f2ed64b5d48 # Parent ff7a9223aa99c0ab964772643265ec83aec5112c DVB v3 adapter upgrade From: Uri Shkolnik <uris@xxxxxxxxxxxx> A) Add DVB v3 events B) UNC set to reflect the TS Packets errors instead of BER C) Identation Priority: normal Signed-off-by: Uri Shkolnik <uris@xxxxxxxxxxxx> diff -r ff7a9223aa99 -r a9dd63fe3974 linux/drivers/media/dvb/siano/smsdvb.c --- a/linux/drivers/media/dvb/siano/smsdvb.c Tue Jan 13 13:51:21 2009 +0200 +++ b/linux/drivers/media/dvb/siano/smsdvb.c Tue Jan 13 13:55:01 2009 +0200 @@ -1,23 +1,23 @@ -/* - * Driver for the Siano SMS1xxx USB dongle - * - * author: Anatoly Greenblat - * - * 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. - */ +/**************************************************************** + +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/init.h> @@ -30,15 +30,55 @@ static struct list_head g_smsdvb_clients static struct list_head g_smsdvb_clients; static struct mutex g_smsdvb_clientslock; + +/* Events that may come from DVB v3 adapter */ +static void sms_board_dvb3_event(struct smscore_device_t *coredev, + enum SMS_DVB3_EVENTS event) { + 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: + sms_debug("DVB3_EVENT_FE_LOCK"); + sms_board_event(coredev, BOARD_EVENT_FE_LOCK); + break; + case DVB3_EVENT_FE_UNLOCK: + sms_debug("DVB3_EVENT_FE_UNLOCK"); + sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); + break; + case DVB3_EVENT_UNC_OK: + sms_debug("DVB3_EVENT_UNC_OK"); + sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); + break; + case 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 int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { - struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; + struct smsdvb_client_t *client = (struct smsdvb_client_t *)context; struct SmsMsgHdr_ST *phdr = - (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); + (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); switch (phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: - dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), + dvb_dmx_swfilter(&client->demux, (u8 *) (phdr + 1), cb->size - sizeof(struct SmsMsgHdr_ST)); break; @@ -47,39 +87,38 @@ static int smsdvb_onresponse(void *conte break; case MSG_SMS_GET_STATISTICS_RES: - { - struct SmsMsgStatisticsInfo_ST *p = - (struct SmsMsgStatisticsInfo_ST *)(phdr + 1); + { + struct SmsMsgStatisticsInfo_ST *p = + (struct SmsMsgStatisticsInfo_ST *)(phdr + 1); - if (p->Stat.IsDemodLocked) { - client->fe_status = FE_HAS_SIGNAL | - FE_HAS_CARRIER | - FE_HAS_VITERBI | - FE_HAS_SYNC | - FE_HAS_LOCK; + if (p->Stat.IsDemodLocked) { + client->fe_status = FE_HAS_SIGNAL | + FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - client->fe_snr = p->Stat.SNR; - client->fe_ber = p->Stat.BER; - client->fe_unc = p->Stat.BERErrorCount; + client->fe_snr = p->Stat.SNR; + client->fe_ber = p->Stat.BER; + client->fe_unc = p->Stat.ErrorTSPackets; - if (p->Stat.InBandPwr < -95) + if (p->Stat.InBandPwr < -95) + client->fe_signal_strength = 0; + else if (p->Stat.InBandPwr > -29) + client->fe_signal_strength = 100; + else + client->fe_signal_strength = + (p->Stat.InBandPwr + 95) * 3 / 2; + } else { + client->fe_status = 0; + client->fe_snr = + client->fe_ber = + client->fe_unc = client->fe_signal_strength = 0; - else if (p->Stat.InBandPwr > -29) - client->fe_signal_strength = 100; - else - client->fe_signal_strength = - (p->Stat.InBandPwr + 95) * 3 / 2; - } else { - client->fe_status = 0; - client->fe_snr = - client->fe_ber = - client->fe_unc = - client->fe_signal_strength = 0; + } + + complete(&client->stat_done); + break; } - - complete(&client->stat_done); - break; - } } + } smscore_putbuffer(client->coredev, cb); @@ -104,7 +143,7 @@ static void smsdvb_onremove(void *contex { kmutex_lock(&g_smsdvb_clientslock); - smsdvb_unregister_client((struct smsdvb_client_t *) context); + smsdvb_unregister_client((struct smsdvb_client_t *)context); kmutex_unlock(&g_smsdvb_clientslock); } @@ -112,16 +151,15 @@ static int smsdvb_start_feed(struct dvb_ static int smsdvb_start_feed(struct dvb_demux_feed *feed) { struct smsdvb_client_t *client = - container_of(feed->demux, struct smsdvb_client_t, demux); + container_of(feed->demux, struct smsdvb_client_t, demux); struct SmsMsgData_ST PidMsg; - sms_debug("add pid %d(%x)", - feed->pid, feed->pid); + 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.msgType = MSG_SMS_ADD_PID_FILTER_REQ; PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); PidMsg.msgData[0] = feed->pid; @@ -132,16 +170,15 @@ static int smsdvb_stop_feed(struct dvb_d static int smsdvb_stop_feed(struct dvb_demux_feed *feed) { struct smsdvb_client_t *client = - container_of(feed->demux, struct smsdvb_client_t, demux); + container_of(feed->demux, struct smsdvb_client_t, demux); struct SmsMsgData_ST PidMsg; - sms_debug("remove pid %d(%x)", - feed->pid, feed->pid); + 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.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ; PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); PidMsg.msgData[0] = feed->pid; @@ -150,16 +187,15 @@ static int smsdvb_stop_feed(struct dvb_d } static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, - void *buffer, size_t size, - struct completion *completion) + void *buffer, size_t size, + struct completion *completion) { int rc = smsclient_sendrequest(client->smsclient, buffer, size); if (rc < 0) return rc; return wait_for_completion_timeout(completion, - msecs_to_jiffies(2000)) ? - 0 : -ETIME; + msecs_to_jiffies(2000)) ? 0 : -ETIME; } static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) @@ -173,18 +209,22 @@ static int smsdvb_send_statistics_reques return ret; if (client->fe_status & FE_HAS_LOCK) - sms_board_led_feedback(client->coredev, - (client->fe_unc == 0) ? - SMS_LED_HI : SMS_LED_LO); + sms_board_dvb3_event(client->coredev, DVB3_EVENT_FE_LOCK); else - sms_board_led_feedback(client->coredev, SMS_LED_OFF); + sms_board_dvb3_event(client->coredev, DVB3_EVENT_FE_UNLOCK); + + if (client->fe_unc == 0) + sms_board_dvb3_event(client->coredev, DVB3_EVENT_UNC_OK); + else + sms_board_dvb3_event(client->coredev, DVB3_EVENT_UNC_ERR); + return ret; } static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) { struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); + container_of(fe, struct smsdvb_client_t, frontend); int rc = smsdvb_send_statistics_request(client); if (!rc) @@ -196,7 +236,7 @@ static int smsdvb_read_ber(struct dvb_fr static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) { struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); + container_of(fe, struct smsdvb_client_t, frontend); int rc = smsdvb_send_statistics_request(client); if (!rc) @@ -208,7 +248,7 @@ static int smsdvb_read_signal_strength(s static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); + container_of(fe, struct smsdvb_client_t, frontend); int rc = smsdvb_send_statistics_request(client); if (!rc) @@ -220,7 +260,7 @@ static int smsdvb_read_snr(struct dvb_fr static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) { struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); + container_of(fe, struct smsdvb_client_t, frontend); int rc = smsdvb_send_statistics_request(client); if (!rc) @@ -256,33 +296,42 @@ static int smsdvb_set_frontend(struct dv struct dvb_frontend_parameters *fep) { struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); + container_of(fe, struct smsdvb_client_t, frontend); struct { - struct SmsMsgHdr_ST Msg; - u32 Data[3]; + struct SmsMsgHdr_ST Msg; + u32 Data[3]; } Msg; - 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.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] = fep->frequency; Msg.Data[2] = 12000000; - sms_debug("freq %d band %d", - fep->frequency, fep->u.ofdm.bandwidth); + sms_debug("freq %d band %d", fep->frequency, fep->u.ofdm.bandwidth); switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; - case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; - case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; -#if 0 - case BANDWIDTH_5_MHZ: Msg.Data[1] = BW_5_MHZ; break; + case BANDWIDTH_8_MHZ: + Msg.Data[1] = BW_8_MHZ; + break; + case BANDWIDTH_7_MHZ: + Msg.Data[1] = BW_7_MHZ; + break; + case BANDWIDTH_6_MHZ: + Msg.Data[1] = BW_6_MHZ; + break; +#if 0 /* 5 MHz is not supported by frontend.h */ + case BANDWIDTH_5_MHZ: + Msg.Data[1] = BW_5_MHZ; + break; #endif - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: return -EINVAL; + case BANDWIDTH_AUTO: + return -EOPNOTSUPP; + default: + return -EINVAL; } return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), @@ -293,14 +342,12 @@ static int smsdvb_get_frontend(struct dv struct dvb_frontend_parameters *fep) { struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); + container_of(fe, struct smsdvb_client_t, frontend); sms_debug(""); /* todo: */ - memcpy(fep, &client->fe_params, - sizeof(struct dvb_frontend_parameters)); - + memcpy(fep, &client->fe_params, sizeof(struct dvb_frontend_parameters)); return 0; } @@ -309,8 +356,7 @@ static int smsdvb_init(struct dvb_fronte struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); - sms_board_power(client->coredev, 1); - + sms_board_dvb3_event(client->coredev, DVB3_EVENT_INIT); return 0; } @@ -319,8 +365,7 @@ static int smsdvb_sleep(struct dvb_front 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->coredev, DVB3_EVENT_SLEEP); return 0; } @@ -332,20 +377,19 @@ static void smsdvb_release(struct dvb_fr static struct dvb_frontend_ops smsdvb_fe_ops = { .info = { - .name = "Siano Mobile Digital SMS1xxx", - .type = FE_OFDM, - .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, - }, + .name = "Siano Mobile Digital MDTV Receiver", + .type = FE_OFDM, + .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, @@ -358,7 +402,6 @@ static struct dvb_frontend_ops smsdvb_fe .read_signal_strength = smsdvb_read_signal_strength, .read_snr = smsdvb_read_snr, .read_ucblocks = smsdvb_read_ucblocks, - .init = smsdvb_init, .sleep = smsdvb_sleep, }; @@ -374,16 +417,9 @@ static int smsdvb_hotplug(struct smscore if (!arrival) return 0; - if (smscore_get_device_mode(coredev) != 4) { -#if 1 /* new siano drop (1.2.17) does this -- yuck */ - sms_err("SMS Device mode is not set for " - "DVB operation."); + if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) { + sms_err("SMS Device mode is not set for " "DVB operation."); return 0; -#else - rc = smscore_set_device_mode(coredev, 4); - if (rc < 0) - return rc; -#endif } client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); @@ -394,9 +430,8 @@ static int smsdvb_hotplug(struct smscore /* register dvb adapter */ rc = dvb_register_adapter(&client->adapter, - sms_get_board( - smscore_get_board_id(coredev))->name, - THIS_MODULE, device, adapter_nr); + 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; @@ -404,7 +439,7 @@ static int smsdvb_hotplug(struct smscore /* init dvb demux */ client->demux.dmx.capabilities = DMX_TS_FILTERING; - client->demux.filternum = 32; /* todo: nova ??? */ + client->demux.filternum = 32; /* todo: nova ??? */ client->demux.feednum = 32; client->demux.start_feed = smsdvb_start_feed; client->demux.stop_feed = smsdvb_stop_feed; @@ -461,7 +496,7 @@ static int smsdvb_hotplug(struct smscore sms_info("success"); - sms_board_setup(coredev); + sms_board_dvb3_event(coredev, DVB3_EVENT_HOTPLUG); return 0; @@ -503,8 +538,12 @@ void smsdvb_unregister(void) kmutex_lock(&g_smsdvb_clientslock); while (!list_empty(&g_smsdvb_clients)) - smsdvb_unregister_client( - (struct smsdvb_client_t *) g_smsdvb_clients.next); + smsdvb_unregister_client((struct smsdvb_client_t *) + g_smsdvb_clients.next); kmutex_unlock(&g_smsdvb_clientslock); } + +MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); +MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@xxxxxxxxxxxx)"); +MODULE_LICENSE("GPL"); -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html