aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/siano/smsdvb.c
diff options
context:
space:
mode:
authorUri Shkolnik <uris@siano-ms.com>2009-05-12 11:28:46 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 18:14:29 -0400
commit793786d19a35c59a9379cb75da5b5d6bd052820d (patch)
tree0f7384f23a77505630db3ba6a5ea4152ad76af13 /drivers/media/dvb/siano/smsdvb.c
parentba79bb2c381f01224786270d0914d46f31667cf0 (diff)
V4L/DVB (11782): Siano: smsdvb - use 'push' status mechanism
This patch replace the old method of pulling the device status by sending "get_statistics" request, to push mode. This make status update much faster, and reduce various operation time (UHF scan now takes 15s instead of 2m). In order to make the change the following modification have been applied: 1) core header - update statistics headers. 2) dvb adapter - omit the statistics request, add handling of status indications. 3) core 'onresponse' - re-route messages addressed to other adapter to the dvb adapter. Signed-off-by: Uri Shkolnik <uris@siano-ms.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/siano/smsdvb.c')
-rw-r--r--drivers/media/dvb/siano/smsdvb.c266
1 files changed, 154 insertions, 112 deletions
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 8fb283b85b6b..881f5c5778f7 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -40,12 +40,15 @@ struct smsdvb_client_t {
40 struct dvb_frontend frontend; 40 struct dvb_frontend frontend;
41 41
42 fe_status_t fe_status; 42 fe_status_t fe_status;
43 int fe_ber, fe_snr, fe_unc, fe_signal_strength;
44 43
45 struct completion tune_done, stat_done; 44 struct completion tune_done;
46 45
47 /* todo: save freq/band instead whole struct */ 46 /* todo: save freq/band instead whole struct */
48 struct dvb_frontend_parameters fe_params; 47 struct dvb_frontend_parameters fe_params;
48
49 struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb;
50 int event_fe_state;
51 int event_unc_state;
49}; 52};
50 53
51static struct list_head g_smsdvb_clients; 54static struct list_head g_smsdvb_clients;
@@ -55,11 +58,19 @@ static int sms_dbg;
55module_param_named(debug, sms_dbg, int, 0644); 58module_param_named(debug, sms_dbg, int, 0644);
56MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); 59MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
57 60
61/* Events that may come from DVB v3 adapter */
62static void sms_board_dvb3_event(struct smsdvb_client_t *client,
63 enum SMS_DVB3_EVENTS event) {
64}
65
58static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) 66static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
59{ 67{
60 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; 68 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
61 struct SmsMsgHdr_ST *phdr = 69 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
62 (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); 70 + cb->offset);
71 u32 *pMsgData = (u32 *) phdr + 1;
72 /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
73 bool is_status_update = false;
63 74
64 smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr); 75 smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);
65 76
@@ -73,43 +84,110 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
73 complete(&client->tune_done); 84 complete(&client->tune_done);
74 break; 85 break;
75 86
76 case MSG_SMS_GET_STATISTICS_RES: 87 case MSG_SMS_SIGNAL_DETECTED_IND:
77 { 88 sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
78 struct SmsMsgStatisticsInfo_ST *p = 89 client->sms_stat_dvb.TransmissionData.IsDemodLocked = true;
79 (struct SmsMsgStatisticsInfo_ST *)(phdr + 1); 90 is_status_update = true;
80 91 break;
81 if (p->Stat.IsDemodLocked) { 92
82 client->fe_status = FE_HAS_SIGNAL | 93 case MSG_SMS_NO_SIGNAL_IND:
83 FE_HAS_CARRIER | 94 sms_info("MSG_SMS_NO_SIGNAL_IND");
84 FE_HAS_VITERBI | 95 client->sms_stat_dvb.TransmissionData.IsDemodLocked = false;
85 FE_HAS_SYNC | 96 is_status_update = true;
86 FE_HAS_LOCK; 97 break;
87 98
88 client->fe_snr = p->Stat.SNR; 99 case MSG_SMS_TRANSMISSION_IND: {
89 client->fe_ber = p->Stat.BER; 100 sms_info("MSG_SMS_TRANSMISSION_IND");
90 client->fe_unc = p->Stat.BERErrorCount; 101
91 102 pMsgData++;
92 if (p->Stat.InBandPwr < -95) 103 memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
93 client->fe_signal_strength = 0; 104 sizeof(struct TRANSMISSION_STATISTICS_S));
94 else if (p->Stat.InBandPwr > -29) 105
95 client->fe_signal_strength = 100; 106 /* Mo need to correct guard interval
96 else 107 * (as opposed to old statistics message).
97 client->fe_signal_strength = 108 */
98 (p->Stat.InBandPwr + 95) * 3 / 2; 109 CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
110 CORRECT_STAT_TRANSMISSON_MODE(
111 client->sms_stat_dvb.TransmissionData);
112 is_status_update = true;
113 break;
114 }
115 case MSG_SMS_HO_PER_SLICES_IND: {
116 struct RECEPTION_STATISTICS_S *pReceptionData =
117 &client->sms_stat_dvb.ReceptionData;
118 struct SRVM_SIGNAL_STATUS_S SignalStatusData;
119
120 /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
121 pMsgData++;
122 SignalStatusData.result = pMsgData[0];
123 SignalStatusData.snr = pMsgData[1];
124 SignalStatusData.inBandPower = (s32) pMsgData[2];
125 SignalStatusData.tsPackets = pMsgData[3];
126 SignalStatusData.etsPackets = pMsgData[4];
127 SignalStatusData.constellation = pMsgData[5];
128 SignalStatusData.hpCode = pMsgData[6];
129 SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
130 SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
131 SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
132 SignalStatusData.reason = pMsgData[10];
133 SignalStatusData.requestId = pMsgData[11];
134 pReceptionData->IsRfLocked = pMsgData[16];
135 pReceptionData->IsDemodLocked = pMsgData[17];
136 pReceptionData->ModemState = pMsgData[12];
137 pReceptionData->SNR = pMsgData[1];
138 pReceptionData->BER = pMsgData[13];
139 pReceptionData->RSSI = pMsgData[14];
140 CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
141
142 pReceptionData->InBandPwr = (s32) pMsgData[2];
143 pReceptionData->CarrierOffset = (s32) pMsgData[15];
144 pReceptionData->TotalTSPackets = pMsgData[3];
145 pReceptionData->ErrorTSPackets = pMsgData[4];
146
147 /* TS PER */
148 if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
149 > 0) {
150 pReceptionData->TS_PER = (SignalStatusData.etsPackets
151 * 100) / (SignalStatusData.tsPackets
152 + SignalStatusData.etsPackets);
99 } else { 153 } else {
100 client->fe_status = 0; 154 pReceptionData->TS_PER = 0;
101 client->fe_snr =
102 client->fe_ber =
103 client->fe_unc =
104 client->fe_signal_strength = 0;
105 } 155 }
106 156
107 complete(&client->stat_done); 157 pReceptionData->BERBitCount = pMsgData[18];
108 break; 158 pReceptionData->BERErrorCount = pMsgData[19];
109 } }
110 159
160 pReceptionData->MRC_SNR = pMsgData[20];
161 pReceptionData->MRC_InBandPwr = pMsgData[21];
162 pReceptionData->MRC_RSSI = pMsgData[22];
163
164 is_status_update = true;
165 break;
166 }
167 }
111 smscore_putbuffer(client->coredev, cb); 168 smscore_putbuffer(client->coredev, cb);
112 169
170 if (is_status_update) {
171 if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
172 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
173 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
174 sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
175 if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets
176 == 0)
177 sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
178 else
179 sms_board_dvb3_event(client,
180 DVB3_EVENT_UNC_ERR);
181
182 } else {
183 /*client->fe_status =
184 (phdr->msgType == MSG_SMS_NO_SIGNAL_IND) ?
185 0 : FE_HAS_SIGNAL;*/
186 client->fe_status = 0;
187 sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
188 }
189 }
190
113 return 0; 191 return 0;
114} 192}
115 193
@@ -194,83 +272,61 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
194 0 : -ETIME; 272 0 : -ETIME;
195} 273}
196 274
197static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
198{
199 struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
200 DVBT_BDA_CONTROL_MSG_ID,
201 HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 };
202 int ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
203 &client->stat_done);
204 if (ret < 0)
205 return ret;
206
207 if (client->fe_status & FE_HAS_LOCK)
208 sms_board_led_feedback(client->coredev,
209 (client->fe_unc == 0) ?
210 SMS_LED_HI : SMS_LED_LO);
211 else
212 sms_board_led_feedback(client->coredev, SMS_LED_OFF);
213 return ret;
214}
215
216static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) 275static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
217{ 276{
218 struct smsdvb_client_t *client = 277 struct smsdvb_client_t *client;
219 container_of(fe, struct smsdvb_client_t, frontend); 278 client = container_of(fe, struct smsdvb_client_t, frontend);
220 int rc = smsdvb_send_statistics_request(client);
221 279
222 if (!rc) 280 *stat = client->fe_status;
223 *stat = client->fe_status;
224 281
225 return rc; 282 return 0;
226} 283}
227 284
228static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) 285static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
229{ 286{
230 struct smsdvb_client_t *client = 287 struct smsdvb_client_t *client;
231 container_of(fe, struct smsdvb_client_t, frontend); 288 client = container_of(fe, struct smsdvb_client_t, frontend);
232 int rc = smsdvb_send_statistics_request(client);
233 289
234 if (!rc) 290 *ber = client->sms_stat_dvb.ReceptionData.BER;
235 *ber = client->fe_ber;
236 291
237 return rc; 292 return 0;
238} 293}
239 294
240static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 295static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
241{ 296{
242 struct smsdvb_client_t *client = 297 struct smsdvb_client_t *client;
243 container_of(fe, struct smsdvb_client_t, frontend); 298 client = container_of(fe, struct smsdvb_client_t, frontend);
244 int rc = smsdvb_send_statistics_request(client);
245 299
246 if (!rc) 300 if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
247 *strength = client->fe_signal_strength; 301 *strength = 0;
302 else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
303 *strength = 100;
304 else
305 *strength =
306 (client->sms_stat_dvb.ReceptionData.InBandPwr
307 + 95) * 3 / 2;
248 308
249 return rc; 309 return 0;
250} 310}
251 311
252static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) 312static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
253{ 313{
254 struct smsdvb_client_t *client = 314 struct smsdvb_client_t *client;
255 container_of(fe, struct smsdvb_client_t, frontend); 315 client = container_of(fe, struct smsdvb_client_t, frontend);
256 int rc = smsdvb_send_statistics_request(client);
257 316
258 if (!rc) 317 *snr = client->sms_stat_dvb.ReceptionData.SNR;
259 *snr = client->fe_snr;
260 318
261 return rc; 319 return 0;
262} 320}
263 321
264static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 322static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
265{ 323{
266 struct smsdvb_client_t *client = 324 struct smsdvb_client_t *client;
267 container_of(fe, struct smsdvb_client_t, frontend); 325 client = container_of(fe, struct smsdvb_client_t, frontend);
268 int rc = smsdvb_send_statistics_request(client);
269 326
270 if (!rc) 327 *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
271 *ucblocks = client->fe_unc;
272 328
273 return rc; 329 return 0;
274} 330}
275 331
276static int smsdvb_get_tune_settings(struct dvb_frontend *fe, 332static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
@@ -294,12 +350,15 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
294 struct SmsMsgHdr_ST Msg; 350 struct SmsMsgHdr_ST Msg;
295 u32 Data[3]; 351 u32 Data[3];
296 } Msg; 352 } Msg;
297 int ret;
298 353
299 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; 354 client->fe_status = FE_HAS_SIGNAL;
300 Msg.Msg.msgDstId = HIF_TASK; 355 client->event_fe_state = -1;
301 Msg.Msg.msgFlags = 0; 356 client->event_unc_state = -1;
302 Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; 357
358 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
359 Msg.Msg.msgDstId = HIF_TASK;
360 Msg.Msg.msgFlags = 0;
361 Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
303 Msg.Msg.msgLength = sizeof(Msg); 362 Msg.Msg.msgLength = sizeof(Msg);
304 Msg.Data[0] = fep->frequency; 363 Msg.Data[0] = fep->frequency;
305 Msg.Data[2] = 12000000; 364 Msg.Data[2] = 12000000;
@@ -315,24 +374,6 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
315 default: return -EINVAL; 374 default: return -EINVAL;
316 } 375 }
317 376
318 /* Disable LNA, if any. An error is returned if no LNA is present */
319 ret = sms_board_lna_control(client->coredev, 0);
320 if (ret == 0) {
321 fe_status_t status;
322
323 /* tune with LNA off at first */
324 ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
325 &client->tune_done);
326
327 smsdvb_read_status(fe, &status);
328
329 if (status & FE_HAS_LOCK)
330 return ret;
331
332 /* previous tune didnt lock - enable LNA and tune again */
333 sms_board_lna_control(client->coredev, 1);
334 }
335
336 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), 377 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
337 &client->tune_done); 378 &client->tune_done);
338} 379}
@@ -357,8 +398,7 @@ static int smsdvb_init(struct dvb_frontend *fe)
357 struct smsdvb_client_t *client = 398 struct smsdvb_client_t *client =
358 container_of(fe, struct smsdvb_client_t, frontend); 399 container_of(fe, struct smsdvb_client_t, frontend);
359 400
360 sms_board_power(client->coredev, 1); 401 sms_board_dvb3_event(client, DVB3_EVENT_INIT);
361
362 return 0; 402 return 0;
363} 403}
364 404
@@ -367,8 +407,7 @@ static int smsdvb_sleep(struct dvb_frontend *fe)
367 struct smsdvb_client_t *client = 407 struct smsdvb_client_t *client =
368 container_of(fe, struct smsdvb_client_t, frontend); 408 container_of(fe, struct smsdvb_client_t, frontend);
369 409
370 sms_board_led_feedback(client->coredev, SMS_LED_OFF); 410 sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
371 sms_board_power(client->coredev, 0);
372 411
373 return 0; 412 return 0;
374} 413}
@@ -500,8 +539,11 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
500 539
501 kmutex_unlock(&g_smsdvb_clientslock); 540 kmutex_unlock(&g_smsdvb_clientslock);
502 541
503 sms_info("success"); 542 client->event_fe_state = -1;
543 client->event_unc_state = -1;
544 sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
504 545
546 sms_info("success");
505 sms_board_setup(coredev); 547 sms_board_setup(coredev);
506 548
507 return 0; 549 return 0;