]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/media/dvb/siano/smsdvb.c
V4L/DVB (13841): smsdvb: Make stats to work
[karo-tx-linux.git] / drivers / media / dvb / siano / smsdvb.c
index 68bf9fbd8fed91094cd641c245ebaf2d467761ce..6b85b4872f59c3f3fab9d9990d05ac4f678594f7 100644 (file)
@@ -134,6 +134,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
                break;
 
        case MSG_SMS_RF_TUNE_RES:
+       case MSG_SMS_ISDBT_TUNE_RES:
                complete(&client->tune_done);
                break;
 
@@ -217,6 +218,39 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
                is_status_update = true;
                break;
        }
+       case MSG_SMS_GET_STATISTICS_RES: {
+               struct SMSHOSTLIB_STATISTICS_S *p =
+                       (struct SMSHOSTLIB_STATISTICS_S *)(phdr + 1);
+               struct RECEPTION_STATISTICS_S *pReceptionData =
+                               &client->sms_stat_dvb.ReceptionData;
+
+               sms_info("MSG_SMS_GET_STATISTICS_RES");
+
+               is_status_update = true;
+               pReceptionData->IsDemodLocked = p->IsDemodLocked;
+               if (!pReceptionData->IsDemodLocked) {
+                       pReceptionData->SNR = 0;
+                       pReceptionData->BER = 0;
+                       pReceptionData->BERErrorCount = 0;
+                       pReceptionData->InBandPwr = 0;
+                       pReceptionData->ErrorTSPackets = 0;
+
+                       complete(&client->tune_done);
+                       break;
+               }
+
+               pReceptionData->SNR = p->SNR;
+               pReceptionData->BER = p->BER;
+               pReceptionData->BERErrorCount = p->BERErrorCount;
+               pReceptionData->InBandPwr = p->InBandPwr;
+               pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
+
+               complete(&client->tune_done);
+               break;
+       }
+       default:
+               sms_info("Unhandled message %d", phdr->msgType);
+
        }
        smscore_putbuffer(client->coredev, cb);
 
@@ -325,6 +359,20 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
                                                0 : -ETIME;
 }
 
+static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
+{
+       int rc;
+       struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
+                                   DVBT_BDA_CONTROL_MSG_ID,
+                                   HIF_TASK,
+                                   sizeof(struct SmsMsgHdr_ST), 0 };
+
+       rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                         &client->tune_done);
+
+       return rc;
+}
+
 static inline int led_feedback(struct smsdvb_client_t *client)
 {
        if (client->fe_status & FE_HAS_LOCK)
@@ -337,33 +385,43 @@ static inline int led_feedback(struct smsdvb_client_t *client)
 
 static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
 {
+       int rc;
        struct smsdvb_client_t *client;
        client = container_of(fe, struct smsdvb_client_t, frontend);
 
+       rc = smsdvb_send_statistics_request(client);
+
        *stat = client->fe_status;
 
        led_feedback(client);
 
-       return 0;
+       return rc;
 }
 
 static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
+       int rc;
        struct smsdvb_client_t *client;
        client = container_of(fe, struct smsdvb_client_t, frontend);
 
+       rc = smsdvb_send_statistics_request(client);
+
        *ber = client->sms_stat_dvb.ReceptionData.BER;
 
        led_feedback(client);
 
-       return 0;
+       return rc;
 }
 
 static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 {
+       int rc;
+
        struct smsdvb_client_t *client;
        client = container_of(fe, struct smsdvb_client_t, frontend);
 
+       rc = smsdvb_send_statistics_request(client);
+
        if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
                *strength = 0;
                else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
@@ -375,31 +433,37 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 
        led_feedback(client);
 
-       return 0;
+       return rc;
 }
 
 static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
+       int rc;
        struct smsdvb_client_t *client;
        client = container_of(fe, struct smsdvb_client_t, frontend);
 
+       rc = smsdvb_send_statistics_request(client);
+
        *snr = client->sms_stat_dvb.ReceptionData.SNR;
 
        led_feedback(client);
 
-       return 0;
+       return rc;
 }
 
 static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
+       int rc;
        struct smsdvb_client_t *client;
        client = container_of(fe, struct smsdvb_client_t, frontend);
 
+       rc = smsdvb_send_statistics_request(client);
+
        *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
 
        led_feedback(client);
 
-       return 0;
+       return rc;
 }
 
 static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
@@ -413,8 +477,8 @@ static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
        return 0;
 }
 
-static int smsdvb_set_frontend(struct dvb_frontend *fe,
-                              struct dvb_frontend_parameters *fep)
+static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe,
+                                   struct dvb_frontend_parameters *fep)
 {
        struct smsdvb_client_t *client =
                container_of(fe, struct smsdvb_client_t, frontend);
@@ -470,6 +534,75 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
                                           &client->tune_done);
 }
 
+static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe,
+                                    struct dvb_frontend_parameters *fep,
+                                    u32 SegmentNumber)
+{
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+
+       struct {
+               struct SmsMsgHdr_ST     Msg;
+               u32             Data[4];
+       } Msg;
+
+       Msg.Msg.msgSrcId  = DVBT_BDA_CONTROL_MSG_ID;
+       Msg.Msg.msgDstId  = HIF_TASK;
+       Msg.Msg.msgFlags  = 0;
+       Msg.Msg.msgType   = MSG_SMS_ISDBT_TUNE_REQ;
+       Msg.Msg.msgLength = sizeof(Msg);
+       Msg.Data[0] = fep->frequency;
+       Msg.Data[2] = 12000000;
+       Msg.Data[3] = SegmentNumber;
+
+       sms_debug("freq %d band %d seg %d\n",
+                 fep->frequency, fep->u.ofdm.bandwidth, SegmentNumber);
+
+       switch (fep->u.ofdm.bandwidth) {
+       case BANDWIDTH_8_MHZ:
+               Msg.Data[1] = BW_ISDBT_3SEG;
+               break;
+       case BANDWIDTH_7_MHZ:
+               Msg.Data[1] = BW_ISDBT_3SEG;
+               break;
+       case BANDWIDTH_6_MHZ:
+               Msg.Data[1] = BW_ISDBT_1SEG;
+               break;
+       case BANDWIDTH_AUTO:
+               return -EOPNOTSUPP;
+       default:
+               return -EINVAL;
+       }
+
+       return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                          &client->tune_done);
+}
+
+static int smsdvb_set_frontend(struct dvb_frontend *fe,
+                              struct dvb_frontend_parameters *fep)
+{
+       struct smsdvb_client_t *client =
+               container_of(fe, struct smsdvb_client_t, frontend);
+       struct smscore_device_t *coredev = client->coredev;
+
+       switch (smscore_get_device_mode(coredev)) {
+       case DEVICE_MODE_DVBT:
+       case DEVICE_MODE_DVBT_BDA:
+               return smsdvb_dvbt_set_frontend(fe, fep);
+       case DEVICE_MODE_ISDBT:
+       case DEVICE_MODE_ISDBT_BDA:
+       {
+               u32 segmentnum;
+               /* XXX: hack - use 4 lower bits in frequency for segment num */
+               segmentnum = fep->frequency & 0x0000000f;
+               fep->frequency &= ~0x0000000f;
+               return smsdvb_isdbt_set_frontend(fe, fep, segmentnum);
+       }
+       default:
+               return -EINVAL;
+       }
+}
+
 static int smsdvb_get_frontend(struct dvb_frontend *fe,
                               struct dvb_frontend_parameters *fep)
 {
@@ -557,13 +690,6 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
        /* device removal handled by onremove callback */
        if (!arrival)
                return 0;
-
-       if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_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");