From 6b26fcea513095cd8a86cb376ad5a9df2fa8fe14 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 22 Dec 2009 21:08:49 -0300 Subject: [PATCH] V4L/DVB (13839): smsdvb: add ISDB-T as DVB-T tuning support hack Activate ISDB-T mode using module option default_mode=6. hack: use 4 lower bits in frequency for segment number [mchehab@redhat.com: fix merge conflicts and CodingStyle] Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsdvb.c | 81 ++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 68bf9fbd8fed..ca952eb8d56b 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -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; @@ -413,8 +414,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 +471,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 +627,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");