From ad6467e18c250c56cb0886372929370027ea14f3 Mon Sep 17 00:00:00 2001 From: Deep Thought Date: Wed, 22 Jul 2020 14:28:08 +0200 Subject: [PATCH] Add fft spectrum scan for stid135; adjusted gain range for stv091x --- drivers/media/dvb-core/dvb_frontend.c | 22 +- drivers/media/dvb-frontends/stid135/chip.c | 467 ++++++++++-------- .../media/dvb-frontends/stid135/stid135-fe.c | 243 ++++++--- .../media/dvb-frontends/stid135/stid135-fft.c | 47 +- .../media/dvb-frontends/stid135/stid135-fft.h | 62 +-- drivers/media/dvb-frontends/stv091x_drv.c | 22 +- include/uapi/linux/dvb/frontend.h | 24 +- 7 files changed, 544 insertions(+), 343 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index be8cbf5e1288b..226196780e80b 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -138,7 +138,7 @@ static void dvb_frontend_invoke_release(struct dvb_frontend *fe, static void release_dtv_fe_spectrum_scan(struct dtv_fe_spectrum* s) { if(s->freq || s->rf_level) - dprintk("releasing memory\n"); + dprintk("releasing memory\n"); if (s->freq) { kfree(s->freq); } @@ -1431,7 +1431,7 @@ static int dvb_frontend_handle_algo_ctrl_ioctl(struct file *file, unsigned int cmd, void *parg); static int dtv_set_sat_scan(struct dvb_frontend *fe, bool scan_continue); -static int dtv_set_spectrum(struct dvb_frontend *fe, int type); +static int dtv_set_spectrum(struct dvb_frontend *fe, enum dtv_fe_spectrum_method method); static int dtv_get_spectrum(struct dvb_frontend *fe, struct dtv_fe_spectrum*user); static int dtv_property_process_get(struct dvb_frontend *fe, @@ -2237,12 +2237,24 @@ static int dtv_property_process_set(struct dvb_frontend *fe, } -static int init_dtv_fe_spectrum_scan(struct dtv_fe_spectrum* s, struct dtv_frontend_properties *p) +static int init_dtv_fe_spectrum_scan(struct dtv_fe_spectrum* s, struct dtv_frontend_properties *p, + enum dtv_fe_spectrum_method method) { u32 start_frequency = p->scan_start_frequency; u32 end_frequency = p->scan_end_frequency; u32 frequency_step = p->scan_resolution; u32 bandwidth = end_frequency-start_frequency; //in kHz + + switch(method) { + case SPECTRUM_METHOD_SWEEP: + case SPECTRUM_METHOD_FFT: + s->spectrum_method = method; + break; + default: + return -EINVAL; + break; + } + s->num_freq = bandwidth/(frequency_step>0 ?frequency_step: 1); if(s->num_freq >= 65536*2) s->num_freq = 65536; @@ -2711,13 +2723,13 @@ static int dtv_set_sat_scan(struct dvb_frontend *fe, bool scan_continue) } -static int dtv_set_spectrum(struct dvb_frontend *fe, int type) +static int dtv_set_spectrum(struct dvb_frontend *fe, enum dtv_fe_spectrum_method method) { struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; if (!fe->ops.get_spectrum) return -ENOTSUPP; - int ret = init_dtv_fe_spectrum_scan(&fepriv->spectrum, c); + int ret = init_dtv_fe_spectrum_scan(&fepriv->spectrum, c, method); if(ret<0) return ret; /* Request the search algorithm to search */ diff --git a/drivers/media/dvb-frontends/stid135/chip.c b/drivers/media/dvb-frontends/stid135/chip.c index 50daaf7ed3309..95747797d3e6b 100644 --- a/drivers/media/dvb-frontends/stid135/chip.c +++ b/drivers/media/dvb-frontends/stid135/chip.c @@ -1,42 +1,45 @@ -/* -* This file is part of STiD135 OXFORD LLA -* -* Copyright (c) <2014>-<2018>, STMicroelectronics - All Rights Reserved -* Author(s): Mathias Hilaire (mathias.hilaire@st.com), Thierry Delahaye (thierry.delahaye@st.com) for STMicroelectronics. -* -* License terms: BSD 3-clause "New" or "Revised" License. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this -* list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* +/* +* This file is part of STiD135 OXFORD LLA +* +* Copyright (c) <2014>-<2018>, STMicroelectronics - All Rights Reserved +* Author(s): Mathias Hilaire (mathias.hilaire@st.com), Thierry Delahaye (thierry.delahaye@st.com) for STMicroelectronics. +* +* License terms: BSD 3-clause "New" or "Revised" License. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* */ #include "i2c.h" #include "chip.h" -/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +#define dprintk(fmt, arg...) \ + printk(KERN_DEBUG pr_fmt("%s:%d " fmt), __func__, __LINE__, ##arg) typedef enum { @@ -47,13 +50,13 @@ typedef enum }PMAP_STATE; -typedef struct node +typedef struct node { STCHIP_Handle_t hChip; struct node *pNextNode; }NODE; -/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ static NODE *pFirstNode = NULL; static BOOL Hierarchy_Flag = FALSE; // 4 compatibility to flat regmaps @@ -62,20 +65,20 @@ static u8 ChipMapRegisterSize = STCHIP_REGSIZE_8; // regsize defaults for a ma /* List routines */ //static u32 revInt (u32 s); -/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ /* big endianess converter */ -/*static u32 revInt (u32 s) -{ +/*static u32 revInt (u32 s) +{ u32 i; char *p = (char *)&i; char *c = (char *)&s; - p[0] = c[3]; p[1] = c[2]; p[2] = c[1]; p[3] = c[0]; + p[0] = c[3]; p[1] = c[2]; p[2] = c[1]; p[3] = c[0]; return i; }*/ static NODE *AppendNode(STCHIP_Handle_t hChip) { NODE *pNode = pFirstNode; - + if(pNode == NULL) { /* Allocation of the first node */ pNode = calloc(1,sizeof(NODE)); @@ -85,32 +88,32 @@ static NODE *AppendNode(STCHIP_Handle_t hChip) { /* Allocation of a new node */ while(pNode->pNextNode != NULL) /* Search of the last node */ pNode = pNode->pNextNode; - + pNode->pNextNode = calloc(1,sizeof(NODE)); /* Memory allocation */ - + if(pNode->pNextNode != NULL) /* Check allocation */ pNode = pNode->pNextNode; else pNode = NULL; } - + if(pNode != NULL) /* if allocation ok */ { /* Fill the node */ pNode->hChip = hChip; - pNode->pNextNode = NULL; + pNode->pNextNode = NULL; } - + return pNode; } static void DeleteNode(NODE *pNode) { NODE *pPrevNode = pFirstNode; - + if(pNode != NULL) { - if(pNode == pFirstNode) + if(pNode == pFirstNode) { /* Delete the first node */ pFirstNode = pNode->pNextNode; @@ -120,13 +123,13 @@ static void DeleteNode(NODE *pNode) /* Delete a non-first node */ while(pPrevNode->pNextNode != pNode) /* search the node before the node to delete */ pPrevNode = pPrevNode->pNextNode; - + if(pNode->pNextNode == NULL) pPrevNode->pNextNode = NULL; /* the node to delete is the last */ - else + else pPrevNode->pNextNode = pPrevNode->pNextNode->pNextNode; /* the node to delete is not the last */ } - + free(pNode); /* memory deallocation */ } } @@ -142,14 +145,14 @@ static void DeleteNode(NODE *pNode) STCHIP_Handle_t ChipGetFirst(void) { if((pFirstNode != NULL) && (pFirstNode->hChip != NULL)) - return pFirstNode->hChip; + return pFirstNode->hChip; else return NULL; } /***************************************************** **FUNCTION :: ChipFindNode -**ACTION :: Find that node that contains the chip +**ACTION :: Find that node that contains the chip **PARAMS IN :: NONE **PARAMS OUT:: NONE **RETURN :: STCHIP_Handle_t if ok, NULL otherwise @@ -157,17 +160,17 @@ STCHIP_Handle_t ChipGetFirst(void) NODE *ChipFindNode(STCHIP_Handle_t hChip) { NODE *pNode = pFirstNode; - + if(pNode != NULL) { while((pNode->hChip != hChip) && (pNode->pNextNode != NULL)) pNode = pNode->pNextNode; - + if(pNode->hChip != hChip) - pNode = NULL; - + pNode = NULL; + } - + return pNode; } @@ -181,12 +184,12 @@ NODE *ChipFindNode(STCHIP_Handle_t hChip) STCHIP_Handle_t ChipGetNext(STCHIP_Handle_t hPrevChip) { NODE *pNode; - + pNode = ChipFindNode(hPrevChip); if((pNode != NULL) && (pNode->pNextNode != NULL)) return pNode->pNextNode->hChip; else - return NULL; + return NULL; } /***************************************************** @@ -199,13 +202,13 @@ STCHIP_Handle_t ChipGetNext(STCHIP_Handle_t hPrevChip) STCHIP_Handle_t ChipGetHandleFromName(char *Name) { STCHIP_Handle_t hChip; - + hChip = ChipGetFirst(); while((hChip != NULL) && (strcmp(hChip->Name,Name) != 0)) { hChip = ChipGetNext(hChip); } - + return hChip; } @@ -224,12 +227,12 @@ STCHIP_Handle_t ChipOpen(STCHIP_Info_t *hChipOpenParams) STCHIP_Handle_t hChip; s32 reg/*, field*/; u32 field; - + hChip = calloc(1,sizeof(STCHIP_Info_t)); /* Allocation of the chip structure */ - + if((hChip != NULL) && (hChipOpenParams != NULL)) - { - if (Hierarchy_Flag) + { + if (Hierarchy_Flag) hChip->pInstMap = calloc(hChipOpenParams->NbInsts,sizeof(STCHIP_Instance_t)); /* Allocation of the instances map */ else { @@ -238,15 +241,15 @@ STCHIP_Handle_t ChipOpen(STCHIP_Info_t *hChipOpenParams) } hChip->pRegMapImage = calloc((u32)hChipOpenParams->NbRegs, sizeof(STCHIP_Register_t)); /* Allocation of the register map */ - + if(hChip->pRegMapImage != NULL) { //hChip->pFieldMap = calloc(hChipOpenParams->NbFields,sizeof(STCHIP_Field_t)); /* Allocation of the field map */ hChip->pFieldMapImage = calloc(hChipOpenParams->NbFields,sizeof(STCHIP_Field_t)); /* Allocation of the field map */ - + if(hChip->pFieldMapImage != NULL) { - if(AppendNode(hChip)!=NULL) + if(AppendNode(hChip)!=NULL) { hChip->pI2CHost = hChipOpenParams->pI2CHost; hChip->I2cAddr = hChipOpenParams->I2cAddr; @@ -259,21 +262,21 @@ STCHIP_Handle_t ChipOpen(STCHIP_Info_t *hChipOpenParams) hChip->RepeaterHost = hChipOpenParams->RepeaterHost; hChip->RepeaterFn = hChipOpenParams->RepeaterFn; hChip->WrStart = hChipOpenParams->WrStart; - hChip->WrSize = hChipOpenParams->WrSize; - hChip->RdStart = hChipOpenParams->RdStart; - hChip->RdSize = hChipOpenParams->RdSize; + hChip->WrSize = hChipOpenParams->WrSize; + hChip->RdStart = hChipOpenParams->RdStart; + hChip->RdSize = hChipOpenParams->RdSize; hChip->Error = CHIPERR_NO_ERROR; hChip->pData = hChipOpenParams->pData; hChip->LastRegIndex = 0; - hChip->Abort = FALSE; - + hChip->Abort = FALSE; + for(reg=0;regNbRegs;reg++) { hChip->pRegMapImage[reg].Addr=0; hChip->pRegMapImage[reg].Value=0; //hChip->pRegMapImage[reg].Base=0; } - + for(field=0;fieldNbFields;field++) { hChip->pFieldMapImage[field].Reg=0; @@ -286,9 +289,9 @@ STCHIP_Handle_t ChipOpen(STCHIP_Info_t *hChipOpenParams) { //free(hChip->pFieldMap); //free(hChip->pRegMap); - free(hChip->pInstMap); + free(hChip->pInstMap); free(hChip); - hChip = NULL; + hChip = NULL; } } else @@ -301,10 +304,10 @@ STCHIP_Handle_t ChipOpen(STCHIP_Info_t *hChipOpenParams) else { free(hChip); - hChip = NULL; + hChip = NULL; } } - + return hChip; } @@ -319,7 +322,7 @@ STCHIP_Error_t ChipClose(STCHIP_Handle_t hChip) { STCHIP_Error_t error = CHIPERR_NO_ERROR; NODE *node = NULL; - + if(hChip != NULL) { node = ChipFindNode(hChip); @@ -330,13 +333,13 @@ STCHIP_Error_t ChipClose(STCHIP_Handle_t hChip) } else error = CHIPERR_INVALID_HANDLE; - - return error; + + return error; } /***************************************************** **FUNCTION :: CreateMask -**ACTION :: Create a mask according to its number of bits and position +**ACTION :: Create a mask according to its number of bits and position **PARAMS IN :: field ==> Id of the field **PARAMS OUT:: NONE **RETURN :: mask of the field @@ -345,28 +348,28 @@ u32 CreateMask(char NbBits, char Pos) { s32 i; u32 mask=0; - - + + /* Create mask */ for (i = 0; i < NbBits; i++) { mask <<= 1 ; mask += 1 ; } - + mask = mask << Pos; - + return mask; } /***************************************************** **FUNCTION :: ChipAddField -**ACTION :: Add a field to the field map +**ACTION :: Add a field to the field map **PARAMS IN :: hChip ==> Handle to the chip ** RegId ==> Id of the register which contains the field ** FieldId ==> Id of the field ** Name ==> Name of the field -** Pos ==> Position (number of left shifts from LSB position) in the register +** Pos ==> Position (number of left shifts from LSB position) in the register ** NbBits ==> Size (in bits) of the field ** Type ==> SIGNED or UNSIGNED **PARAMS OUT:: NONE @@ -374,8 +377,8 @@ u32 CreateMask(char NbBits, char Pos) *****************************************************/ STCHIP_Error_t ChipAddField(STCHIP_Handle_t hChip,u16 RegId, u32 FieldId,char * Name, char Pos, char NbBits, STCHIP_FieldType_t Type) { - STCHIP_Field_t *pField; - + STCHIP_Field_t *pField; + if(hChip != NULL) { if(RegId < hChip->NbRegs) @@ -384,8 +387,8 @@ STCHIP_Error_t ChipAddField(STCHIP_Handle_t hChip,u16 RegId, u32 FieldId,char * { //pField=&hChip->pFieldMap[FieldId]; pField=&hChip->pFieldMapImage[FieldId]; - - strcpy(pField->Name,Name); + + strcpy(pField->Name,Name); pField->Reg = RegId; pField->Pos = (u8)Pos; pField->Bits = (u8)NbBits; @@ -401,9 +404,9 @@ STCHIP_Error_t ChipAddField(STCHIP_Handle_t hChip,u16 RegId, u32 FieldId,char * else hChip->Error = CHIPERR_INVALID_REG_ID; } - else + else return CHIPERR_INVALID_HANDLE; - + return hChip->Error; } @@ -415,39 +418,73 @@ int dichotomy_search(STCHIP_Register_t tab[], s32 nbVal, u16 val) u32 start_index; // start index u32 end_index; // end index u32 middle_index; // middle index - + /* Initialisation of these variables before search loop */ found = FALSE; // value is not yet found start_index = 0; // search range between 0 and ... end_index = (u32)nbVal; //... nbVal - + /* search loop */ while(!found && ((end_index - start_index) > 1)) { - + middle_index = (start_index + end_index)/2; // we set middle index found = (tab[middle_index].Addr == val); // we check if searched value is located at this index - + if(tab[middle_index].Addr > val) end_index = middle_index; // if value which located at im index is greater to searched value, end index becomes "ifin" middle index, therefore search range is narrower for the next loop else start_index = middle_index; // otherwise start index becomes middle index and search range is also narrower } - + /* test conditionnant la valeur que la fonction va renvoyer */ if(tab[start_index].Addr == val) return((s32)start_index); // if we have found the good value, we return index else return(-1); // other wise we return -1 } + +void dump(STCHIP_Handle_t hChip) { + int i; + STCHIP_Register_t *tab=hChip->pRegMapImage; + for(i=0; iNbRegs; ++i) { + printk("[%d]=%d\n", i, tab[i].Addr); + } +} + + +int direct_search(STCHIP_Register_t tab[], s32 nbVal, u16 val) +{ + /* Declaration of local variables */ + BOOL found; // equals false while "val" is not yet found + u32 start_index; // start index + u32 end_index; // end index + u32 middle_index; // middle index + int i; + /* Initialisation of these variables before search loop */ + found = FALSE; // value is not yet found + start_index = 0; // search range between 0 and ... + end_index = (u32)nbVal; //... nbVal + + /* search loop */ + for(i=start_index; i Handle to the chip ** RegId ==> Id of the register (adress) -**PARAMS OUT:: None +**PARAMS OUT:: None **RETURN :: Index of the register in the register map image *****************************************************/ s32 ChipGetRegisterIndex(STCHIP_Handle_t hChip, u16 RegId) { s32 regIndex=-1; - + if(hChip) { if(hChip->Abort==FALSE) @@ -458,6 +495,12 @@ s32 ChipGetRegisterIndex(STCHIP_Handle_t hChip, u16 RegId) { /* We assume that reg addresses in STiD135DefVal and STiD135SocDefVal are sorted in the growing order */ regIndex = dichotomy_search(hChip->pRegMapImage, hChip->NbRegs, RegId); + if(regIndex<0) { + printk("register not found: %d\n", RegId); + regIndex = direct_search(hChip->pRegMapImage, hChip->NbRegs, RegId); + if(regIndex>=0) + printk("register found second time: %d\n", RegId); + } hChip->LastRegIndex = regIndex; } } @@ -479,38 +522,47 @@ s32 ChipGetFieldIndex(STCHIP_Handle_t hChip, u32 FieldId) { s32 regIndex=-1; u16 regAddress; - + if(hChip) { - if(hChip->Abort==FALSE) + if(hChip->Abort==FALSE) { regAddress=(u16)((FieldId >> 16)&0xFFFF); + if(regAddress==0) + dprintk("BAD CALL: probably FieldId was cast to less than 32 bit\n"); if(hChip->pRegMapImage[hChip->LastRegIndex].Addr ==regAddress) regIndex = hChip->LastRegIndex; else { /* We assume that reg addresses in STiD135DefVal and STiD135SocDefVal are sorted in the growing order */ regIndex = dichotomy_search(hChip->pRegMapImage, hChip->NbRegs, regAddress); + if(regIndex<0) { + printk("field not found: %d\n", regAddress); + regIndex = direct_search(hChip->pRegMapImage, hChip->NbRegs, regAddress); + if(regIndex>=0) + printk("field found second time: %d\n", regAddress); + } + hChip->LastRegIndex = regIndex; } } else regIndex=0; } - + return regIndex; } /***************************************************** **FUNCTION :: ChipSetOneRegister -**ACTION :: Set the value of one register +**ACTION :: Set the value of one register **PARAMS IN :: hChip ==> Handle to the chip ** reg_id ==> Id of the register ** Data ==> Data to store in the register **PARAMS OUT:: NONE **RETURN :: Error *****************************************************/ -STCHIP_Error_t ChipSetOneRegister(STCHIP_Handle_t hChip,u16 RegAddr,u32 Data) +STCHIP_Error_t ChipSetOneRegister(STCHIP_Handle_t hChip,u16 RegAddr,u32 Data) { s32 regIndex; @@ -526,22 +578,22 @@ STCHIP_Error_t ChipSetOneRegister(STCHIP_Handle_t hChip,u16 RegAddr,u32 Data) } } else return CHIPERR_INVALID_HANDLE; - + return hChip->Error; } /***************************************************** **FUNCTION :: ChipGetOneRegister -**ACTION :: Get the value of one register +**ACTION :: Get the value of one register **PARAMS IN :: hChip ==> Handle to the chip ** reg_id ==> Id of the register **PARAMS OUT :: Register's value -**RETURN :: fe_lla_error_t +**RETURN :: fe_lla_error_t *****************************************************/ STCHIP_Error_t ChipGetOneRegister(STCHIP_Handle_t hChip, u16 RegAddr, u32* data_p ) { - s32 regIndex; - + s32 regIndex; + *data_p = 0xFFFFFFFF; hChip->Error = CHIPERR_NO_ERROR; if(hChip) @@ -549,7 +601,7 @@ STCHIP_Error_t ChipGetOneRegister(STCHIP_Handle_t hChip, u16 RegAddr, u32* data_ if(hChip->Abort==FALSE) { regIndex =ChipGetRegisterIndex(hChip, RegAddr); - + if((regIndex >= 0) && (regIndex < hChip->NbRegs)) { if(hChip->ChipMode != STCHIP_MODE_NOSUBADR) @@ -559,7 +611,7 @@ STCHIP_Error_t ChipGetOneRegister(STCHIP_Handle_t hChip, u16 RegAddr, u32* data_ } else { - if(ChipGetRegisters(hChip,hChip->RdStart,(s32)hChip->RdSize) == CHIPERR_NO_ERROR) + if(ChipGetRegisters(hChip,hChip->RdStart,(s32)hChip->RdSize) == CHIPERR_NO_ERROR) *data_p = (u32)hChip->pRegMapImage[regIndex].Value; } } @@ -569,7 +621,7 @@ STCHIP_Error_t ChipGetOneRegister(STCHIP_Handle_t hChip, u16 RegAddr, u32* data_ } else hChip->Error = CHIPERR_INVALID_HANDLE; - + return hChip->Error; } @@ -579,7 +631,7 @@ STCHIP_Error_t ChipGetOneRegister(STCHIP_Handle_t hChip, u16 RegAddr, u32* data_ **ACTION :: Set values of consecutive's registers (values are taken in RegMap) **PARAMS IN :: hChip ==> Handle to the chip ** FirstReg ==> Id of the first register -** NbRegs ==> Number of register to write +** NbRegs ==> Number of register to write **PARAMS OUT:: NONE **RETURN :: Error *****************************************************/ @@ -594,27 +646,27 @@ STCHIP_Error_t ChipSetRegisters(STCHIP_Handle_t hChip, u16 FirstReg, s32 NbRegs if(!hChip->Error) { firstRegIndex =ChipGetRegisterIndex(hChip, FirstReg); - if((firstRegIndex >= 0) && ((firstRegIndex + NbRegs - 1) < hChip->NbRegs)) + if((firstRegIndex >= 0) && ((firstRegIndex + NbRegs - 1) < hChip->NbRegs)) { switch(hChip->ChipMode) { case STCHIP_MODE_I2C2STBUS: /* fixed 2 addr + 1 data transaction mode 4 I2C to STBus bridge */ // 16 Bit special register bug workaround RnDHV00063986 & RnDHV00062932 & BZ#69936 if (NbRegs > 1) - data[nbdata] = (U8)(hChip->WrStart + STBUS_STREAM_INCR_1); + data[nbdata] = (U8)(hChip->WrStart + STBUS_STREAM_INCR_1); else data[nbdata] = (U8)(hChip->WrStart); nbdata = (u8)(nbdata + 1); - + //data[nbdata++]=MSB(hChip->pRegMapImage[FirstReg].Addr); /* Hi sub address */ //data[nbdata++]=LSB(hChip->pRegMapImage[FirstReg].Addr); /* Lo sub address */ data[nbdata++]=(u8)(MSB(hChip->pRegMapImage[firstRegIndex].Addr)); /* Hi sub address */ - data[nbdata++]=(u8)(LSB(hChip->pRegMapImage[firstRegIndex].Addr)); /* Lo sub address */ - + data[nbdata++]=(u8)(LSB(hChip->pRegMapImage[firstRegIndex].Addr)); /* Lo sub address */ + for(i=0;ipRegMapImage[firstRegIndex+i].Size - 1); j>=0;j--) /* byte's loop */ data[nbdata++]=0xff&(hChip->pRegMapImage[firstRegIndex+i].Value>>(8*j)); /* fill data buffer (MSB first) */ - + break; case STCHIP_MODE_SUBADR_16: @@ -628,7 +680,7 @@ STCHIP_Error_t ChipSetRegisters(STCHIP_Handle_t hChip, u16 FirstReg, s32 NbRegs for(j=0;j<(s32)(hChip->pRegMapImage[firstRegIndex+i].Size);j++) /* byte's loop */ data[nbdata++]=0xff&(hChip->pRegMapImage[firstRegIndex+i].Value>>(8*j)); /* fill data buffer (LSB first) */ break; - } + } #ifndef NO_I2C if(hChip->Repeater && hChip->RepeaterHost && hChip->RepeaterFn) hChip->RepeaterFn(hChip->RepeaterHost,TRUE); /* Set repeater ON */ @@ -638,7 +690,7 @@ STCHIP_Error_t ChipSetRegisters(STCHIP_Handle_t hChip, u16 FirstReg, s32 NbRegs if(hChip->Repeater && hChip->RepeaterHost && hChip->RepeaterFn) hChip->RepeaterFn(hChip->RepeaterHost,FALSE); /* Set repeater OFF */ - + #endif } else @@ -646,13 +698,13 @@ STCHIP_Error_t ChipSetRegisters(STCHIP_Handle_t hChip, u16 FirstReg, s32 NbRegs } else return hChip->Error; - + } else return CHIPERR_INVALID_HANDLE; - + return hChip->Error; - + } /***************************************************** @@ -660,7 +712,7 @@ STCHIP_Error_t ChipSetRegisters(STCHIP_Handle_t hChip, u16 FirstReg, s32 NbRegs **ACTION :: Get values of consecutive's registers (values are writen in RegMap) **PARAMS IN :: hChip ==> Handle to the chip ** FirstReg ==> Id of the first register -** NbRegs ==> Number of register to read +** NbRegs ==> Number of register to read **PARAMS OUT:: NONE **RETURN :: Error *****************************************************/ @@ -685,52 +737,52 @@ STCHIP_Error_t ChipGetRegisters(STCHIP_Handle_t hChip, u16 FirstReg, s32 NbRegs) #ifndef NO_I2C switch(hChip->ChipMode) { - case STCHIP_MODE_I2C2STBUS: /* fixed 2 addr + 1 data transaction - + case STCHIP_MODE_I2C2STBUS: /* fixed 2 addr + 1 data transaction - mode for I2C to STBus bridge */ // 16 Bit special register bug workaround RnDHV00063986 & RnDHV00062932 & BZ#69936 if (NbRegs > 1) data[nbdata] = (U8)(hChip->WrStart + STBUS_READ + STBUS_STREAM_INCR_1); else data[nbdata] = (U8)(hChip->WrStart + STBUS_READ); nbdata = (u8)(nbdata + 1); - + case STCHIP_MODE_SUBADR_16: data[nbdata++]=(u8)(MSB(hChip->pRegMapImage[firstRegIndex].Addr)); /* for 16 bits sub addresses */ case STCHIP_MODE_SUBADR_8: data[nbdata++]=(u8)(LSB(hChip->pRegMapImage[firstRegIndex].Addr)); /* for 8 bits sub addresses */ - + if(hChip->Repeater && hChip->RepeaterHost && hChip->RepeaterFn) hChip->RepeaterFn(hChip->RepeaterHost,TRUE); /* Set repeater ON */ - + if(I2cReadWrite(hChip->pI2CHost,I2C_WRITE,hChip->I2cAddr,data,nbdata) != I2C_ERR_NONE) /* Write sub address */ hChip->Error = CHIPERR_I2C_NO_ACK; - - + + if(hChip->Repeater && hChip->RepeaterHost && hChip->RepeaterFn) hChip->RepeaterFn(hChip->RepeaterHost,FALSE); /* Set repeater OFF */ - + case STCHIP_MODE_NOSUBADR: case STCHIP_MODE_NOSUBADR_RD: /* FIXME: new for 32-bit access */ nbdata=0; for(i=0;ipRegMapImage[firstRegIndex+i].Size)); /* sum register's size */ - + if(hChip->Repeater && hChip->RepeaterHost && hChip->RepeaterFn) hChip->RepeaterFn(hChip->RepeaterHost,TRUE); /* Set repeater ON */ - - if(I2cReadWrite(hChip->pI2CHost,I2C_READ,hChip->I2cAddr,data,nbdata) != I2C_ERR_NONE) /* Read data buffer */ + + if(I2cReadWrite(hChip->pI2CHost,I2C_READ,hChip->I2cAddr,data,nbdata) != I2C_ERR_NONE) /* Read data buffer */ hChip->Error = CHIPERR_I2C_NO_ACK; - + if(hChip->Repeater && hChip->RepeaterHost && hChip->RepeaterFn) hChip->RepeaterFn(hChip->RepeaterHost,FALSE); /* Set repeater OFF */ - - /* FIXME: new for 32-bit access */ + + /* FIXME: new for 32-bit access */ // TAB data consistency if (keep_lsb) data[0] = lsb; break; } - + /* Update RegMap structure */ /*for(i=0;iError) @@ -744,7 +796,7 @@ STCHIP_Error_t ChipGetRegisters(STCHIP_Handle_t hChip, u16 FirstReg, s32 NbRegs) for(i=0;ipRegMapImage[firstRegIndex+i].Value=0x00000000; /* reset register's value */ - + for(j=0;j<(s32)(hChip->pRegMapImage[firstRegIndex+i].Size);j++) /* byte's loop */ if (hChip->ChipMode == STCHIP_MODE_I2C2STBUS) /* gb hware can also be little endian */ hChip->pRegMapImage[firstRegIndex+i].Value = (hChip->pRegMapImage[firstRegIndex+i].Value << 8) + (data[i+j]); /* fill register value, big endian, new */ @@ -754,16 +806,16 @@ STCHIP_Error_t ChipGetRegisters(STCHIP_Handle_t hChip, u16 FirstReg, s32 NbRegs) } else hChip->Error = CHIPERR_INVALID_REG_ID; - + } - else + else hChip->Error = CHIPERR_I2C_BURST; } } } else return CHIPERR_INVALID_HANDLE; - + return hChip->Error; } @@ -771,7 +823,7 @@ STCHIP_Error_t ChipGetRegisters(STCHIP_Handle_t hChip, u16 FirstReg, s32 NbRegs) **FUNCTION :: ChipUpdateDefaultValues **ACTION :: update the default values of the RegMap chip **PARAMS IN :: hChip ==> handle to the chip - :: pRegMap ==> pointer to + :: pRegMap ==> pointer to **PARAMS OUT:: NONE **RETURN :: CHIPERR_NO_ERROR if ok, CHIPERR_INVALID_HANDLE otherwise *****************************************************/ @@ -779,7 +831,7 @@ STCHIP_Error_t ChipUpdateDefaultValues(STCHIP_Handle_t hChip,STCHIP_Register_t { STCHIP_Error_t error = CHIPERR_NO_ERROR; s32 reg; - + if(hChip != NULL) { for(reg=0;regNbRegs;reg++) @@ -790,33 +842,33 @@ STCHIP_Error_t ChipUpdateDefaultValues(STCHIP_Handle_t hChip,STCHIP_Register_t } else error = CHIPERR_INVALID_HANDLE; - + return error; } /***************************************************** **FUNCTION :: ChipApplyDefaultValues **ACTION :: Write default values in all the registers -**PARAMS IN :: hChip ==> Handle of the chip +**PARAMS IN :: hChip ==> Handle of the chip **PARAMS OUT:: NONE **RETURN :: Error *****************************************************/ STCHIP_Error_t ChipApplyDefaultValues(STCHIP_Handle_t hChip, u16 RegAddr, u8 RegsVal) { - if(hChip != NULL) + if(hChip != NULL) { - if(hChip->ChipMode != STCHIP_MODE_NOSUBADR) + if(hChip->ChipMode != STCHIP_MODE_NOSUBADR) { if((!hChip->Error)) { - ChipSetOneRegister(hChip,RegAddr,RegsVal); + ChipSetOneRegister(hChip,RegAddr,RegsVal); } } - + } else return CHIPERR_INVALID_HANDLE; - + return hChip->Error; } @@ -830,7 +882,7 @@ STCHIP_Error_t ChipApplyDefaultValues(STCHIP_Handle_t hChip, u16 RegAddr, u8 Reg *****************************************************/ STCHIP_Error_t ChipGetError(STCHIP_Handle_t hChip) { - if(hChip != NULL) + if(hChip != NULL) return hChip->Error; else return CHIPERR_INVALID_HANDLE; @@ -843,50 +895,50 @@ STCHIP_Error_t ChipGetError(STCHIP_Handle_t hChip) **PARAMS OUT:: NONE **RETURN :: Error *****************************************************/ -STCHIP_Error_t ChipResetError(STCHIP_Handle_t hChip) +STCHIP_Error_t ChipResetError(STCHIP_Handle_t hChip) { - if(hChip != NULL) + if(hChip != NULL) hChip->Error = CHIPERR_NO_ERROR; else return CHIPERR_INVALID_HANDLE; - + return hChip->Error; } /***************************************************** **FUNCTION :: ChipGetFieldMask **ACTION :: get the mask of a field in the chip -**PARAMS IN :: +**PARAMS IN :: **PARAMS OUT:: mask **RETURN :: mask *****************************************************/ s32 ChipGetFieldMask(u32 FieldId) { s32 mask; - mask = FieldId & 0xFF; /*FieldId is [reg address][reg address][sign][mask] --- 4 bytes */ - + mask = FieldId & 0xFF; /*FieldId is [reg address][reg address][sign][mask] --- 4 bytes */ + return mask; } /***************************************************** **FUNCTION :: ChipGetFieldSign **ACTION :: get the sign of a field in the chip -**PARAMS IN :: +**PARAMS IN :: **PARAMS OUT:: sign **RETURN :: sign *****************************************************/ s32 ChipGetFieldSign(u32 FieldId) { s32 sign; - sign = (FieldId>>8) & 0x01; /*FieldId is [reg address][reg address][sign][mask] --- 4 bytes */ - + sign = (FieldId>>8) & 0x01; /*FieldId is [reg address][reg address][sign][mask] --- 4 bytes */ + return sign; } /***************************************************** **FUNCTION :: ChipGetFieldPosition **ACTION :: get the position of a field in the chip -**PARAMS IN :: +**PARAMS IN :: **PARAMS OUT:: position **RETURN :: position *****************************************************/ @@ -899,14 +951,14 @@ s32 ChipGetFieldPosition(u8 Mask) position = (Mask >> i) & 0x01; i++; } - + return (i-1); } /***************************************************** **FUNCTION :: ChipGetFieldBits **ACTION :: get the number of bits of a field in the chip -**PARAMS IN :: +**PARAMS IN :: **PARAMS OUT:: number of bits **RETURN :: number of bits *****************************************************/ @@ -914,14 +966,14 @@ s32 ChipGetFieldBits(s32 mask, s32 Position) { s32 bits,bit; s32 i =0; - + bits = mask >> Position; bit = bits ; while ((bit > 0)&&(i<8)) { i++; bit = bits >> i; - + } return i; } @@ -942,7 +994,7 @@ STCHIP_Error_t ChipSetFieldImage(STCHIP_Handle_t hChip,u32 FieldId, s32 Value) sign, bits, pos; - + if(hChip != NULL) { if(!hChip->Error) @@ -950,7 +1002,7 @@ STCHIP_Error_t ChipSetFieldImage(STCHIP_Handle_t hChip,u32 FieldId, s32 Value) if(hChip->Abort==FALSE) { regIndex=ChipGetFieldIndex(hChip,FieldId); /* Just for code simplification */ - + if((regIndex >= 0) && (regIndex < hChip->NbRegs)) { @@ -958,7 +1010,7 @@ STCHIP_Error_t ChipSetFieldImage(STCHIP_Handle_t hChip,u32 FieldId, s32 Value) mask = ChipGetFieldMask(FieldId); pos = ChipGetFieldPosition((u8)mask); bits = ChipGetFieldBits(mask,pos); - + if(sign == CHIP_SIGNED) Value = (Value > 0 ) ? Value : Value + (1<Error; } @@ -995,7 +1047,7 @@ STCHIP_Error_t ChipSetField(STCHIP_Handle_t hChip,u32 FieldId,s32 Value) sign, bits, pos; - + if(hChip) { if(!hChip->Error) @@ -1008,7 +1060,7 @@ STCHIP_Error_t ChipSetField(STCHIP_Handle_t hChip,u32 FieldId,s32 Value) mask = ChipGetFieldMask(FieldId); pos = ChipGetFieldPosition((u8)mask); bits = ChipGetFieldBits(mask,pos); - + if(sign == CHIP_SIGNED) Value = (Value > 0 ) ? Value : Value + (bits); /* compute signed fieldval */ @@ -1024,7 +1076,7 @@ STCHIP_Error_t ChipSetField(STCHIP_Handle_t hChip,u32 FieldId,s32 Value) } else return CHIPERR_INVALID_HANDLE; - + return hChip->Error; } @@ -1044,19 +1096,19 @@ s32 ChipGetFieldImage(STCHIP_Handle_t hChip,u32 FieldId) sign, bits, pos; - + if(hChip) { - if(hChip->Abort==FALSE) + if(hChip->Abort==FALSE) { regIndex=ChipGetFieldIndex(hChip,FieldId); /* Just for code simplification */ - + if((regIndex >= 0) && (regIndex < hChip->NbRegs)) { sign = ChipGetFieldSign(FieldId); mask = ChipGetFieldMask(FieldId); pos = ChipGetFieldPosition((u8)mask); - bits = ChipGetFieldBits(mask,pos); + bits = ChipGetFieldBits(mask,pos); if(!hChip->Error) value = (s32)hChip->pRegMapImage[regIndex].Value; @@ -1070,7 +1122,7 @@ s32 ChipGetFieldImage(STCHIP_Handle_t hChip,u32 FieldId) hChip->Error = CHIPERR_INVALID_FIELD_ID; } } - + return value; } @@ -1088,12 +1140,12 @@ s32 ChipGetFieldImage(STCHIP_Handle_t hChip,u32 FieldId) *****************************************************/ STCHIP_Error_t ChipGetField(STCHIP_Handle_t hChip,u32 FieldId, s32* value_p ) { - + s32 sign, mask, pos, bits; - STCHIP_Error_t error = CHIPERR_NO_ERROR; - + STCHIP_Error_t error = CHIPERR_NO_ERROR; + *value_p = 0xFF; - + if(hChip != NULL) { if(!hChip->Error) @@ -1104,9 +1156,9 @@ STCHIP_Error_t ChipGetField(STCHIP_Handle_t hChip,u32 FieldId, s32* value_p ) sign = ChipGetFieldSign(FieldId); mask = ChipGetFieldMask(FieldId); pos = ChipGetFieldPosition((u8)mask); - bits = ChipGetFieldBits(mask,pos); - - error=ChipGetOneRegister(hChip,(u16)(FieldId >> 16), (u32*)value_p); /* Read the register */ + bits = ChipGetFieldBits(mask,pos); + + error=ChipGetOneRegister(hChip,(u16)(FieldId >> 16), (u32*)value_p); /* Read the register */ *value_p=(*value_p & mask) >> pos; /* Extract field */ if((sign == CHIP_SIGNED)&&(*value_p & (1<<(bits-1)))) @@ -1114,7 +1166,7 @@ STCHIP_Error_t ChipGetField(STCHIP_Handle_t hChip,u32 FieldId, s32* value_p ) } } } - + return error; } @@ -1129,39 +1181,39 @@ int ChipCheckAck(STCHIP_Handle_t hChip) { I2C_RESULT status = I2C_ERR_ACK; u8 data = 0; - - if(hChip) + + if(hChip) { hChip->Error = CHIPERR_NO_ERROR; #ifndef NO_I2C if(hChip->Repeater && hChip->RepeaterHost && hChip->RepeaterFn) - hChip->RepeaterFn(hChip->RepeaterHost,TRUE); /* Set repeater ON */ + hChip->RepeaterFn(hChip->RepeaterHost,TRUE); /* Set repeater ON */ // PJ 07/2012 change polling access to WRITE, since a READ could clear flags on target device //status = I2cReadWrite(hChip->pI2CHost,I2C_READ,hChip->I2cAddr,&data,1); status = I2cReadWrite(hChip->pI2CHost,I2C_WRITE,hChip->I2cAddr,&data,0); - + if(hChip->Repeater && hChip->RepeaterHost && hChip->RepeaterFn) - hChip->RepeaterFn(hChip->RepeaterHost,FALSE); /* Set repeater OFF */ - + hChip->RepeaterFn(hChip->RepeaterHost,FALSE); /* Set repeater OFF */ + #else status = I2C_ERR_NONE; #endif - + if(status != I2C_ERR_NONE) hChip->Error = CHIPERR_I2C_NO_ACK; } - return status; + return status; } #endif /***************************************************** **FUNCTION :: ChipWait_Or_Abort -**ACTION :: wait for n ms or abort if requested -**PARAMS IN :: +**ACTION :: wait for n ms or abort if requested +**PARAMS IN :: **PARAMS OUT:: NONE -**RETURN :: NONE +**RETURN :: NONE *****************************************************/ void ChipWaitOrAbort(STCHIP_Handle_t hChip,u32 delay_ms) { @@ -1180,17 +1232,16 @@ void ChipAbort(STCHIP_Handle_t hChip, BOOL Abort) **FUNCTION :: Chip_368dvbt2_WaitMailboxComplete *****************************************************/ -/* --------------------------------------------------------------------------*/ +/* --------------------------------------------------------------------------*/ /* WBDemod Instance Map generation */ void ChipSetHierarchyMap (BOOL Flag) - { - Hierarchy_Flag = Flag; + { + Hierarchy_Flag = Flag; return; - } + } - void ChipSetMapRegisterSize(STCHIP_RegSize_t RegSize) -{ + void ChipSetMapRegisterSize(STCHIP_RegSize_t RegSize) +{ ChipMapRegisterSize = RegSize; /* helper, sets global regsize default for a map */ } - diff --git a/drivers/media/dvb-frontends/stid135/stid135-fe.c b/drivers/media/dvb-frontends/stid135/stid135-fe.c index 25d602beefea5..809004fdeeba3 100644 --- a/drivers/media/dvb-frontends/stid135/stid135-fe.c +++ b/drivers/media/dvb-frontends/stid135/stid135-fe.c @@ -31,7 +31,6 @@ #include #include #include - #include #include "stid135.h" #include "i2c.h" @@ -509,6 +508,9 @@ static int stid135_set_parameters(struct dvb_frontend *fe) search_params.puncture_rate = FE_SAT_PR_UNKNOWN; satellitte_scan = 0; break; + case ALGORITHM_SEARCH: + //todo + break; } #else @@ -1156,33 +1158,32 @@ static void spi_write(struct dvb_frontend *fe,struct ecp3_info *ecp3inf) } -#if 0 -static int stid135_get_spectrum_scan_fft(struct dvb_frontend *fe, unsigned int *delay, - enum fe_status *status) + +static int stid135_get_spectrum_scan_fft_one_band(struct stv *state, + struct dtv_fe_spectrum* s, + s32 center_freq, u32 range, + u32* freq, + s32* rf_level, + int num_freq) { - s32 Reg[60]; fe_lla_error_t error = FE_LLA_NO_ERROR; - struct dtv_frontend_properties *p = &fe->dtv_property_cache; - struct stv *state = fe->demodulator_priv; - *s->type = SC_DBM; - s32 center_freq= p->frequency; //in kHz - u32 range = p->symbol_rate; //in Hz u32 mode = 1; //table of 4096 samples //u32 mode = 5; //table of 256 samples u32 nb_acquisition = 255; //average 1 samples u32 table_size = 8192; s32 lo_frequency; - u32* freqs = s->freq; - s32* rf_level = s->rf_level; u32 begin =0; int i; - int step; + int step = range/1000; + int a=3; for(mode=1;mode<=5; ++mode) { table_size >>=1; - if(table_size <= s->num_freq) + if(table_size <= num_freq) break; } + if (num_freq != table_size) + dprintk("Error: num_freq should be power of 2\n"); dprintk("Start of spectrum scan\n"); error = FE_STiD135_GetLoFreqHz(state->base->handle, &lo_frequency); if(error) { @@ -1192,35 +1193,117 @@ static int stid135_get_spectrum_scan_fft(struct dvb_frontend *fe, unsigned int * lo_frequency *= 1000000; //now in Hz - error = fe_stid135_init_fft(state->base->handle, state->nr+1, state->rf_in+1, Reg); - if(error) { - dprintk("fe_stid135_init_fft FAILED: error=%d\n", error); - return error; - } - dprintk("freq=%d lo=%d range=%d mode=%d table_size=%d\n", center_freq, lo_frequency, range, mode, table_size); + dprintk("center_freq=%d lo=%d range=%d mode=%d table_size=%d\n", center_freq, lo_frequency, range, mode, table_size); error = fe_stid135_fft(state->base->handle, state->nr+1, mode, nb_acquisition, center_freq*1000 - lo_frequency, range, rf_level, &begin); - step = range/1000; if(begin==1) rf_level[0] = rf_level[1]; for(i=0; i< table_size; ++i) { - freqs[i]= center_freq + ((i-(signed)table_size/2)*step)/(signed)table_size; + s32 f = ((i-(signed)table_size/2)*step)/(signed)table_size; //in kHz + freq[i]= center_freq + f; + } + + for(i=-a+1; idtv_property_cache; + struct stv *state = fe->demodulator_priv; + s32 Reg[60]; + // s32 center_freq; //in kHz + fe_lla_error_t error = FE_LLA_NO_ERROR; + fe_lla_error_t error1 = FE_LLA_NO_ERROR; + u32 idx=0; + int i; + u32* temp_freq = NULL; + u32* temp_rf_level = NULL; + s32 fft_size = 256; + s32 max_range= 96800; + s32 start_frequency = p->scan_start_frequency; + s32 end_frequency = p->scan_end_frequency; + //uint32_t resolution = p->scan_resolution>0 ? p->scan_resolution : 100; //in kHz + s32 sample_step = (end_frequency - start_frequency +s->num_freq-1)/s->num_freq; + u32 range = sample_step * fft_size; //in kHz + int useable_samples2 = ((fft_size*6)/10+1)/2; + int lost_samples2 = fft_size/2 - useable_samples2; + int subsample_factor =1; + if(range >= max_range) { + subsample_factor = (range+ max_range-1)/max_range; + dprintk("resolution must be lower! Will subsample\n"); + //error= -EINVAL; + //goto _end; } - rf_level[table_size/2] = (rf_level[table_size/2-1] + rf_level[table_size/2+1])/2; - error |= fe_stid135_term_fft(state->base->handle, state->nr+1, state->rf_in+1, Reg); + + dprintk("demod: %d: tuner:%d range=[%d,%d]kHz resolution=%dkHz num_freq=%d range=%dkHz\n", + state->nr, state->rf_in, + start_frequency, end_frequency, sample_step, + s->num_freq, range/1000); + s->scale = FE_SCALE_RELATIVE; + + temp_freq = kzalloc(8192 * (sizeof(temp_freq[0])), GFP_KERNEL); + temp_rf_level = kzalloc(8192 * (sizeof(temp_rf_level[0])), GFP_KERNEL); + if (!temp_rf_level || !temp_freq) { + error = -ENOMEM; + goto _end; + } + + + error = fe_stid135_init_fft(state->base->handle, state->nr+1, state->rf_in+1, Reg); + if(error) { + dprintk("fe_stid135_init_fft FAILED: error=%d\n", error); + return error; + } + + for(idx=0; idx < s->num_freq;) { + s32 center_freq = start_frequency + (idx + useable_samples2)* sample_step; + if (kthread_should_stop() || dvb_frontend_task_should_stop(fe)) { + //@todo: should this be moved into stid135_get_spectrum_scan_fft_one_band? + dprintk("exiting on should stop\n"); + break; + } + + error = stid135_get_spectrum_scan_fft_one_band(state, s, center_freq, range*1000, + temp_freq, temp_rf_level, fft_size); + if(error) { + dprintk("Error=%d\n", error); + goto _end; + } + for(i= lost_samples2; inum_freq; ++idx, ++i) { + s->freq[idx]= temp_freq[i]; + s->rf_level[idx]= temp_rf_level[i]; + } + } + + _end: + dprintk("ending\n"); + if(temp_freq) + kfree(temp_freq); + if(temp_rf_level) + kfree(temp_rf_level); + error |= (error1=fe_stid135_term_fft(state->base->handle, state->nr+1, state->rf_in+1, Reg)); if(error) { dprintk("fe_stid135_term_fft FAILED: error=%d\n", error); } + *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC|FE_HAS_LOCK; + return 0; + dprintk("encountered error\n"); + *status = FE_TIMEDOUT|FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC|FE_HAS_LOCK; return error; } -#endif -static int stid135_get_spectrum_scan(struct dvb_frontend *fe, - struct dtv_fe_spectrum* s, - unsigned int *delay, enum fe_status *status) + +static int stid135_get_spectrum_scan_regular(struct dvb_frontend *fe, + struct dtv_fe_spectrum* s, + unsigned int *delay, enum fe_status *status) { struct stv *state = fe->demodulator_priv; struct dtv_frontend_properties *p = &fe->dtv_property_cache; @@ -1230,7 +1313,7 @@ static int stid135_get_spectrum_scan(struct dvb_frontend *fe, fe_lla_error_t error1 = FE_LLA_NO_ERROR; s32 pband_rf; s32 pch_rf; - int i; + int i = 0; u32 start_frequency = p->scan_start_frequency; u32 end_frequency = p->scan_end_frequency; //u32 bandwidth = end_frequency-start_frequency; //in kHz @@ -1303,57 +1386,57 @@ static int stid135_get_spectrum_scan(struct dvb_frontend *fe, dprintk("exiting on should stop\n"); break; } - //stop demod + //stop demod error |= (error1=ChipSetOneRegister(pParams->handle_demod, (u16)REG_RC8CODEW_DVBSX_DEMOD_DMDISTATE(state->nr+1), 0x1C)); if(error1) { - dprintk("Failed: err=%d\n", error1); - goto __onerror; - } + dprintk("Failed: err=%d\n", error1); + goto __onerror; + } - //warm start @todo: needed? - error |= (error1=ChipSetOneRegister(pParams->handle_demod, - (u16)REG_RC8CODEW_DVBSX_DEMOD_DMDISTATE(state->nr+1), 0x18)); - if(error1) { - dprintk("Failed: err=%d\n", error1); - goto __onerror; - } - s->freq[i]= start_frequency +i*resolution; - frequency = s->freq[i]; + //warm start @todo: needed? + error |= (error1=ChipSetOneRegister(pParams->handle_demod, + (u16)REG_RC8CODEW_DVBSX_DEMOD_DMDISTATE(state->nr+1), 0x18)); + if(error1) { + dprintk("Failed: err=%d\n", error1); + goto __onerror; + } + s->freq[i]= start_frequency +i*resolution; + frequency = s->freq[i]; - //Set frequency with minimal register changes - { - s32 frequency_hz = (s32)frequency*1000 - lo_frequency; - s32 si_register; - int demod = state->nr +1; - const u16 cfr_factor = 6711; // 6711 = 2^20/(10^6/2^6)*100 - - /* Search range definition */ - si_register = ((frequency_hz/PLL_FVCO_FREQUENCY)*cfr_factor)/100; - error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_CFRINIT2_CFR_INIT(demod), - ((u8)(si_register >> 16))); - error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_CFRINIT1_CFR_INIT(demod), - ((u8)(si_register >> 8))); - error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_CFRINIT0_CFR_INIT(demod), - ((u8)(si_register))); - error |= ChipSetRegisters(pParams->handle_demod,REG_RC8CODEW_DVBSX_DEMOD_CFRINIT2(demod),3); - if(error) - goto __onerror; - //msleep(10); + //Set frequency with minimal register changes + { + s32 frequency_hz = (s32)frequency*1000 - lo_frequency; + s32 si_register; + int demod = state->nr +1; + const u16 cfr_factor = 6711; // 6711 = 2^20/(10^6/2^6)*100 + + /* Search range definition */ + si_register = ((frequency_hz/PLL_FVCO_FREQUENCY)*cfr_factor)/100; + error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_CFRINIT2_CFR_INIT(demod), + ((u8)(si_register >> 16))); + error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_CFRINIT1_CFR_INIT(demod), + ((u8)(si_register >> 8))); + error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_CFRINIT0_CFR_INIT(demod), + ((u8)(si_register))); + error |= ChipSetRegisters(pParams->handle_demod,REG_RC8CODEW_DVBSX_DEMOD_CFRINIT2(demod),3); + if(error) + goto __onerror; + //msleep(10); - } + } - error |= (error1=FE_STiD135_GetRFLevel(pParams, state->nr+1, &pch_rf, &pband_rf)); - s->rf_level[i] = pch_rf; - if(error1) { - dprintk("Failed: err=%d\n", error1); - goto __onerror; - } - if(error) - goto __onerror; + error |= (error1=FE_STiD135_GetRFLevel(pParams, state->nr+1, &pch_rf, &pband_rf)); + s->rf_level[i] = pch_rf; + if(error1) { + dprintk("Failed: err=%d\n", error1); + goto __onerror; + } + if(error) + goto __onerror; - usleep_range(12000, 13000); + usleep_range(12000, 13000); } *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC|FE_HAS_LOCK; @@ -1365,6 +1448,22 @@ static int stid135_get_spectrum_scan(struct dvb_frontend *fe, } +static int stid135_get_spectrum_scan(struct dvb_frontend *fe, + struct dtv_fe_spectrum* s, + unsigned int *delay, enum fe_status *status) +{ + switch(s->spectrum_method) { + case SPECTRUM_METHOD_SWEEP: + default: + return stid135_get_spectrum_scan_regular(fe, s, delay, status); + break; + case SPECTRUM_METHOD_FFT: + return stid135_get_spectrum_scan_fft(fe, s, delay, status); + break; + } + return -1; +} + static struct dvb_frontend_ops stid135_ops = { .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .info = { @@ -1423,7 +1522,7 @@ struct dvb_frontend *stid135_attach(struct i2c_adapter *i2c, { struct stv *state; struct stv_base *base; - + dprintk("ATTACH nr=%d rf_in=%d\n", nr, rf_in); state = kzalloc(sizeof(struct stv), GFP_KERNEL); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/stid135/stid135-fft.c b/drivers/media/dvb-frontends/stid135/stid135-fft.c index d66d8a7990a6a..49d9c74837432 100644 --- a/drivers/media/dvb-frontends/stid135/stid135-fft.c +++ b/drivers/media/dvb-frontends/stid135/stid135-fft.c @@ -192,7 +192,8 @@ static fe_lla_error_t fe_stid135_fft_save_registers(fe_stid135_handle_t handle, --PARAMS OUT :: Reg[] -> table of stored registers --RETURN :: Error (if any) --***************************************************/ -fe_lla_error_t fe_stid135_init_fft(fe_stid135_handle_t handle, enum fe_stid135_demod path, FE_OXFORD_TunerPath_t tuner_nb, s32 Reg[60]) +fe_lla_error_t fe_stid135_init_fft(fe_stid135_handle_t handle, enum fe_stid135_demod path, + FE_OXFORD_TunerPath_t tuner_nb, s32 Reg[60]) { fe_lla_error_t error = FE_LLA_NO_ERROR; struct fe_stid135_internal_param *pParams; @@ -235,9 +236,13 @@ fe_lla_error_t fe_stid135_init_fft(fe_stid135_handle_t handle, enum fe_stid135_d //store the result error |= ChipSetRegisters(pParams->handle_demod, (u16)REG_RC8CODEW_DVBSX_DEMOD_GCTRL(path), 1); +#if 0 //select continuous update of spectrum after 2 scans error |= ChipSetField(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_UPDCONT_UPD_CONTINUOUS(path), 2); - +#else + //select continuous update of spectrum after 2 scans + error |= ChipSetField(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_UPDCONT_UPD_CONTINUOUS(path), 0); +#endif // Request 256 samples; max would be 4096 samples error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_FFTCTRL_FFT_MODE(path), 5); @@ -257,20 +262,32 @@ fe_lla_error_t fe_stid135_init_fft(fe_stid135_handle_t handle, enum fe_stid135_d //set a threshold to detect "peak found" error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_THRESHOLD_MAX_THRESHOLD(path), 4); //FFT continuous if a good peak was found, the alternative setting would be good for blindscan +#if 0 error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_THRESHOLD_NO_STOP(path), 0); // Off +#else + error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_THRESHOLD_NO_STOP(path), 1); // Off +#endif //Store the result error |= ChipSetRegisters(pParams->handle_demod, (u16)REG_RC8CODEW_DVBSX_DEMOD_THRESHOLD(path),1); +#if 1 //LATEST //do not treat overflow specially error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_DEBUG1_DISABLE_RESCALE(path), 0); //do not remove mean value to disable DC coefficient error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_DEBUG1_DISABLE_AVERAGE(path), 0); +#else + error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_DEBUG1_DISABLE_RESCALE(path), 1); + //do not remove mean value to disable DC coefficient + error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_DEBUG1_DISABLE_AVERAGE(path), 1); + #endif error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_DEBUG1_DEBUG_INTERSYMBOL(path), 0); // Off - +#if 0 //spectrum will be in log format: (PSD=val*3/64 dB) (unsigned) error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_DEBUG1_MODE_DB(path), 1); - +#else + error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_DEBUG1_MODE_DB(path), 0); +#endif //read power spectral density instead of fft result error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_DEBUG1_SEL_MEM(path), 0); @@ -447,7 +464,7 @@ fe_lla_error_t fe_stid135_term_fft(fe_stid135_handle_t handle, enum fe_stid135_d --RETURN :: Error (if any) --***************************************************/ fe_lla_error_t fe_stid135_fft(fe_stid135_handle_t handle, enum fe_stid135_demod path, u32 mode, u32 nb_acquisition, s32 freq, u32 range, u32 *tab, u32* begin) -{ +{ u32 nb_words =0; s32 val[4]= { 0 }, val_max; u32 j=0, i=0, bin=0; @@ -501,7 +518,7 @@ fe_lla_error_t fe_stid135_fft(fe_stid135_handle_t handle, enum fe_stid135_demod ((u8)(f >> 8))); error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_CFRINIT0_CFR_INIT(path), ((u8)f)); - error |= ChipSetRegisters(pParams->handle_demod, (u16)REG_RC8CODEW_DVBSX_DEMOD_CFRINIT2(path),3); + error |= ChipSetRegisters(pParams->handle_demod, REG_RC8CODEW_DVBSX_DEMOD_CFRINIT2(path),3); // Set bandwidth (symbol rate) error |= fe_stid135_set_symbol_rate(pParams->handle_demod, pParams->master_clock, range, path); @@ -559,13 +576,16 @@ fe_lla_error_t fe_stid135_fft(fe_stid135_handle_t handle, enum fe_stid135_demod } for (i=0; ihandle_demod, FLD_FC8CODEW_DVBSX_DEMOD_MEMADDR1_MEM_ADDR(path), (i>>8) & 0x03); error |= ChipSetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_MEMADDR0_MEM_ADDR(path), (i & 0xff)); error |= ChipSetRegisters(pParams->handle_demod, (u16)REG_RC8CODEW_DVBSX_DEMOD_MEMADDR1(path), 2); - dprintk("FFT %d/%d\n", i, nb_words); + //dprintk("FFT %d/%d\n", i, nb_words); // wait for end of transfer error |= ChipGetField(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_MEMSTAT_MEM_STAT(path), &memstat); while ((!memstat) && (timeout < 50)) { @@ -575,7 +595,7 @@ fe_lla_error_t fe_stid135_fft(fe_stid135_handle_t handle, enum fe_stid135_demod } if(timeout == 50) return(FE_LLA_NODATA); - dprintk("FFT %d/%d end of transfer\n", i, nb_words); + //dprintk("FFT %d/%d end of transfer\n", i, nb_words); // read & store data to create an fft list error |= ChipGetField(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_DEBUG1_MODE_FULL(path), &fld_value); @@ -586,9 +606,10 @@ fe_lla_error_t fe_stid135_fft(fe_stid135_handle_t handle, enum fe_stid135_demod val[2] = ChipGetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_MEMVA00_MEM_VAL0(path) + ((4 * j) << 16)); val[1] = ChipGetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_MEMVA11_MEM_VAL1(path) + ((4 * j) << 16)); val[0] = ChipGetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_MEMVA10_MEM_VAL1(path) + ((4 * j) << 16)); - val_max = (((val[3] & 0x7) << 24) + (val[2] << 16) + (val[1] << 8) + val[0]) * XtoPowerY(2, exp); + val_max = STLog10(((val[3] & 0x7) << 24) + (val[2] << 16) + (val[1] << 8) + val[0]) + +693* exp; bin = (u32)(i*4+j); - tab[nbr_pts-bin-1] = (u32)val_max; // fil the table back to front + tab[nbr_pts-bin-1] = (u32)val_max; // fill the table back to front } } else if(fld_value == 0) { // 16-bit mode // read temporary memory @@ -596,9 +617,9 @@ fe_lla_error_t fe_stid135_fft(fe_stid135_handle_t handle, enum fe_stid135_demod error |= ChipGetRegisters(pParams->handle_demod, (u16)(REG_RC8CODEW_DVBSX_DEMOD_MEMVA01(path) + (2 * j)), 2); val[3] = ChipGetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_MEMVA01_MEM_VAL0(path) + ((2 * j) << 16)); // 16 = address bus width for demod val[2] = ChipGetFieldImage(pParams->handle_demod, FLD_FC8CODEW_DVBSX_DEMOD_MEMVA00_MEM_VAL0(path) + ((2 * j) << 16)); - val_max = ((val[3] << 8) + val[2]) * XtoPowerY(2, exp); + val_max = STLog10((val[3] << 8) + val[2]) + 693*exp; bin = (u32)(i*8+j); - tab[nbr_pts-bin-1] = (u32)val_max; // fil the table back to front + tab[nbr_pts-bin-1] = 10*(u32)val_max; // fil the table back to front; unit is 0.001dB } } } diff --git a/drivers/media/dvb-frontends/stid135/stid135-fft.h b/drivers/media/dvb-frontends/stid135/stid135-fft.h index c2292c4f13550..591b4c10f5902 100644 --- a/drivers/media/dvb-frontends/stid135/stid135-fft.h +++ b/drivers/media/dvb-frontends/stid135/stid135-fft.h @@ -1,35 +1,35 @@ /* -* This file is part of STiD135 OXFORD LLA +* This file is part of STiD135 OXFORD LLA * -* Copyright (c) <2014>-<2018>, STMicroelectronics - All Rights Reserved -* Author(s): Mathias Hilaire (mathias.hilaire@st.com), Thierry Delahaye (thierry.delahaye@st.com) for STMicroelectronics. +* Copyright (c) <2014>-<2018>, STMicroelectronics - All Rights Reserved +* Author(s): Mathias Hilaire (mathias.hilaire@st.com), Thierry Delahaye (thierry.delahaye@st.com) for STMicroelectronics. * -* License terms: BSD 3-clause "New" or "Revised" License. +* License terms: BSD 3-clause "New" or "Revised" License. * -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this -* list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ @@ -42,13 +42,13 @@ fe_lla_error_t fe_stid135_init_fft(fe_stid135_handle_t handle, enum fe_stid135_demod path, FE_OXFORD_TunerPath_t tuner_nb, s32 Reg[60]); - + fe_lla_error_t fe_stid135_term_fft(fe_stid135_handle_t handle, enum fe_stid135_demod path, FE_OXFORD_TunerPath_t tuner_nb, s32 Reg[60]); fe_lla_error_t fe_stid135_fft(fe_stid135_handle_t handle, enum fe_stid135_demod path, u32 mode, u32 nb_acquisition, s32 frq, u32 range, u32 *tab, u32* begin); - - + + #ifdef __cplusplus } #endif diff --git a/drivers/media/dvb-frontends/stv091x_drv.c b/drivers/media/dvb-frontends/stv091x_drv.c index acefe7553ba72..e863db1679974 100644 --- a/drivers/media/dvb-frontends/stv091x_drv.c +++ b/drivers/media/dvb-frontends/stv091x_drv.c @@ -1775,12 +1775,13 @@ static s32 stv091x_agc1_power_gain(struct stv *state) //todo: Py_AGC, AGC2_INTEGRATOR } +//units of 0.001dB static s32 stv091x_agc1_power_gain_dbm(struct stv *state) { u16 agc_gain = stv091x_agc1_power_gain(state); //u16 because of stv6120 interface (todo) if (state->fe.ops.tuner_ops.get_rf_strength) state->fe.ops.tuner_ops.get_rf_strength(&state->fe, &agc_gain);//in units of 0.01dB - return agc_gain; + return 10*agc_gain; } @@ -1801,25 +1802,28 @@ static s32 stv091x_iq_power(struct stv *state) //todo: Py_AGC, AGC2_INTEGRATOR } +//unit 0.001dB static s32 stv091x_iq_power_dbm(struct stv *state) { s32 iq_power = stv091x_iq_power(state); - return TableLookup(PADC_Lookup, ARRAY_SIZE(PADC_Lookup), iq_power) + 352; + return 10*(TableLookup(PADC_Lookup, ARRAY_SIZE(PADC_Lookup), iq_power) + 352); } /* signal power in the stv6120 tuner bandwidth (not representative for narrow band signals) + unit: 0.001dB */ static s32 stv091x_signal_power_dbm(struct dvb_frontend *fe) { struct stv *state = fe->demodulator_priv; //todo: take into account agc2 - return (-52 - stv091x_agc1_power_gain_dbm(state)); //unit is 0.01dB + return (-520 - stv091x_agc1_power_gain_dbm(state)); //unit is 0.01dB /* -0.52 is the output level in dBm*/ } /* signal power representative for narrow band signals + unit: 0.001dB */ static s32 stv091x_narrow_band_signal_power_dbm(struct dvb_frontend *fe) { @@ -1828,9 +1832,9 @@ static s32 stv091x_narrow_band_signal_power_dbm(struct dvb_frontend *fe) s32 agc2level = (read_reg_field(state, FSTV0910_P2_AGC2_INTEGRATOR1) <<8) | read_reg_field(state, FSTV0910_P2_AGC2_INTEGRATOR0); s32 agc2ref = read_reg(state, RSTV0910_P2_AGC2REF); - s32 x = 2*(s32)STLog10((u32)(agc2ref)); //unit is 0.01dB - s32 y = 2*(s32)STLog10(agc2level); //unit is 0.01dB - return (x-y) + (-52 - stv091x_agc1_power_gain_dbm(state)); //unit is 0.01dB + s32 x = 20*(s32)STLog10((u32)(agc2ref)); //unit is 0.01dB + s32 y = 20*(s32)STLog10(agc2level); //unit is 0.01dB + return (x-y) + (-520 - stv091x_agc1_power_gain_dbm(state)); //unit is 0.01dB } static int read_status(struct dvb_frontend *fe, enum fe_status *status) @@ -1843,16 +1847,16 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) u32 FECLock = 0; s32 snr; u32 n, d; - s32 signal_strength = stv091x_signal_power_dbm(fe); //unit=0.01dB + s32 signal_strength = stv091x_signal_power_dbm(fe); //unit=0.001dB /*pr_warn("%s: agc = %d iq_power = %d Padc = %d\n", __func__, agc, iq_power, Padc);*/ p->strength.len = 2; p->strength.stat[0].scale = FE_SCALE_DECIBEL; - p->strength.stat[0].svalue = signal_strength*10; //result in uints of 0.0001dB + p->strength.stat[0].svalue = signal_strength; //result in uints of 0.0001dB p->strength.stat[1].scale = FE_SCALE_RELATIVE; - p->strength.stat[1].uvalue = (100 + signal_strength/100) * 656; //todo: check range + p->strength.stat[1].uvalue = (100 + signal_strength/1000) * 656; //todo: check range //todo: if not locked, and signal is too low FE_HAS_SIGNAL should be removed *status = FE_HAS_SIGNAL; diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index 60482b186ad35..1fc01fd4f70a4 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -902,14 +902,27 @@ struct dtv_stats { #define MAX_DTV_STATS 4 +/** + enum dtv_fe_spectrum_method; + Should be passed as integer parameter when setting DTV_SPECTRUM property + **/ +enum dtv_fe_spectrum_method { + SPECTRUM_METHOD_SWEEP, + SPECTRUM_METHOD_FFT +}; + + /** * struct dtv_fe_spectrum - decriptor for a spectrum scan buffer - * - * when calling FE_SET_FRONTEND: - * @freq: buffer created by caller with num_freq elements; will be filled with data; - * @rf_level: buffer created by caller with num_freq elements; will be filled with data + * This is passed as an input to FE_GET_PROPERTY + * The caller should initialise the fields as followed + * @spectrum_method: method ti use for creating the spectrum + * @freq: buffer created by caller with num_freq elements; will be filled with data and should have + * room for @num_freq elements + * @rf_level: buffer created by caller with num_freq elements; will be filled with data and should have + * room for @num_freq elements * @num_freq: set by caller: length of the buffer, will be replaced on return with the true size, - * which will be less or equal + * if the true size is smaller => num_freq should be set as an upper bound * @scale: after return this will contain FE_SCALE_DECIBEL or FE_SCALE_RELATIVE * */ @@ -918,6 +931,7 @@ struct dtv_fe_spectrum { __s32 *rf_level; __u32 num_freq; __u32 scale; //FE_SCALE_DECIBEL; or FE_SCALE_RELATIVE + __u8 spectrum_method; };